diff --git a/Cargo.lock b/Cargo.lock index c2e635b4cfe65..d0d440b64c11d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,9 +128,9 @@ dependencies = [ [[package]] name = "anstyle-svg" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc03a770ef506fe1396c0e476120ac0e6523cf14b74218dd5f18cd6833326fa9" +checksum = "26b9ec8c976eada1b0f9747a3d7cc4eae3bef10613e443746e7487f26c872fde" dependencies = [ "anstyle", "anstyle-lossy", diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index d2b275ad20a9f..70d796cda11c0 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -5,7 +5,7 @@ use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, PResult}; use rustc_macros::{Decodable, Encodable}; use rustc_session::parse::ParseSess; -use rustc_span::{Ident, Span, Symbol}; +use rustc_span::{Ident, Span, Symbol, sym}; use crate::errors; @@ -69,15 +69,15 @@ impl MetaVarExpr { } let mut iter = args.iter(); - let rslt = match ident.as_str() { - "concat" => parse_concat(&mut iter, psess, outer_span, ident.span)?, - "count" => parse_count(&mut iter, psess, ident.span)?, - "ignore" => { + let rslt = match ident.name { + sym::concat => parse_concat(&mut iter, psess, outer_span, ident.span)?, + sym::count => parse_count(&mut iter, psess, ident.span)?, + sym::ignore => { eat_dollar(&mut iter, psess, ident.span)?; MetaVarExpr::Ignore(parse_ident(&mut iter, psess, ident.span)?) } - "index" => MetaVarExpr::Index(parse_depth(&mut iter, psess, ident.span)?), - "len" => MetaVarExpr::Len(parse_depth(&mut iter, psess, ident.span)?), + sym::index => MetaVarExpr::Index(parse_depth(&mut iter, psess, ident.span)?), + sym::len => MetaVarExpr::Len(parse_depth(&mut iter, psess, ident.span)?), _ => { let err = errors::MveUnrecognizedExpr { span: ident.span, @@ -119,14 +119,13 @@ fn check_trailing_tokens<'psess>( } // `None` for max indicates the arg count must be exact, `Some` indicates a range is accepted. - let (min_or_exact_args, max_args) = match ident.as_str() { - "concat" => panic!("concat takes unlimited tokens but didn't eat them all"), - "ignore" => (1, None), + let (min_or_exact_args, max_args) = match ident.name { + sym::concat => panic!("concat takes unlimited tokens but didn't eat them all"), + sym::ignore => (1, None), // 1 or 2 args - "count" => (1, Some(2)), + sym::count => (1, Some(2)), // 0 or 1 arg - "index" => (0, Some(1)), - "len" => (0, Some(1)), + sym::index | sym::len => (0, Some(1)), other => unreachable!("unknown MVEs should be rejected earlier (got `{other}`)"), }; diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 6a3f1f62c91e1..dddd62a4945a2 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -375,6 +375,19 @@ fn transcribe_metavar<'tx>( return Ok(()); }; + let MatchedSingle(pnr) = cur_matched else { + // We were unable to descend far enough. This is an error. + return Err(dcx.create_err(MacroVarStillRepeating { span: sp, ident })); + }; + + transcribe_pnr(tscx, sp, pnr) +} + +fn transcribe_pnr<'tx>( + tscx: &mut TranscrCtx<'tx, '_>, + mut sp: Span, + pnr: &ParseNtResult, +) -> PResult<'tx, ()> { // We wrap the tokens in invisible delimiters, unless they are already wrapped // in invisible delimiters with the same `MetaVarKind`. Because some proc // macros can't handle multiple layers of invisible delimiters of the same @@ -404,33 +417,33 @@ fn transcribe_metavar<'tx>( ) }; - let tt = match cur_matched { - MatchedSingle(ParseNtResult::Tt(tt)) => { + let tt = match pnr { + ParseNtResult::Tt(tt) => { // `tt`s are emitted into the output stream directly as "raw tokens", // without wrapping them into groups. Other variables are emitted into // the output stream as groups with `Delimiter::Invisible` to maintain // parsing priorities. maybe_use_metavar_location(tscx.psess, &tscx.stack, sp, tt, &mut tscx.marker) } - MatchedSingle(ParseNtResult::Ident(ident, is_raw)) => { + ParseNtResult::Ident(ident, is_raw) => { tscx.marker.mark_span(&mut sp); with_metavar_spans(|mspans| mspans.insert(ident.span, sp)); let kind = token::NtIdent(*ident, *is_raw); TokenTree::token_alone(kind, sp) } - MatchedSingle(ParseNtResult::Lifetime(ident, is_raw)) => { + ParseNtResult::Lifetime(ident, is_raw) => { tscx.marker.mark_span(&mut sp); with_metavar_spans(|mspans| mspans.insert(ident.span, sp)); let kind = token::NtLifetime(*ident, *is_raw); TokenTree::token_alone(kind, sp) } - MatchedSingle(ParseNtResult::Item(item)) => { + ParseNtResult::Item(item) => { mk_delimited(item.span, MetaVarKind::Item, TokenStream::from_ast(item)) } - MatchedSingle(ParseNtResult::Block(block)) => { + ParseNtResult::Block(block) => { mk_delimited(block.span, MetaVarKind::Block, TokenStream::from_ast(block)) } - MatchedSingle(ParseNtResult::Stmt(stmt)) => { + ParseNtResult::Stmt(stmt) => { let stream = if let StmtKind::Empty = stmt.kind { // FIXME: Properly collect tokens for empty statements. TokenStream::token_alone(token::Semi, stmt.span) @@ -439,10 +452,10 @@ fn transcribe_metavar<'tx>( }; mk_delimited(stmt.span, MetaVarKind::Stmt, stream) } - MatchedSingle(ParseNtResult::Pat(pat, pat_kind)) => { + ParseNtResult::Pat(pat, pat_kind) => { mk_delimited(pat.span, MetaVarKind::Pat(*pat_kind), TokenStream::from_ast(pat)) } - MatchedSingle(ParseNtResult::Expr(expr, kind)) => { + ParseNtResult::Expr(expr, kind) => { let (can_begin_literal_maybe_minus, can_begin_string_literal) = match &expr.kind { ExprKind::Lit(_) => (true, true), ExprKind::Unary(UnOp::Neg, e) if matches!(&e.kind, ExprKind::Lit(_)) => { @@ -460,14 +473,14 @@ fn transcribe_metavar<'tx>( TokenStream::from_ast(expr), ) } - MatchedSingle(ParseNtResult::Literal(lit)) => { + ParseNtResult::Literal(lit) => { mk_delimited(lit.span, MetaVarKind::Literal, TokenStream::from_ast(lit)) } - MatchedSingle(ParseNtResult::Ty(ty)) => { + ParseNtResult::Ty(ty) => { let is_path = matches!(&ty.kind, TyKind::Path(None, _path)); mk_delimited(ty.span, MetaVarKind::Ty { is_path }, TokenStream::from_ast(ty)) } - MatchedSingle(ParseNtResult::Meta(attr_item)) => { + ParseNtResult::Meta(attr_item) => { let has_meta_form = attr_item.meta_kind().is_some(); mk_delimited( attr_item.span(), @@ -475,16 +488,12 @@ fn transcribe_metavar<'tx>( TokenStream::from_ast(attr_item), ) } - MatchedSingle(ParseNtResult::Path(path)) => { + ParseNtResult::Path(path) => { mk_delimited(path.span, MetaVarKind::Path, TokenStream::from_ast(path)) } - MatchedSingle(ParseNtResult::Vis(vis)) => { + ParseNtResult::Vis(vis) => { mk_delimited(vis.span, MetaVarKind::Vis, TokenStream::from_ast(vis)) } - MatchedSeq(..) => { - // We were unable to descend far enough. This is an error. - return Err(dcx.create_err(MacroVarStillRepeating { span: sp, ident })); - } }; tscx.result.push(tt); diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index f735c0a416099..46accb76a184a 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -47,7 +47,7 @@ You can read more about trait objects in the Trait Objects section of the Refere https://doc.rust-lang.org/reference/types.html#trait-objects"; fn is_number(text: &str) -> bool { - text.chars().all(|c: char| c.is_digit(10)) + text.chars().all(|c: char| c.is_ascii_digit()) } /// Information about the expected type at the top level of type checking a pattern. @@ -262,8 +262,9 @@ enum InheritedRefMatchRule { /// pattern matches a given type: /// - If the underlying type is not a reference, a reference pattern may eat the inherited reference; /// - If the underlying type is a reference, a reference pattern matches if it can eat either one - /// of the underlying and inherited references. E.g. a `&mut` pattern is allowed if either the - /// underlying type is `&mut` or the inherited reference is `&mut`. + /// of the underlying and inherited references. E.g. a `&mut` pattern is allowed if either the + /// underlying type is `&mut` or the inherited reference is `&mut`. + /// /// If `false`, a reference pattern is only matched against the underlying type. /// This is `false` for stable Rust and `true` for both the `ref_pat_eat_one_layer_2024` and /// `ref_pat_eat_one_layer_2024_structural` feature gates. @@ -1069,7 +1070,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { if !self.tcx.features().mut_ref() { feature_err( - &self.tcx.sess, + self.tcx.sess, sym::mut_ref, pat.span.until(ident.span), "binding cannot be both mutable and by-reference", @@ -1487,31 +1488,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { opt_def_id: Option, ident: Ident, ) -> bool { - match opt_def_id { - Some(def_id) => match self.tcx.hir_get_if_local(def_id) { - Some(hir::Node::Item(hir::Item { - kind: hir::ItemKind::Const(_, _, _, body_id), - .. - })) => match self.tcx.hir_node(body_id.hir_id) { - hir::Node::Expr(expr) => { - if hir::is_range_literal(expr) { - let span = self.tcx.hir_span(body_id.hir_id); - if let Ok(snip) = self.tcx.sess.source_map().span_to_snippet(span) { - e.span_suggestion_verbose( - ident.span, - "you may want to move the range into the match block", - snip, - Applicability::MachineApplicable, - ); - return true; - } - } - } - _ => (), - }, - _ => (), - }, - _ => (), + if let Some(def_id) = opt_def_id + && let Some(hir::Node::Item(hir::Item { + kind: hir::ItemKind::Const(_, _, _, body_id), + .. + })) = self.tcx.hir_get_if_local(def_id) + && let hir::Node::Expr(expr) = self.tcx.hir_node(body_id.hir_id) + && hir::is_range_literal(expr) + { + let span = self.tcx.hir_span(body_id.hir_id); + if let Ok(snip) = self.tcx.sess.source_map().span_to_snippet(span) { + e.span_suggestion_verbose( + ident.span, + "you may want to move the range into the match block", + snip, + Applicability::MachineApplicable, + ); + return true; + } } false } @@ -1529,7 +1523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(span) = self.tcx.hir_res_span(pat_res) { e.span_label(span, format!("{} defined here", res.descr())); - if let [hir::PathSegment { ident, .. }] = &*segments { + if let [hir::PathSegment { ident, .. }] = segments { e.span_label( pat_span, format!( @@ -1557,17 +1551,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => (None, None), }; - let is_range = match type_def_id.and_then(|id| self.tcx.as_lang_item(id)) { + let is_range = matches!( + type_def_id.and_then(|id| self.tcx.as_lang_item(id)), Some( LangItem::Range - | LangItem::RangeFrom - | LangItem::RangeTo - | LangItem::RangeFull - | LangItem::RangeInclusiveStruct - | LangItem::RangeToInclusive, - ) => true, - _ => false, - }; + | LangItem::RangeFrom + | LangItem::RangeTo + | LangItem::RangeFull + | LangItem::RangeInclusiveStruct + | LangItem::RangeToInclusive, + ) + ); if is_range { if !self.maybe_suggest_range_literal(&mut e, item_def_id, *ident) { let msg = "constants only support matching by type, \ diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index c29ab569f4795..f6790f7ed1e96 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -599,14 +599,16 @@ impl Cursor<'_> { if potential_closing.is_none() { // a less fortunate recovery if all else fails which finds any dashes preceded by whitespace // on a standalone line. Might be wrong. + let mut base_index = 0; while let Some(closing) = rest.find("---") { let preceding_chars_start = rest[..closing].rfind("\n").map_or(0, |i| i + 1); if rest[preceding_chars_start..closing].chars().all(is_horizontal_whitespace) { // candidate found - potential_closing = Some(closing); + potential_closing = Some(closing + base_index); break; } else { rest = &rest[closing + 3..]; + base_index += closing + 3; } } } diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index a820045521b9f..c50f07ff6bb66 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -779,7 +779,7 @@ impl OneShot for result::IterMut<'_, T> {} impl OneShot for Empty {} impl OneShot for array::IntoIter {} -// These adaptors never increase the number of items. +// These adapters never increase the number of items. // (There are more possible, but for now this matches BoundedSize above.) impl OneShot for Cloned {} impl OneShot for Copied {} diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index ff0e29e04c251..a45edd08e8ccc 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1081,7 +1081,7 @@ pub trait Read { default_read_buf_exact(self, cursor) } - /// Creates a "by reference" adaptor for this instance of `Read`. + /// Creates a "by reference" adapter for this instance of `Read`. /// /// The returned adapter also implements `Read` and will simply borrow this /// current reader. diff --git a/src/doc/book b/src/doc/book index 3e9dc46aa563c..33f1af40cc44d 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 3e9dc46aa563ca0c53ec826c41b05f10c5915925 +Subproject commit 33f1af40cc44dde7e3e892f7a508e6f427d2cbc6 diff --git a/src/doc/reference b/src/doc/reference index b3ce60628c6f5..cc7247d8dfaef 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit b3ce60628c6f55ab8ff3dba9f3d20203df1c0dee +Subproject commit cc7247d8dfaef4c39000bb12c55c32ba5b5ba976 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index dd26bc8e726dc..2c9b490d70e53 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit dd26bc8e726dc2e73534c8972d4dccd1bed7495f +Subproject commit 2c9b490d70e535cf166bf17feba59e594579843f diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index df2bac877b66f..0dc9ce843e9c9 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -2f3f27bf79ec147fec9d2e7980605307a74067f4 +9f32ccf35fb877270bc44a86a126440f04d676d0 diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index a1612738537d7..249140956c09a 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -108,6 +108,7 @@ - [Installation](./autodiff/installation.md) - [How to debug](./autodiff/debugging.md) - [Autodiff flags](./autodiff/flags.md) + - [Type Trees](./autodiff/type-trees.md) # Source Code Representation diff --git a/src/doc/rustc-dev-guide/src/about-this-guide.md b/src/doc/rustc-dev-guide/src/about-this-guide.md index f1a406a1c29be..4f5733ae0821a 100644 --- a/src/doc/rustc-dev-guide/src/about-this-guide.md +++ b/src/doc/rustc-dev-guide/src/about-this-guide.md @@ -48,9 +48,9 @@ In addition, many of the ideas discussed throughout this guide are idealized des that are not fully realized yet. All this makes keeping this guide completely up to date on everything very hard! -The Guide itself is of course open-source as well, -and the sources can be found at the [GitHub repository]. -If you find any mistakes in the guide, please file an issue about it. +The guide itself is of course open source as well, +and the sources are hosted on [a GitHub repository]. +If you find any mistakes in the guide, please file an issue. Even better, open a PR with a correction! If you do contribute to the guide, @@ -105,7 +105,7 @@ You might also find the following sites useful: [cheatsheet]: https://bors.rust-lang.org/ [Miri]: https://github.com/rust-lang/miri [@bors]: https://github.com/bors -[GitHub repository]: https://github.com/rust-lang/rustc-dev-guide/ +[a GitHub repository]: https://github.com/rust-lang/rustc-dev-guide/ [rustc API docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle [Forge]: https://forge.rust-lang.org/ [compiler-team]: https://github.com/rust-lang/compiler-team/ diff --git a/src/doc/rustc-dev-guide/src/appendix/glossary.md b/src/doc/rustc-dev-guide/src/appendix/glossary.md index 1837b59e850ae..21162f8ee7d08 100644 --- a/src/doc/rustc-dev-guide/src/appendix/glossary.md +++ b/src/doc/rustc-dev-guide/src/appendix/glossary.md @@ -68,6 +68,7 @@ Term | Meaning rib | A data structure in the name resolver that keeps track of a single scope for names. ([see more](../name-resolution.md)) RPIT | A return-position `impl Trait`. ([see the reference](https://doc.rust-lang.org/reference/types/impl-trait.html#abstract-return-types)). RPITIT | A return-position `impl Trait` in trait. Unlike RPIT, this is desugared to a generic associated type (GAT). Introduced in [RFC 3425](https://rust-lang.github.io/rfcs/3425-return-position-impl-trait-in-traits.html). ([see more](../return-position-impl-trait-in-trait.md)) +rustbuild | A deprecated term for the part of bootstrap that is written in Rust scrutinee | A scrutinee is the expression that is matched on in `match` expressions and similar pattern matching constructs. For example, in `match x { A => 1, B => 2 }`, the expression `x` is the scrutinee. `sess` | The compiler _session_, which stores global data used throughout compilation side tables | Because the [AST](#ast) and HIR are immutable once created, we often carry extra information about them in the form of hashtables, indexed by the id of a particular node. diff --git a/src/doc/rustc-dev-guide/src/autodiff/type-trees.md b/src/doc/rustc-dev-guide/src/autodiff/type-trees.md new file mode 100644 index 0000000000000..68cb78650b009 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/autodiff/type-trees.md @@ -0,0 +1,193 @@ +# TypeTrees for Autodiff + +## What are TypeTrees? +Memory layout descriptors for Enzyme. Tell Enzyme exactly how types are structured in memory so it can compute derivatives efficiently. + +## Structure +```rust +TypeTree(Vec) + +Type { + offset: isize, // byte offset (-1 = everywhere) + size: usize, // size in bytes + kind: Kind, // Float, Integer, Pointer, etc. + child: TypeTree // nested structure +} +``` + +## Example: `fn compute(x: &f32, data: &[f32]) -> f32` + +**Input 0: `x: &f32`** +```rust +TypeTree(vec![Type { + offset: -1, size: 8, kind: Pointer, + child: TypeTree(vec![Type { + offset: 0, size: 4, kind: Float, // Single value: use offset 0 + child: TypeTree::new() + }]) +}]) +``` + +**Input 1: `data: &[f32]`** +```rust +TypeTree(vec![Type { + offset: -1, size: 8, kind: Pointer, + child: TypeTree(vec![Type { + offset: -1, size: 4, kind: Float, // -1 = all elements + child: TypeTree::new() + }]) +}]) +``` + +**Output: `f32`** +```rust +TypeTree(vec![Type { + offset: 0, size: 4, kind: Float, // Single scalar: use offset 0 + child: TypeTree::new() +}]) +``` + +## Why Needed? +- Enzyme can't deduce complex type layouts from LLVM IR +- Prevents slow memory pattern analysis +- Enables correct derivative computation for nested structures +- Tells Enzyme which bytes are differentiable vs metadata + +## What Enzyme Does With This Information: + +Without TypeTrees: +```llvm +; Enzyme sees generic LLVM IR: +define float @distance(ptr %p1, ptr %p2) { +; Has to guess what these pointers point to +; Slow analysis of all memory operations +; May miss optimization opportunities +} +``` + +With TypeTrees: +```llvm +define "enzyme_type"="{[-1]:Float@float}" float @distance( + ptr "enzyme_type"="{[-1]:Pointer, [-1,0]:Float@float}" %p1, + ptr "enzyme_type"="{[-1]:Pointer, [-1,0]:Float@float}" %p2 +) { +; Enzyme knows exact type layout +; Can generate efficient derivative code directly +} +``` + +# TypeTrees - Offset and -1 Explained + +## Type Structure + +```rust +Type { + offset: isize, // WHERE this type starts + size: usize, // HOW BIG this type is + kind: Kind, // WHAT KIND of data (Float, Int, Pointer) + child: TypeTree // WHAT'S INSIDE (for pointers/containers) +} +``` + +## Offset Values + +### Regular Offset (0, 4, 8, etc.) +**Specific byte position within a structure** + +```rust +struct Point { + x: f32, // offset 0, size 4 + y: f32, // offset 4, size 4 + id: i32, // offset 8, size 4 +} +``` + +TypeTree for `&Point` (internal representation): +```rust +TypeTree(vec![ + Type { offset: 0, size: 4, kind: Float }, // x at byte 0 + Type { offset: 4, size: 4, kind: Float }, // y at byte 4 + Type { offset: 8, size: 4, kind: Integer } // id at byte 8 +]) +``` + +Generates LLVM +```llvm +"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer}" +``` + +### Offset -1 (Special: "Everywhere") +**Means "this pattern repeats for ALL elements"** + +#### Example 1: Direct Array `[f32; 100]` (no pointer indirection) +```rust +TypeTree(vec![Type { + offset: -1, // ALL positions + size: 4, // each f32 is 4 bytes + kind: Float, // every element is float +}]) +``` + +Generates LLVM: `"enzyme_type"="{[-1]:Float@float}"` + +#### Example 1b: Array Reference `&[f32; 100]` (with pointer indirection) +```rust +TypeTree(vec![Type { + offset: -1, size: 8, kind: Pointer, + child: TypeTree(vec![Type { + offset: -1, // ALL array elements + size: 4, // each f32 is 4 bytes + kind: Float, // every element is float + }]) +}]) +``` + +Generates LLVM: `"enzyme_type"="{[-1]:Pointer, [-1,-1]:Float@float}"` + +Instead of listing 100 separate Types with offsets `0,4,8,12...396` + +#### Example 2: Slice `&[i32]` +```rust +// Pointer to slice data +TypeTree(vec![Type { + offset: -1, size: 8, kind: Pointer, + child: TypeTree(vec![Type { + offset: -1, // ALL slice elements + size: 4, // each i32 is 4 bytes + kind: Integer + }]) +}]) +``` + +Generates LLVM: `"enzyme_type"="{[-1]:Pointer, [-1,-1]:Integer}"` + +#### Example 3: Mixed Structure +```rust +struct Container { + header: i64, // offset 0 + data: [f32; 1000], // offset 8, but elements use -1 +} +``` + +```rust +TypeTree(vec![ + Type { offset: 0, size: 8, kind: Integer }, // header + Type { offset: 8, size: 4000, kind: Pointer, + child: TypeTree(vec![Type { + offset: -1, size: 4, kind: Float // ALL array elements + }]) + } +]) +``` + +## Key Distinction: Single Values vs Arrays + +**Single Values** use offset `0` for precision: +- `&f32` has exactly one f32 value at offset 0 +- More precise than using -1 ("everywhere") +- Generates: `{[-1]:Pointer, [-1,0]:Float@float}` + +**Arrays** use offset `-1` for efficiency: +- `&[f32; 100]` has the same pattern repeated 100 times +- Using -1 avoids listing 100 separate offsets +- Generates: `{[-1]:Pointer, [-1,-1]:Float@float}` \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/writing-tools-in-bootstrap.md b/src/doc/rustc-dev-guide/src/building/bootstrapping/writing-tools-in-bootstrap.md index c3660e24b1526..8ac2e6bfe287c 100644 --- a/src/doc/rustc-dev-guide/src/building/bootstrapping/writing-tools-in-bootstrap.md +++ b/src/doc/rustc-dev-guide/src/building/bootstrapping/writing-tools-in-bootstrap.md @@ -3,18 +3,32 @@ There are three types of tools you can write in bootstrap: - **`Mode::ToolBootstrap`** + Use this for tools that don’t need anything from the in-tree compiler and can run with the stage0 `rustc`. - The output is placed in the "bootstrap-tools" directory. This mode is for general-purpose tools built - entirely with the stage0 compiler, including target libraries and only works for stage 0. + The output is placed in the "bootstrap-tools" directory. + This mode is for general-purpose tools built entirely with the stage0 compiler, + including target libraries, and it only works for stage 0. - **`Mode::ToolStd`** - Use this for tools that rely on the locally built std. The output goes into the "stageN-tools" directory. + + Use this for tools that rely on the locally built std. + The output goes into the "stageN-tools" directory. This mode is rarely used, mainly for `compiletest` which requires `libtest`. - **`Mode::ToolRustcPrivate`** - Use this for tools that use the `rustc_private` mechanism, and thus depend on the locally built `rustc` and its rlib artifacts. This is more complex than the other modes because the tool must be built with the same compiler used for `rustc` and placed in the "stageN-tools" directory. When you choose `Mode::ToolRustcPrivate`, `ToolBuild` implementation takes care of this automatically. If you need to use the builder’s compiler for something specific, you can get it from `ToolBuildResult`, which is - returned by the tool's [`Step`]. -Regardless of the tool type you must return `ToolBuildResult` from the tool’s [`Step`] implementation and use `ToolBuild` inside it. + Use this for tools that use the `rustc_private` mechanism, + and thus depend on the locally built `rustc` and its rlib artifacts. + This is more complex than the other modes, + because the tool must be built with the same compiler used for `rustc`, + and placed in the "stageN-tools" directory. + When you choose `Mode::ToolRustcPrivate`, + `ToolBuild` implementation takes care of this automatically. + If you need to use the builder’s compiler for something specific, + you can get it from `ToolBuildResult`, which is returned by the tool's [`Step`]. + +Regardless of the tool type, +you must return `ToolBuildResult` from the tool’s [`Step`] implementation, +and use `ToolBuild` inside it. [`Step`]: https://doc.rust-lang.org/nightly/nightly-rustc/bootstrap/core/builder/trait.Step.html diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md index b07d3533f59bc..36610f28854b5 100644 --- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md +++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md @@ -149,7 +149,7 @@ On Windows, the Powershell commands may give you an error that looks like this: ``` PS C:\Users\vboxuser\rust> ./x ./x : File C:\Users\vboxuser\rust\x.ps1 cannot be loaded because running scripts is disabled on this system. For more -information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170. +information, see about_Execution_Policies at https://go.microsoft.com/fwlink/?LinkID=135170. At line:1 char:1 + ./x + ~~~ diff --git a/src/doc/rustc-dev-guide/src/compiler-team.md b/src/doc/rustc-dev-guide/src/compiler-team.md index 6be52833f3964..896d9e6f6d94c 100644 --- a/src/doc/rustc-dev-guide/src/compiler-team.md +++ b/src/doc/rustc-dev-guide/src/compiler-team.md @@ -1,10 +1,14 @@ # About the compiler team +> NOTE: +> There exists much detail about the team [on Forge], making most of the following obsolete. + rustc is maintained by the [Rust compiler team][team]. The people who belong to this team collectively work to track regressions and implement new features. Members of the Rust compiler team are people who have made significant contributions to rustc and its design. +[on Forge]: https://forge.rust-lang.org/compiler [team]: https://www.rust-lang.org/governance/teams/compiler ## Discussion diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 3000537861778..cc98b49a97c68 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -90,14 +90,15 @@ Here are a few things you can do to help the Rust project after filing an ICE. triggering the ICE, such as syntax errors or borrow-checking errors - Minimize the test case (see below). If successful, you can label the issue with `S-has-mcve`. Otherwise, you can apply `E-needs-mcve`. -- Add the minimal test case to the rust-lang/rust repo as a [crashes test]. +- Add the minimal test case to the rust-lang/rust repo as a [crash test]. While you're at it, consider including other "untracked" crashes in your PR. - Please don't forget to mark your issue with `S-bug-has-test` afterwards. + Please don't forget to mark all relevant issues with `S-bug-has-test` once + your PR is merged. See also [applying and removing labels][labeling]. [bisect]: https://rust-lang.github.io/cargo-bisect-rustc/ -[crashes test]: tests/compiletest.html#crashes-tests +[crash test]: tests/compiletest.html#crash-tests [labeling]: https://forge.rust-lang.org/release/issue-triaging.html#applying-and-removing-labels ## Minimization diff --git a/src/doc/rustc-dev-guide/src/profiling/with_perf.md b/src/doc/rustc-dev-guide/src/profiling/with_perf.md index 0d4f23bcd9ad3..e452dde5226d4 100644 --- a/src/doc/rustc-dev-guide/src/profiling/with_perf.md +++ b/src/doc/rustc-dev-guide/src/profiling/with_perf.md @@ -4,8 +4,7 @@ This is a guide for how to profile rustc with [perf](https://perf.wiki.kernel.or ## Initial steps -- Get a clean checkout of rust-lang/master, or whatever it is you want - to profile. +- Get a clean checkout of rust-lang/rust - Set the following settings in your `bootstrap.toml`: - `rust.debuginfo-level = 1` - enables line debuginfo - `rust.jemalloc = false` - lets you do memory use profiling with valgrind diff --git a/src/doc/rustc-dev-guide/src/tests/best-practices.md b/src/doc/rustc-dev-guide/src/tests/best-practices.md index efc626035b79d..10372c36ac99e 100644 --- a/src/doc/rustc-dev-guide/src/tests/best-practices.md +++ b/src/doc/rustc-dev-guide/src/tests/best-practices.md @@ -71,7 +71,7 @@ related tests. > //! Regression test for . > ``` > -> One exception to this rule is [crashes tests]: there it is canonical that +> One exception to this rule is [crash tests]: there it is canonical that > tests are named only after issue numbers because its purpose is to track > snippets from which issues no longer ICE/crash, and they would either be > removed or converted into proper ui/other tests in the fix PRs. @@ -199,4 +199,4 @@ See [LLVM FileCheck guide][FileCheck] for details. [compiletest directives]: ./directives.md [`run-make`]: ./compiletest.md#run-make-tests [FileCheck]: https://llvm.org/docs/CommandGuide/FileCheck.html -[crashes tests]: ./compiletest.md#crashes-tests +[crash tests]: ./compiletest.md#crash-tests diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index a8cc959124ff6..6c0b5c2e84554 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -1,18 +1,18 @@ # Testing with CI The primary goal of our CI system is to ensure that the `master` branch of -`rust-lang/rust` is always in a valid state and passes our test suite. +`rust-lang/rust` is always in a valid state by passing our test suite. From a high-level point of view, when you open a pull request at `rust-lang/rust`, the following will happen: - A small [subset](#pull-request-builds) of tests and checks are run after each - push to the PR. This should help catching common errors. + push to the PR. This should help catch common errors. - When the PR is approved, the [bors] bot enqueues the PR into a [merge queue]. - Once the PR gets to the front of the queue, bors will create a merge commit and run the [full test suite](#auto-builds) on it. The merge commit either contains only one specific PR or it can be a ["rollup"](#rollups) which - combines multiple PRs together, to save CI costs. + combines multiple PRs together, to reduce CI costs and merge delays. - Once the whole test suite finishes, two things can happen. Either CI fails with an error that needs to be addressed by the developer, or CI succeeds and the merge commit is then pushed to the `master` branch. @@ -38,12 +38,12 @@ input, which contains a declarative configuration of all our CI jobs. > orchestrating the scripts that drive the process. In essence, all CI jobs run `./x test`, `./x dist` or some other command with -different configurations, across various operating systems, targets and +different configurations, across various operating systems, targets, and platforms. There are two broad categories of jobs that are executed, `dist` and non-`dist` jobs. - Dist jobs build a full release of the compiler for a specific platform, - including all the tools we ship through rustup; Those builds are then uploaded + including all the tools we ship through rustup. Those builds are then uploaded to the `rust-lang-ci2` S3 bucket and are available to be locally installed with the [rustup-toolchain-install-master] tool. The same builds are also used for actual releases: our release process basically consists of copying those @@ -70,7 +70,7 @@ these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `pr-check-1`, `pr-che and `tidy` jobs, all running on Linux. These execute a relatively short (~40 minutes) and lightweight test suite that should catch common issues. More specifically, they run a set of lints, they try to perform a cross-compile check -build to Windows mingw (without producing any artifacts) and they test the +build to Windows mingw (without producing any artifacts), and they test the compiler using a *system* version of LLVM. Unfortunately, it would take too many resources to run the full test suite for each commit on every PR. @@ -95,17 +95,16 @@ jobs that exercise various tests across operating systems and targets. The full test suite is quite slow; it can take several hours until all the `auto` CI jobs finish. -Most platforms only run the build steps, some run a restricted set of tests, +Most platforms only run the build steps, some run a restricted set of tests; only a subset run the full suite of tests (see Rust's [platform tiers]). Auto jobs are defined in the `auto` section of [`jobs.yml`]. They are executed -on the `auto` branch under the `rust-lang/rust` repository and -their results can be seen [here](https://github.com/rust-lang/rust/actions), -although usually you will be notified of the result by a comment made by bors on -the corresponding PR. +on the `auto` branch under the `rust-lang/rust` repository, +and the final result will be reported via a comment made by bors on the corresponding PR. +The live results can be seen on [the GitHub Actions workflows page]. At any given time, at most a single `auto` build is being executed. Find out -more [here](#merging-prs-serially-with-bors). +more in [Merging PRs serially with bors](#merging-prs-serially-with-bors). [platform tiers]: https://forge.rust-lang.org/release/platform-support.html#rust-platform-support @@ -125,7 +124,7 @@ There are several use-cases for try builds: when you start a try build). To create a try build and schedule it for a performance benchmark, you can use the `@bors try @rust-timer queue` command combination. -- Check the impact of the PR across the Rust ecosystem, using a [crater] run. +- Check the impact of the PR across the Rust ecosystem, using a [Crater](crater.md) run. Again, a working compiler build is needed for this, which can be produced by the [dist-x86_64-linux] CI job. - Run a specific CI job (e.g. Windows tests) on a PR, to quickly test if it @@ -134,11 +133,11 @@ There are several use-cases for try builds: By default, if you send a comment with `@bors try`, the jobs defined in the `try` section of [`jobs.yml`] will be executed. We call this mode a "fast try build". Such a try build will not execute any tests, and it will allow compilation warnings. It is useful when you want to -get an optimized toolchain as fast as possible, for a crater run or performance benchmarks, +get an optimized toolchain as fast as possible, for a Crater run or performance benchmarks, even if it might not be working fully correctly. If you want to do a full build for the default try job, specify its job name in a job pattern (explained below). -If you want to run custom CI job(s) in a try build and make sure that they pass all tests and do +If you want to run custom CI jobs in a try build and make sure that they pass all tests and do not produce any compilation warnings, you can select CI jobs to be executed by specifying a *job pattern*, which can be used in one of two ways: - You can add a set of `try-job: ` directives to the PR description (described below) and then @@ -151,8 +150,9 @@ which can be used in one of two ways: Each job pattern can either be an exact name of a job or a glob pattern that matches multiple jobs, for example `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try build. When using -glob patterns, you might want to wrap them in backticks (`` ` ``) to avoid GitHub rendering -the pattern as Markdown. +glob patterns in the PR description, you can optionally wrap them in backticks (`` ` ``) to avoid GitHub rendering +the pattern as Markdown if it contains e.g. an asterisk. Note that this escaping will not work when using +the `@bors jobs=` parameter. The job pattern needs to match one or more jobs defined in the `auto` or `optional` sections of [`jobs.yml`]: @@ -189,18 +189,17 @@ of [`jobs.yml`]: > that are exercised this way. Try builds are executed on the `try` branch under the `rust-lang/rust` repository and -their results can be seen [here](https://github.com/rust-lang/rust/actions), +their results can be seen on [the GitHub Actions workflows page], although usually you will be notified of the result by a comment made by bors on the corresponding PR. Multiple try builds can execute concurrently across different PRs, but there can be at most a single try build running on a single PR at any given time. -Note that try builds are handled using the new [bors][new-bors] implementation. +Note that try builds are handled using the [new bors] implementation. [rustc-perf]: https://github.com/rust-lang/rustc-perf -[crater]: https://github.com/rust-lang/crater -[new-bors]: https://github.com/rust-lang/bors +[new bors]: https://github.com/rust-lang/bors ### Modifying CI jobs @@ -210,8 +209,7 @@ If you want to modify what gets executed on our CI, you can simply modify the You can also modify what gets executed temporarily, for example to test a particular platform or configuration that is challenging to test locally (for example, if a Windows build fails, but you don't have access to a Windows -machine). Don't hesitate to use CI resources in such situations to try out a -fix! +machine). Don't hesitate to use CI resources in such situations. You can perform an arbitrary CI job in two ways: - Use the [try build](#try-builds) functionality, and specify the CI jobs that @@ -254,8 +252,8 @@ purposes. Although you are welcome to use CI, just be conscious that this is a shared -resource with limited concurrency. Try not to enable too many jobs at once (one -or two should be sufficient in most cases). +resource with limited concurrency. Try not to enable too many jobs at once; +one or two should be sufficient in most cases. ## Merging PRs serially with bors @@ -279,12 +277,12 @@ by listening for either Commit Statuses or Check Runs. Since the merge commit is based on the latest `master` and only one can be tested at the same time, when the results are green, `master` is fast-forwarded to that merge commit. -Unfortunately testing a single PR at the time, combined with our long CI (~2 -hours for a full run), means we can’t merge too many PRs in a single day, and a -single failure greatly impacts our throughput for the day. The maximum number of +Unfortunately, testing a single PR at a time, combined with our long CI (~2 +hours for a full run), means we can’t merge a lot of PRs in a single day, and a +single failure greatly impacts our throughput. The maximum number of PRs we can merge in a day is around ~10. -The large CI run times and requirement for a large builder pool is largely due +The long CI run times, and requirement for a large builder pool, is largely due to the fact that full release artifacts are built in the `dist-` builders. This is worth it because these release artifacts: @@ -297,12 +295,11 @@ is worth it because these release artifacts: Some PRs don’t need the full test suite to be executed: trivial changes like typo fixes or README improvements *shouldn’t* break the build, and testing every -single one of them for 2+ hours is a big waste of time. To solve this, we +single one of them for 2+ hours would be wasteful. To solve this, we regularly create a "rollup", a PR where we merge several pending trivial PRs so they can be tested together. Rollups are created manually by a team member using the "create a rollup" button on the [merge queue]. The team member uses their -judgment to decide if a PR is risky or not, and are the best tool we have at the -moment to keep the queue in a manageable state. +judgment to decide if a PR is risky or not. ## Docker @@ -315,18 +312,22 @@ platform’s custom [Docker container]. This has a lot of advantages for us: - We can use ancient build environments to ensure maximum binary compatibility, for example [using older CentOS releases][dist-x86_64-linux] on our Linux builders. -- We can avoid reinstalling tools (like QEMU or the Android emulator) every time +- We can avoid reinstalling tools (like QEMU or the Android emulator) every time, thanks to Docker image caching. -- Users can run the same tests in the same environment locally by just running - `cargo run --manifest-path src/ci/citool/Cargo.toml run-local `, which is awesome to debug failures. Note that there are only linux docker images available locally due to licensing and +- Users can run the same tests in the same environment locally by just running this command: + + cargo run --manifest-path src/ci/citool/Cargo.toml run-local + + This is helpful for debugging failures. + Note that there are only Linux Docker images available locally due to licensing and other restrictions. -The docker images prefixed with `dist-` are used for building artifacts while +The Docker images prefixed with `dist-` are used for building artifacts while those without that prefix run tests and checks. We also run tests for less common architectures (mainly Tier 2 and Tier 3 -platforms) in CI. Since those platforms are not x86 we either run everything -inside QEMU or just cross-compile if we don’t want to run the tests for that +platforms) in CI. Since those platforms are not x86, we either run everything +inside QEMU, or we just cross-compile if we don’t want to run the tests for that platform. These builders are running on a special pool of builders set up and maintained @@ -363,41 +364,41 @@ invalidated if one of the following changes: [ghcr.io]: https://github.com/rust-lang/rust/pkgs/container/rust-ci [Docker registry caching]: https://docs.docker.com/build/cache/backends/registry/ -### LLVM caching with sccache +### LLVM caching with Sccache -We build some C/C++ stuff in various CI jobs, and we rely on [sccache] to cache +We build some C/C++ stuff in various CI jobs, and we rely on [Sccache] to cache the intermediate LLVM artifacts. Sccache is a distributed ccache developed by Mozilla, which can use an object storage bucket as the storage backend. -With sccache there's no need to calculate the hash key ourselves. Sccache +With Sccache there's no need to calculate the hash key ourselves. Sccache invalidates the cache automatically when it detects changes to relevant inputs, such as the source code, the version of the compiler, and important environment variables. -So we just pass the sccache wrapper on top of cargo and sccache does the rest. +So we just pass the Sccache wrapper on top of Cargo and Sccache does the rest. -We store the persistent artifacts on the S3 bucket `rust-lang-ci-sccache2`. So -when the CI runs, if sccache sees that LLVM is being compiled with the same C/C++ -compiler and the LLVM source code is the same, sccache retrieves the individual +We store the persistent artifacts on the S3 bucket, `rust-lang-ci-sccache2`. So +when the CI runs, if Sccache sees that LLVM is being compiled with the same C/C++ +compiler and the LLVM source code is the same, Sccache retrieves the individual compiled translation units from S3. [sccache]: https://github.com/mozilla/sccache ## Custom tooling around CI -During the years we developed some custom tooling to improve our CI experience. +During the years, we developed some custom tooling to improve our CI experience. ### Rust Log Analyzer to show the error message in PRs The build logs for `rust-lang/rust` are huge, and it’s not practical to find -what caused the build to fail by looking at the logs. To improve the developers’ -experience we developed a bot called [Rust Log Analyzer][rla] (RLA) that -receives the build logs on failure and extracts the error message automatically, -posting it on the PR. +what caused the build to fail by looking at the logs. +We therefore developed a bot called [Rust Log Analyzer][rla] (RLA) that +receives the build logs on failure, and extracts the error message automatically, +posting it on the PR thread. The bot is not hardcoded to look for error strings, but was trained with a bunch of build failures to recognize which lines are common between builds and which are not. While the generated snippets can be weird sometimes, the bot is pretty -good at identifying the relevant lines even if it’s an error we've never seen +good at identifying the relevant lines, even if it’s an error we've never seen before. [rla]: https://github.com/rust-lang/rust-log-analyzer @@ -429,11 +430,11 @@ More information is available in the [toolstate documentation]. ## Public CI dashboard -To monitor the Rust CI, you can have a look at the [public dashboard] maintained by the infra-team. +To monitor the Rust CI, you can have a look at the [public dashboard] maintained by the infra team. These are some useful panels from the dashboard: -- Pipeline duration: check how long the auto builds takes to run. +- Pipeline duration: check how long the auto builds take to run. - Top slowest jobs: check which jobs are taking the longest to run. - Change in median job duration: check what jobs are slowest than before. Useful to detect regressions. @@ -456,8 +457,7 @@ this: 2. Choose the job you are interested in on the left-hand side. 3. Click on the gear icon and choose "View raw logs" 4. Search for the string "Configure the build" -5. All of the build settings are listed below that starting with the - `configure:` prefix. +5. All of the build settings are listed on the line with the text, `build.configure-args` [GitHub Actions]: https://github.com/rust-lang/rust/actions [`jobs.yml`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/jobs.yml @@ -467,3 +467,4 @@ this: [homu]: https://github.com/rust-lang/homu [merge queue]: https://bors.rust-lang.org/queue/rust [dist-x86_64-linux]: https://github.com/rust-lang/rust/blob/master/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +[the GitHub Actions workflows page]: https://github.com/rust-lang/rust/actions diff --git a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md index 4caf4c0e0eefa..74dbfb7d31b30 100644 --- a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md +++ b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md @@ -1,3 +1,56 @@ -# GCC codegen backend tests +# GCC codegen backend -TODO: please add some more information to this page. +If you ran into an error related to tests executed with the GCC codegen backend on CI, +you can use the following command to run tests locally using the GCC backend: + +```bash +./x test tests/ui --set 'rust.codegen-backends = ["llvm", "gcc"]' --test-codegen-backend gcc +``` + +Below, you can find more information about how to configure the GCC backend in bootstrap. + +## Choosing which codegen backends are built + +The `rust.codegen-backends = [...]` bootstrap option affects which codegen backends will be built and +included in the sysroot of the produced `rustc`. To use the GCC codegen backend, `"gcc"` has to +be included in this array in `bootstrap.toml`: + +```toml +rust.codegen-backends = ["llvm", "gcc"] +``` + +If you don't want to change your `bootstrap.toml` file, you can alternatively run your `x` +commands with `--set rust.codegen-backends=["llvm", "gcc"]'`. For example: + +```bash +./x build --set 'rust.codegen-backends=["llvm", "gcc"]' +``` + +The first backend in the `codegen-backends` array will determine which backend will be used as the +*default backend* of the built `rustc`. This also determines which backend will be used to compile the +stage 1 standard library (or anything built in stage 2+). To produce `rustc` that uses the GCC backend +by default, you can thus put `"gcc"` as the first element of this array: + +```bash +./x build --set 'rust.codegen-backends=["gcc"]' library +``` + +## Choosing the codegen backend used in tests + +To run compiler tests with the GCC codegen backend being used to build the test Rust programs, you can use the +`--test-codegen-backend` flag: + +```bash +./x test tests/ui --test-codegen-backend gcc +``` + +Note that in order for this to work, the tested compiler must have the GCC codegen backend available in its sysroot +directory. You can achieve that using the [instructions above](#choosing-which-codegen-backends-are-built). + +## Downloading GCC from CI + +The `gcc.download-ci-gcc` bootstrap option controls if GCC (which is a dependency of the GCC codegen backend) +will be downloaded from CI or built locally. The default value is `true`, which will download GCC from CI +if there are no local changes to the GCC sources and the given host target is available on CI. + +Note that GCC can currently only be downloaded from CI for the `x86_64-unknown-linux-gnu` target. diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index a4a729935fa47..0234b394c2a05 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -72,7 +72,7 @@ The following test suites are available, with links for more information: | [`mir-opt`](#mir-opt-tests) | Check MIR generation and optimizations | | [`coverage`](#coverage-tests) | Check coverage instrumentation | | [`coverage-run-rustdoc`](#coverage-tests) | `coverage` tests that also run instrumented doctests | -| [`crashes`](#crashes-tests) | Check that the compiler ICEs/panics/crashes on certain inputs to catch accidental fixes | +| [`crashes`](#crash-tests) | Check that the compiler ICEs/panics/crashes on certain inputs to catch accidental fixes | ### General purpose test suite @@ -557,7 +557,7 @@ only running the main `coverage` suite. [`src/tools/coverage-dump`]: https://github.com/rust-lang/rust/tree/master/src/tools/coverage-dump [`tests/coverage-run-rustdoc`]: https://github.com/rust-lang/rust/tree/master/tests/coverage-run-rustdoc -### Crashes tests +### Crash tests [`tests/crashes`] serve as a collection of tests that are expected to cause the compiler to ICE, panic or crash in some other way, so that accidental fixes are @@ -580,13 +580,13 @@ recommended to include test cases from several issues in a single PR. When you do so, each issue number should be noted in the file name (`12345.rs` should suffice) and also inside the file by means of a `//@ known-bug: #12345` directive. Please [label][labeling] the relevant issues with `S-bug-has-test` -afterwards. +once your PR is merged. If you happen to fix one of the crashes, please move it to a fitting subdirectory in `tests/ui` and give it a meaningful name. Please add a doc comment at the top of the file explaining why this test exists, even better if you can briefly explain how the example causes rustc to crash previously and -what was done to prevent rustc to ICE/panic/crash. +what was done to prevent rustc to ICE / panic / crash. Adding diff --git a/src/doc/rustc-dev-guide/src/tests/crater.md b/src/doc/rustc-dev-guide/src/tests/crater.md index 9d4ac87daf36a..96bb5a4f2ae67 100644 --- a/src/doc/rustc-dev-guide/src/tests/crater.md +++ b/src/doc/rustc-dev-guide/src/tests/crater.md @@ -8,30 +8,30 @@ stable compiler versions. ## When to run Crater -You should request a crater run if your PR makes large changes to the compiler +You should request a Crater run if your PR makes large changes to the compiler or could cause breakage. If you are unsure, feel free to ask your PR's reviewer. ## Requesting Crater Runs -The rust team maintains a few machines that can be used for running crater runs -on the changes introduced by a PR. If your PR needs a crater run, leave a +The Rust team maintains a few machines that can be used for Crater runs +on the changes introduced by a PR. If your PR needs a Crater run, leave a comment for the triage team in the PR thread. Please inform the team whether you -require a "check-only" crater run, a "build only" crater run, or a -"build-and-test" crater run. The difference is primarily in time; the -conservative (if you're not sure) option is to go for the build-and-test run. If +require a "check-only" Crater run, a "build only" Crater run, or a +"build-and-test" Crater run. The difference is primarily in time; +if you're not sure, go for the build-and-test run. If making changes that will only have an effect at compile-time (e.g., implementing -a new trait) then you only need a check run. +a new trait), then you only need a check run. Your PR will be enqueued by the triage team and the results will be posted when -they are ready. Check runs will take around ~3-4 days, with the other two taking +they are ready. Check runs will take around ~3-4 days, and the other two taking 5-6 days on average. -While crater is really useful, it is also important to be aware of a few +While Crater is really useful, it is also important to be aware of a few caveats: - Not all code is on crates.io! There is a lot of code in repos on GitHub and elsewhere. Also, companies may not wish to publish their code. Thus, a - successful crater run is not a magically green light that there will be no + successful Crater run does not mean there will be no breakage; you still need to be careful. - Crater only runs Linux builds on x86_64. Thus, other architectures and @@ -41,5 +41,5 @@ caveats: the crate doesn't compile any more (e.g. used old nightly features), has broken or flaky tests, requires network access, or other reasons. -- Before crater can be run, `@bors try` needs to succeed in building artifacts. - This means that if your code doesn't compile, you cannot run crater. +- Before Crater can be run, `@bors try` needs to succeed in building artifacts. + This means that if your code doesn't compile, you cannot run Crater. diff --git a/src/doc/rustc-dev-guide/src/tracing.md b/src/doc/rustc-dev-guide/src/tracing.md index 5e5b81fc65b22..a7cdab73e7973 100644 --- a/src/doc/rustc-dev-guide/src/tracing.md +++ b/src/doc/rustc-dev-guide/src/tracing.md @@ -109,7 +109,7 @@ Miri, use `MIRI_LOG` instead. You get the idea :) See the [`tracing`] crate's docs, and specifically the docs for [`debug!`] to see the full syntax you can use. (Note: unlike the compiler, the [`tracing`] -crate and its examples use the `RUST_LOG` environment variable. rustc, rustdoc, +crate and its examples use the `RUSTC_LOG` environment variable. rustc, rustdoc, and other tools set custom environment variables.) **Note that unless you use a very strict filter, the logger will emit a lot of diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index cdada5a223062..6597c3c70f691 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -12,7 +12,7 @@ path = "src/bin/main.rs" [dependencies] # tidy-alphabetical-start -anstyle-svg = "0.1.3" +anstyle-svg = "0.1.11" build_helper = { path = "../../build_helper" } camino = "1" colored = "2" diff --git a/tests/run-make/crate-loading/multiple-dep-versions-3.rs b/tests/run-make/crate-loading/dep-2-reexport.rs similarity index 100% rename from tests/run-make/crate-loading/multiple-dep-versions-3.rs rename to tests/run-make/crate-loading/dep-2-reexport.rs diff --git a/tests/run-make/crate-loading/multiple-dep-versions-1.rs b/tests/run-make/crate-loading/dependency-1.rs similarity index 100% rename from tests/run-make/crate-loading/multiple-dep-versions-1.rs rename to tests/run-make/crate-loading/dependency-1.rs diff --git a/tests/run-make/crate-loading/multiple-dep-versions-2.rs b/tests/run-make/crate-loading/dependency-2.rs similarity index 100% rename from tests/run-make/crate-loading/multiple-dep-versions-2.rs rename to tests/run-make/crate-loading/dependency-2.rs diff --git a/tests/run-make/crate-loading/rmake.rs b/tests/run-make/crate-loading/rmake.rs index 6ad456e3e3e57..8f2577861239d 100644 --- a/tests/run-make/crate-loading/rmake.rs +++ b/tests/run-make/crate-loading/rmake.rs @@ -6,12 +6,9 @@ use run_make_support::{diff, rust_lib_name, rustc}; fn main() { - rustc().input("multiple-dep-versions-1.rs").run(); - rustc().input("multiple-dep-versions-2.rs").extra_filename("2").metadata("2").run(); - rustc() - .input("multiple-dep-versions-3.rs") - .extern_("dependency", rust_lib_name("dependency2")) - .run(); + rustc().input("dependency-1.rs").run(); + rustc().input("dependency-2.rs").extra_filename("2").metadata("2").run(); + rustc().input("dep-2-reexport.rs").extern_("dependency", rust_lib_name("dependency2")).run(); let out = rustc() .input("multiple-dep-versions.rs") diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg b/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg index 1cedbf75e4bf6..7ffbc64b074bf 100644 --- a/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg +++ b/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg @@ -1,7 +1,7 @@ - +