From 108bfc13febf252b41daeb0f833865b70ef24d8d Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Fri, 30 May 2025 15:32:46 +0300 Subject: [PATCH 01/64] Update opaque-types-type-alias-impl-trait.md 1. Clarify that there is a single concrete type for an opaque type 2. Clarify that defining a type alias to an opaque type is an unstable feature 3. Add complete example 4. Clarify that defining an associate type as opaque is an unstable feature 5. Add another complete example --- .../src/opaque-types-type-alias-impl-trait.md | 51 ++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md index 956f568285a02..0f0e8e87c3213 100644 --- a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md +++ b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md @@ -12,15 +12,16 @@ type Foo = impl Bar; This declares an opaque type named `Foo`, of which the only information is that it implements `Bar`. Therefore, any of `Bar`'s interface can be used on a `Foo`, -but nothing else (regardless of whether it implements any other traits). +but nothing else (regardless of whether the concrete type implements any other traits). Since there needs to be a concrete background type, -you can (as of January 2021) express that type +you can (as of May 2025) express that type by using the opaque type in a "defining use site". ```rust,ignore struct Struct; impl Bar for Struct { /* stuff */ } +#[define_opaque(Foo)] fn foo() -> Foo { Struct } @@ -28,6 +29,27 @@ fn foo() -> Foo { Any other "defining use site" needs to produce the exact same type. +Note that defining a type alias to an opaque type is an unstable feature. +To use it, you need `nightly` and the annotations `#![feature(type_alias_impl_trait)]` on the file and `#[define_opaque(Foo)]` on the method that links the opaque type to the concrete type. +Complete example: + +```rust +#![feature(type_alias_impl_trait)] + +trait Bar { /* stuff */ } + +type Foo = impl Bar; + +struct Struct; + +impl Bar for Struct { /* stuff */ } + +#[define_opaque(Foo)] +fn foo() -> Foo { + Struct +} +``` + ## Defining use site(s) Currently only the return value of a function can be a defining use site @@ -61,3 +83,28 @@ impl Baz for Quux { fn foo() -> Self::Foo { ... } } ``` + +For this you would also need to use `nightly` and the (different) `#![feature(impl_trait_in_assoc_type)]` annotation. +Note that you don't need a `#[define_opaque(Foo)]` on the method anymore. +Complete example: + +``` +#![feature(impl_trait_in_assoc_type)] + +trait Bar {} +struct Zap; + +impl Bar for Zap {} + +trait Baz { + type Foo; + fn foo() -> Self::Foo; +} + +struct Quux; + +impl Baz for Quux { + type Foo = impl Bar; + fn foo() -> Self::Foo { Zap } +} +``` From 8a50a15d72524b5802e45ae23fa6574d3132de6f Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sun, 31 Aug 2025 00:04:22 +0200 Subject: [PATCH 02/64] make sentence more clear --- src/doc/rustc-dev-guide/src/tests/compiletest.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index 4980ed845d6dd..cda5c1bcec715 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -90,7 +90,8 @@ The following test suites are available, with links for more information: | `rustdoc-ui` | Check terminal output of `rustdoc` ([see also](ui.md)) | Some rustdoc-specific tests can also be found in `ui/rustdoc/`. -These check rustdoc-related or -specific lints that (also) run as part of `rustc`, not (only) `rustdoc`. +These tests ensure that lints that are emitted as part of executing rustdoc +are also run when executing rustc. Run-make tests pertaining to rustdoc are typically named `run-make/rustdoc-*/`. [rustdoc-html-tests]: ../rustdoc-internals/rustdoc-test-suite.md From e548d77721254a12519b2d04a00c6b5afd0758d6 Mon Sep 17 00:00:00 2001 From: "Tim (Theemathas) Chirananthavat" Date: Tue, 21 Oct 2025 17:51:38 +0700 Subject: [PATCH 03/64] Remove an attempted error annotation This file previously contained an error annotation with incorrect syntax. Remove this annotation, as per the dev guide, since this is marked as known-bug. https://rustc-dev-guide.rust-lang.org/tests/ui.html#known-bugs --- .../const-traits/const_closure-const_trait_impl-ice-113381.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs index 30002038f6891..e355ee724d1bd 100644 --- a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs +++ b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs @@ -13,6 +13,4 @@ impl Foo for () { fn main() { (const || (()).foo())(); - // ^ ERROR: cannot call non-const method `<() as Foo>::foo` in constant functions - // FIXME(const_trait_impl) this should probably say constant closures } From a2d1d14f682c7976a089c26546ab55c7c2e66744 Mon Sep 17 00:00:00 2001 From: "Tim (Theemathas) Chirananthavat" Date: Tue, 21 Oct 2025 14:10:07 +0700 Subject: [PATCH 04/64] Make `const BorrowMut` require `const Borrow` --- library/core/src/borrow.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/borrow.rs b/library/core/src/borrow.rs index 78ba69fec1422..eb4562bda4ce3 100644 --- a/library/core/src/borrow.rs +++ b/library/core/src/borrow.rs @@ -187,7 +187,7 @@ pub const trait Borrow { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "BorrowMut"] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] -pub const trait BorrowMut: Borrow { +pub const trait BorrowMut: [const] Borrow { /// Mutably borrows from an owned value. /// /// # Examples From 28819e0f4b860f62d2e1748fdc19a1628cc5933c Mon Sep 17 00:00:00 2001 From: "Tim (Theemathas) Chirananthavat" Date: Tue, 21 Oct 2025 14:11:33 +0700 Subject: [PATCH 05/64] Make `const Fn` require `const FnMut` --- library/core/src/ops/function.rs | 2 +- tests/ui/traits/const-traits/call.rs | 1 + tests/ui/traits/const-traits/call.stderr | 11 ++++++++++- .../const_closure-const_trait_impl-ice-113381.stderr | 11 ++++++++++- .../non-const-op-const-closure-non-const-outer.rs | 1 + .../non-const-op-const-closure-non-const-outer.stderr | 11 ++++++++++- 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs index 479368ba8f801..efe5c0871fb8b 100644 --- a/library/core/src/ops/function.rs +++ b/library/core/src/ops/function.rs @@ -73,7 +73,7 @@ use crate::marker::Tuple; #[fundamental] // so that regex can rely that `&str: !FnMut` #[must_use = "closures are lazy and do nothing unless called"] #[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")] -pub const trait Fn: FnMut { +pub const trait Fn: [const] FnMut { /// Performs the call operation. #[unstable(feature = "fn_traits", issue = "29625")] extern "rust-call" fn call(&self, args: Args) -> Self::Output; diff --git a/tests/ui/traits/const-traits/call.rs b/tests/ui/traits/const-traits/call.rs index b1080fe78bb5f..65b75cfe5cb24 100644 --- a/tests/ui/traits/const-traits/call.rs +++ b/tests/ui/traits/const-traits/call.rs @@ -6,6 +6,7 @@ pub const _: () = { assert!((const || true)()); //~^ ERROR }: [const] Fn()` is not satisfied + //~| ERROR }: [const] FnMut()` is not satisfied }; fn main() {} diff --git a/tests/ui/traits/const-traits/call.stderr b/tests/ui/traits/const-traits/call.stderr index 8e32cab6dfcfb..b688746e25068 100644 --- a/tests/ui/traits/const-traits/call.stderr +++ b/tests/ui/traits/const-traits/call.stderr @@ -4,6 +4,15 @@ error[E0277]: the trait bound `{closure@$DIR/call.rs:7:14: 7:22}: [const] Fn()` LL | assert!((const || true)()); | ^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0277]: the trait bound `{closure@$DIR/call.rs:7:14: 7:22}: [const] FnMut()` is not satisfied + --> $DIR/call.rs:7:13 + | +LL | assert!((const || true)()); + | ^^^^^^^^^^^^^^^^^ + | +note: required by a bound in `call` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr index dab3f14161fac..90e87c724f54d 100644 --- a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr +++ b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr @@ -4,6 +4,15 @@ error[E0277]: the trait bound `{closure@$DIR/const_closure-const_trait_impl-ice- LL | (const || (()).foo())(); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0277]: the trait bound `{closure@$DIR/const_closure-const_trait_impl-ice-113381.rs:15:6: 15:14}: [const] FnMut()` is not satisfied + --> $DIR/const_closure-const_trait_impl-ice-113381.rs:15:5 + | +LL | (const || (()).foo())(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: required by a bound in `call` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs index d0470fa345848..ee4ff02f4c7c2 100644 --- a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs +++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs @@ -12,4 +12,5 @@ impl Foo for () { fn main() { (const || { (()).foo() })(); //~^ ERROR: }: [const] Fn()` is not satisfied + //~| ERROR: }: [const] FnMut()` is not satisfied } diff --git a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr index dcf65ab694080..69d289537da1d 100644 --- a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr +++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr @@ -4,6 +4,15 @@ error[E0277]: the trait bound `{closure@$DIR/non-const-op-const-closure-non-cons LL | (const || { (()).foo() })(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0277]: the trait bound `{closure@$DIR/non-const-op-const-closure-non-const-outer.rs:13:6: 13:14}: [const] FnMut()` is not satisfied + --> $DIR/non-const-op-const-closure-non-const-outer.rs:13:5 + | +LL | (const || { (()).foo() })(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: required by a bound in `call` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. From 63ca8047bc8717763db6188b3621b72383616519 Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Tue, 18 Nov 2025 03:04:20 -0600 Subject: [PATCH 06/64] add debuginfo subsection --- src/doc/rustc-dev-guide/src/SUMMARY.md | 13 +- .../src/debuginfo/CodeView.pdf | Bin 0 -> 214354 bytes .../src/debuginfo/debugger-internals.md | 14 + .../src/debuginfo/debugger-visualizers.md | 62 ++ .../src/debuginfo/gdb-internals.md | 4 + .../src/debuginfo/gdb-visualizers.md | 9 + .../rustc-dev-guide/src/debuginfo/intro.md | 114 +++ .../src/debuginfo/lldb-internals.md | 205 ++++++ .../src/debuginfo/lldb-visualizers.md | 662 ++++++++++++++++++ .../src/debuginfo/llvm-codegen.md | 12 + .../src/debuginfo/natvis-visualizers.md | 3 + .../src/debuginfo/rust-codegen.md | 183 +++++ .../rustc-dev-guide/src/debuginfo/testing.md | 8 + 13 files changed, 1288 insertions(+), 1 deletion(-) create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/CodeView.pdf create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/gdb-visualizers.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/intro.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/natvis-visualizers.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md create mode 100644 src/doc/rustc-dev-guide/src/debuginfo/testing.md diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index 249140956c09a..bec587f0eec98 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -228,11 +228,22 @@ - [Debugging LLVM](./backend/debugging.md) - [Backend Agnostic Codegen](./backend/backend-agnostic.md) - [Implicit caller location](./backend/implicit-caller-location.md) +- [Debug Info](./debuginfo/intro.md) + - [Rust Codegen](./debuginfo/rust-codegen.md) + - [LLVM Codegen](./debuginfo/llvm-codegen.md) + - [Debugger Interanls](./debuginfo/debugger-internals.md) + - [LLDB Internals](./debuginfo/lldb-internals.md) + - [GDB Internals](./debuginfo/gdb-internals.md) + - [Debugger Visualizers](./debuginfo/debugger-visualizers.md) + - [LLDB - Python Providers](./debuginfo/lldb-visualizers.md) + - [GDB - Python Providers](./debuginfo/gdb-visualizers.md) + - [CDB - Natvis](./debuginfo/natvis-visualizers.md) + - [Testing](./debuginfo/testing.md) + - [(Lecture Notes) Debugging support in the Rust compiler](./debugging-support-in-rustc.md) - [Libraries and metadata](./backend/libs-and-metadata.md) - [Profile-guided optimization](./profile-guided-optimization.md) - [LLVM source-based code coverage](./llvm-coverage-instrumentation.md) - [Sanitizers support](./sanitizers.md) -- [Debugging support in the Rust compiler](./debugging-support-in-rustc.md) --- diff --git a/src/doc/rustc-dev-guide/src/debuginfo/CodeView.pdf b/src/doc/rustc-dev-guide/src/debuginfo/CodeView.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f899d25178458c24bf49cb9ab086761fbdc86f08 GIT binary patch literal 214354 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

Qy!5YFK=h&x?Vf?_B_Sa|t` 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 APXGV_ literal 0 HcmV?d00001 diff --git a/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md new file mode 100644 index 0000000000000..114ce8a998c58 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md @@ -0,0 +1,14 @@ +# Debugger Internals + +It is the debugger's job to convert the debug info into an in-memory representation. Both the +interpretation of the debug info and the in-memory representation are arbitrary; anything will do +so long as meaningful information can be reconstructed while the program is running. The pipeline +from raw debug info to usable types can be quite complicated. + +Once the information is in a workable format, the debugger front-end then must provide a way to +interpret and display the data, a way for users to interact with it, and an API for extensibility. + +Debuggers are vast systems and cannot be covered completely here. This section will provide a brief +overview of the subsystems directly relevant to the Rust debugging experience. + +Microsoft's debugging engine is closed source, so it will not be covered here. \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md new file mode 100644 index 0000000000000..07e3861a500b3 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md @@ -0,0 +1,62 @@ +# Debugger Visualizers + +These are typically the last step before the debugger displays the information, but the results may +be piped through a debug adapter such as an IDE's debugger API. + +The term "Visualizer" is a bit of a misnomer. The real goal isn't just to prettify the output, but +to provide an interface for the user to interact with that is as useful as possible. In many cases +this means reconstructing the original type as closely as possible to its Rust representation, but +not always. + +The visualizer interface allows generating "synthetic children" - fields that don't exist in the +debug info, but can be derived from invariants about the language and the type itself. A simple +example is allowing one to interact with the elements of a `Vec` instead of just it's `*mut u8` +heap pointer, length, and capacity. + +## Performance + +Before tackling the visualizers themselves, it's important to note that these are part of a +performance-sensitive system. Please excuse the break in formality, but: if I have to spend +significant time debugging, I'm annoyed. If I have to *wait on my debugger*, I'm pissed. + +Every millisecond spent in these visualizers is a millisecond longer for the user to see output. +This can be especially painful for large stackframes that contain many/large container types. +Debugger GUI's such as VSCode will request the whole stack frame at once, and this can result in +delays of tens of seconds (or even minutes) before being able to interact with any variables in the +frame. + +There is a tendancy to balk at the idea of optimizing Python code, but it really can have a +substantial impact. Remember, there is no compiler to help keep the code fast. Even simple +transformations are not done for you. It can be difficult to find Python performance tips through +all the noise of people suggesting you don't bother optimizing Python, so here are some things to +keep in mind that are relevant to these scripts: + +* Everything allocates, even `int` +* Use tuples when possible. `list` is effectively `Vec>`, whereas tuples are equivalent +to `Box<[Any]>`. They have one less layer of indirection, don't carry extra capacity and can't +grow/shrink which can be advantageous in many cases. An additional benefit is that Python caches and +recycles the underlying allocations of all tuples up to size 20. +* Regexes are slow and should be avoided when simple string manipulation will do +* Strings are immutable, thus many string operations implictly copy the contents. +* When concatenating large lists of strings, `"".join(iterable_of_strings)` is typically the fastest +way to do it. +* f-strings are generally the fastest way to do small, simple string transformations such as +surrounding a string with parentheses. +* The act of calling a function is somewhat slow (even if the function is completely empty). If the +code section is very hot, consider inlining the function manually. +* Local variable access is significantly faster than global and built-in function access +* Member/method access via the `.` operator is also slow, consider reassigning deeply nested values +to local variables to avoid this cost (e.g. `h = a.b.c.d.e.f.g.h`). +* Accessing inherited methods and fields is about 2x slower than base-class methods and fields. +Avoid inheritance whenever possible. +* Use [`__slots__`](https://wiki.python.org/moin/UsingSlots) wherever possible. `__slots__` is a way +to indicate to Python that your class's fields won't change and speeds up field access by a +noticable amount. This does require you to name your fields in advance and initialize them in +`__init__`, but it's a small price to pay for the benefits. +* Match statements/if..elif..else are not optimized in any way. The conditions are checked in order, +1 by 1. If possible, use an alternative such as dictionary dispatch or a table of values +* Compute lazily when possible +* List comprehensions are typically faster than loops, generator comprehensions are a bit slower +than list comprehensions, but use less memory. You can think of comprehensions as equivalent to +Rust's `iter.map()`. List comprehensions effectively call `collect::>` at the end, whereas +generator comprehensions do not. \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md new file mode 100644 index 0000000000000..95f543c8e94a0 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md @@ -0,0 +1,4 @@ +# (WIP) GDB Internals + +GDB's Rust support lives at `gdb/rust-lang.h` and `gdb/rust-lang.c`. The expression parsing support +can be found in `gdb/rust-exp.h` and `gdb/rust-parse.c` \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/gdb-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/gdb-visualizers.md new file mode 100644 index 0000000000000..4027ef897f28a --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/gdb-visualizers.md @@ -0,0 +1,9 @@ +# (WIP) GDB - Python Providers + +Below are links to relevant parts of the GDB documentation + +* [Overview on writing a pretty printer](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Writing-a-Pretty_002dPrinter.html#Writing-a-Pretty_002dPrinter) +* [Pretty Printer API](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Pretty-Printing-API.html#Pretty-Printing-API) (equivalent to LLDB's `SyntheticProvider`) +* [Value API](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Values-From-Inferior.html#Values-From-Inferior) (equivalent to LLDB's `SBValue`) +* [Type API](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Types-In-Python.html#Types-In-Python) (equivalent to LLDB's `SBType`) +* [Type Printing API](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Type-Printing-API.html#Type-Printing-API) (equivalent to LLDB's `SyntheticProvider.get_type_name`) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/intro.md b/src/doc/rustc-dev-guide/src/debuginfo/intro.md new file mode 100644 index 0000000000000..0f1e59fa65e26 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/intro.md @@ -0,0 +1,114 @@ +# Debug Info + +Debug info is a collection of information generated by the compiler that allows debuggers to +correctly interpret the state of a program while it is running. That includes things like mapping +instruction addresses to lines of code in the source file, and type layout information so that +bytes in memory can be read and displayed in a meaningful way. + +Debug info can be a slightly overloaded term, covering all the layers between Rust MIR, and the +end-user seeing the output of their debugger onscreen. In brief, the stack from beginning to end is +as follows: + +1. Rustc inspects the MIR and communicates the relevant source, symbol, and type information to LLVM +2. LLVM translates this information into a target-specific debug info format during compilation +3. A debugger reads and interprets the debug info, mapping source-lines and allowing the debugee's +variables in memory to be located and read with the correct layout +4. Built-in debugger formatting and styling is applied to variables +5. User-defined scripts are run, formatting and styling the variables further +6. The debugger frontend displays the variable to the user, possibly through the means of additional +API layers (e.g. VSCode extension by way of the +[Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/)) + + +> NOTE: This subsection of the dev guide is perhaps more detailed than necessary. It aims to collect +> a large amount of scattered information into one place and equip the reader with as firm a grasp of +> the entire debug stack as possible. +> +> If you are only interested in working on the visualizer +> scripts, the information in the [debugger-visualizers](./debugger-visualizers.md) and +> [testing](./testing.md) will suffice. If you need to make changes to Rust's debug node generation, +> please see [rust-codegen](./rust-codegen.md). All other sections are supplementary, but can be +> vital to understanding some of the compromises the visualizers or codegen need to make. It can +> also be valuable to know when a problem might be better solved in LLVM or the debugger itself. + +# DWARF + +The is the primary debug info format for `*-gnu` targets. It is typically bundled in with the +binary, but it [can be generated as a separate file](https://gcc.gnu.org/wiki/DebugFission). The +DWARF standard is available [here](https://dwarfstd.org/). + +> NOTE: To inspect DWARF debug info, [gimli](https://crates.io/crates/gimli) can be used +> programatically. If you prefer a GUI, the author recommends [DWEX](https://github.com/sevaa/dwex) + +# PDB/CodeView + +The primary debug info format for `*-msvc` targets. PDB is a proprietary container format created by +Microsoft that, unfortunately, +[has multiple meanings](https://docs.rs/ms-pdb/0.1.10/ms_pdb/taster/enum.Flavor.html). +We are concerned with ordinary PDB files, as Portable PDB is used mainly for .Net applications. PDB +files are separate from the compiled binary and use the `.pdb` extension. + +PDB files contain CodeView objects, equivalent to DWARF's tags. CodeView, the debugger that +consumed CodeView objects, was originally released in 1985. Its original intent was for C debugging, +and was later extended to support Visual C++. There are still minor alterations to the format to +support modern architectures and languages, but many of these changes are undocumented and/or +sparsely used. + +It is important to keep this context in mind when working with CodeView objects. Due to its origins, +the "feature-set" of these objects is very limited, and focused around the core features of C. It +does not have many of the convenience or features of modern DWARF standards. A fair number of +workarounds exist within the debug info stack to compensate for CodeView's shortcomings. + +Due to its proprietary nature, it is very difficult to find information about PDB and CodeView. Many +of the sources were made at vastly different times and contain incomplete or somewhat contradictory +information. As such this page will aim to collect as many sources as possible. + +* [CodeView 1.0 specification](./CodeView.pdf) +* LLVM + * [CodeView Overview](https://llvm.org/docs/SourceLevelDebugging.html#codeview-debug-info-format) + * [PDB Overview and technical details](https://llvm.org/docs/PDB/index.html) +* Microsoft + * [microsoft-pdb](https://github.com/microsoft/microsoft-pdb) - A C/C++ implementation of a PDB + reader. The implementation does not contain the full PDB or CodeView specification, but does + contain enough information for other PDB consumers to be written. At time of writing (Nov 2025), + this repo has been archived for several years. + * [pdb-rs](https://github.com/microsoft/pdb-rs/) - A Rust-based PDB reader and writer based on + other publicly-available information. Does not guarantee stability or spec compliance. Also + contains `pdbtool`, which can dump PDB files (`cargo install pdbtool`) + * [Debug Interface Access SDK](https://learn.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/getting-started-debug-interface-access-sdk). + While it does not document the PDB format directly, details can be gleaned from the interface + itself. + +# Debuggers + +Rust supports 3 major debuggers: GDB, LLDB, and CDB. Each has its own set of requirements, +limitations, and quirks. This unfortunately creates a large surface area to account for. + +> NOTE: CDB is a proprietary debugger created by Microsoft. The underlying engine also powers +>WinDbg, KD, the Microsoft C/C++ extension for VSCode, and part of the Visual Studio Debugger. In +>these docs, it will be referred to as CDB for consistency + +While GDB and LLDB do offer facilities to natively support Rust's value layout, this isn't +completely necessary. Rust currently outputs debug info very similar to that of C++, allowing +debuggers without Rust support to work with a slightly degraded experience. More detail will be +included in later sections, but here is a quick reference for the capabilities of each debugger: + +| Debugger | Debug Info Format | Native Rust support | Expression Style | Visualizer Scripts | +| --- | --- | --- | --- | --- | +| GDB | DWARF | Full | Rust | Python | +| LLDB | DWARF and PDB | Partial | C/C++ | Python | +| CDB | PDB | None | C/C++ | Natvis | + +> IMPORTANT: CDB can be assumed to run only on Windows. No assumptions can be made about the OS +>running GDB or LLDB. + +## Unsupported + +Below, are several unsupported debuggers that are of particular note due to their potential impact +in the future. + +* [Bugstalker](https://github.com/godzie44/BugStalker) is an x86-64 Linux debugger written in Rust, +specifically to debug Rust programs. While promising, it is still in early development. +* [RAD Debugger](https://github.com/EpicGamesExt/raddebugger) is a Windows-only GUI debugger. It has +a custom debug info format that PDB is translated into. The project also includes a linker that can +generate their new debug info format during the linking phase. \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md new file mode 100644 index 0000000000000..301dda9778d50 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md @@ -0,0 +1,205 @@ +# LLDB Internals + +LLDB's debug info processing relies on a set of extensible interfaces largely defined in +[lldb/src/Plugins][lldb_plugins]. These are meant to allow third-party compiler developers to add +language support that is loaded at run-time by LLDB, but at time of writing (Nov 2025) the public +API has not been settled on, so plugins exist either in LLDB itself or in standalone forks of LLDB. + +[lldb_plugins]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins + +Typically, language support will be written as a pipeline of these plugins: `*ASTParser` -> +`TypeSystem` -> `ExpressionParser`/`Language`. + +Here are some existing implementations of LLDB's plugin API: + +* [Apple's fork with support for Swift](https://github.com/swiftlang/llvm-project) +* [CodeLLDB's former fork with support for Rust](https://archive.softwareheritage.org/browse/origin/directory/?branch=refs/heads/codelldb/16.x&origin_url=https://github.com/vadimcn/llvm-project&path=lldb/source/Plugins/TypeSystem/Rust×tamp=2023-09-11T04:55:10Z) +* [A work in progress reimplementation of Rust support](https://github.com/Walnut356/llvm-project/tree/lldbrust/19.x) + +## Rust Support and TypeSystemClang + +As mentioned in the debug info overview, LLDB has partial Rust support. To further clarify, Rust +uses the plugin-pipeline that was built for C/C++ (though it contains some helpers for Rust enum +types), which relies directly on the `clang` compiler's representation of types. This imposes heavy +restrictions on how much we can change when LLDB's output doesn't match what we want. Some +workarounds can help, but at the end of the day Rust's needs are secondary compared to making sure +C and C++ compilation and debugging work correctly. + +LLDB is receptive to adding a `TypeSystemRust`, but it is a massive undertaking. This section serves +to not only document how we currently interact with [`TypeSystemClang`][ts_clang], but also as light +guidance on implementing a `TypeSystemRust` in the future. + +[ts_clang]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/TypeSystem/Clang + +It is worth noting that a `TypeSystem` directly interacting with the target language's compiler is +the intention, but it is not a requirement. One can create all the necessary supporting types within +their plugin implementation. + +> Note: LLDB's documentation, including comments in the source code, is pretty sparse. Trying to +> understand how language support works by reading `TypeSystemClang`'s implementation is somewhat +> difficult due to the added requirement of understanding the `clang` compiler's internals. It is +> recommended to look at the 2 `TypeSystemRust` implementations listed above, as they are written +> "from scratch" without leveraging a compiler's type representation. They are relatively close to +> the minimum necessary to implement language support. + +## DWARF vs PDB + +LLDB is unique in being able to handle both DWARF and PDB debug information. This does come with +some added complexity. To complicate matters further, PDB support is split between `dia`, which +relies on the `msdia140.dll` library distributed with Visual Studio, and `native`, which is written +from scratch using publicly available information about the PDB format. + +> Note: `dia` was the default up to LLDB version 21. `native` is the new default as of +> LLDB 22's release. There are plans to deprecate and completely remove the `dia`-based plugins. As +> such, only `native` parsing will be discussed below. For progress, please see +> [this discourse thread][dia_discourse] and the relevant [tracking issue][dia_tracking]. +> +> `native` can be toggled via the `plugin.symbol-file.pdb.reader` setting added in LLDB 22 or using +> the environment variable `LLDB_USE_NATIVE_PDB_READER=0/1` + +[dia_discourse]: https://discourse.llvm.org/t/rfc-removing-the-dia-pdb-plugin-from-lldb/87827 +[dia_tracking]: https://github.com/llvm/llvm-project/issues/114906 + +## Debug Node Parsing + +The first step is to process the raw debug nodes into something usable. This primarily occurs in +the [`DWARFASTParser`][dwarf_ast] and [`PdbAstBuilder`][pdb_ast] classes. These classes are fed a +deserialized form of the debug info generated from [`SymbolFileDWARF`][sf_dwarf] and +[`SymbolFileNativePDB`][sf_pdb] respectively. The `SymbolFile` implementers make almost no +transformations to the underlying debug info before passing it to the parsers. For both PDB and +DWARF, the debug info is read using LLVM's debug info handlers. + +[dwarf_ast]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/SymbolFile/DWARF +[pdb_ast]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/SymbolFile/NativePDB +[sf_dwarf]: https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +[sf_pdb]: https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h + +The parsers translate the nodes into more convenient formats for LLDB's purposes. For `clang`, these +formats are `clang::QualType`, `clang::Decl`, and `clang::DeclContext`, which are the types `clang` +uses internally when compiling C and C++. Again, using the compiler's representation of types is not a +requirement, but the plugin system was built with it as a possibility. + +> Note: The above types will be referred to language-agnostically as `LangType`, `Decl`, and +`DeclContext` when the specific implementation details of `TypeSystemClang` are not relevant. + +`LangType` represents a type. This includes information such as the name of the type, the size and +alignment, its classification (e.g. struct, primitive, pointer), its qualifiers (e.g. +`const`, `volatile`), template arguments, function argument and return types, etc. [Here][rust_type] +is an example of what a `RustType` might look like. + +[rust_type]: https://github.com/Walnut356/llvm-project/blob/13bcfd502452606d69faeea76aec3a06db554af9/lldb/source/Plugins/TypeSystem/Rust/TypeSystemRust.h#L618 + +`Decl` represents any kind of declaration. It could be a type, a variable, a static field of a +struct, the value that a static or const is initialized with, etc. + +`DeclContext` more or less represents a scope. `DeclContext`s typically contain `Decl`s and other +`DeclContexts`, though the relationship isn't that straight forward. For example, a function can be +both a `Decl` (because function signatures are types), **and** a `DeclContext` (because functions +contain variable declarations, nested functions declarations, etc.). + +The translation process can be quite verbose, but is usually straightforward. Much of the work here +is dependant on the exact information needed to fill out `LangType`, `Decl`, and `DeclContext`. + +Once a node is translated, a pointer to it is type-erased (`void*`) and wrapped in `CompilerType`, +`CompilerDecl`, or `CompilerDeclContext`. These wrappers associate the them with the `TypeSystem` +that owns them. Methods on these objects delegates to the `TypeSystem`, which casts the `void*` back +to the appropriate `LangType*`/`Decl*`/`DeclContext*` and operates on the internals. In Rust terms, +the relationship looks something like this: + +```Rust +struct CompilerType { + inner_type: *mut c_void, + type_system: Arc, +} + +impl CompilerType { + pub fn get_byte_size(&self) -> usize { + self.type_system.get_byte_size(self.lang_type) + } + +} + +... + +impl TypeSystem for TypeSystemLang { + pub fn get_byte_size(lang_type: *mut c_void) -> usize { + let lang_type = lang_type as *mut LangType; + + // Operate on the internals of the LangType to + // determine its size + ... + } +} +``` + +## Type Systems + +The [`TypeSystem` interface][ts_interface] has 3 major purposes: + +[ts_interface]: https://github.com/llvm/llvm-project/blob/main/lldb/include/lldb/Symbol/TypeSystem.h#L69 + +1. Act as the "sole authority" of a language's types. This allows the type system to be added to +LLDB's "pool" of type systems. When an executable is loaded, the target language is determined, and +the pool is queried to find a `TypeSystem` that claims it can handle the language. One can also use +the `TypeSystem` to retrieve the backing `SymbolFile`, search for types, and synthesize basic types +that might not exist in the debug info (e.g. primitives, arrays-of-`T`, pointers-to-`T`). +2. Manage the lifetimes of the `LangType`, `Decl`, and `DeclContext` objects +3. Customize the "defaults" of how those types appear and how they can be interacted with. + +The first two functions are pretty straightforward so we will focus on the third. + +Many of the functions in the `TypeSystem` interface will look familiar if you have worked with the +visualizer scripts. These functions underpin `SBType` the `SBValue` functions with matching names. +For example, `TypeSystem::GetFormat` returns the default format for the type if no custom formatter +has been applied to it. + +Of particular note are `GetIndexOfChildWithName` and `GetNumChildren`. The `TypeSystem` versions of +these functions operate on a *type*, not a value like the `SBValue` versions. The values returned +from the `TypeSystem` functions dictate what parts of the struct can be interacted with *at all* by +the rest of LLDB. If a field is ommitted, that field effectively no longer exists to LLDB. + +Additionally, since they do not work with objects, there is no underlying memory to inspect or +interpret. Essentially, this means these functions do not have the same purpose as their equivalent +`SyntheticProvider` functions. There is no way to determine how many elements a `Vec` has or what +address those elements live at. It is also not possible to determine the value of the discriminant +of a sum-type. + +Ideally, the `TypeSystem` should expose types as they appear in the debug info with as few +alterations as possible. LLDB's synthetics and frontend can handle making the type pretty. If some +piece of information is useless, the Rust compiler should be altered to not output that debug info +in the first place. + +## Expression Parsing + +The `TypeSystem` is typically written to have a counterpart that can handle expression parsing. It +requires implementing a few extra functions in the `TypeSystem` interface. The bulk of the +expression parsing code should live in [lldb/source/Plugins/ExpressionParser][expr]. + +[expr]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/ExpressionParser + +There isn't too much of note about the parser. It requires implementing a simple interpreter that +can handle (possibly simplified) Rust syntax. They operate on `lldb::ValueObject`s, which are the +objects that underpin `SBValue`. + +## Language + +The [`Language` plugins][lang_plugin] are the C++ equivalent to the Python visualizer scripts. They +operate on `SBValue` objects for the same purpose: creating synthetic children and pretty-printing. +The [CPlusPlusLanguage's implementations][cpp_lang] for the LibCxx types are great resources to +learn how visualizers should be written. + +[lang_plugin]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/Language +[cpp_lang]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/Language/CPlusPlus + +These plugins can access LLDB's private internals (including the underlying `TypeSystem`), so +synthetic/summary providers written as a `Language` plugin can provide higher quality output than +their python equivalent. + +While debug node parsing, type systems, and expression parsing are all closely tied to eachother, +the `Language` plugin is encapsulated more and thus can be written "standalone" for any language +that an existing type system supports. Due to the lower barrier of entry, a `RustLanguage` plugin +may be a good stepping stone towards full language support in LLDB. + +## Visualizers + +WIP \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md new file mode 100644 index 0000000000000..c7bcc25029ef0 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md @@ -0,0 +1,662 @@ +# LLDB - Python Providers + +> NOTE: LLDB's C++<->Python FFI expects a version of python designated at the time LLDB was +>compiled. LLDB is careful to correspond this version to the minimum in typical Linux and MacOs +>distributions, but on Windows there is no easy solution. If you recieve an import error regarding +>`_lldb` not existing, a mismatched Python version is likely the cause. +> +> LLDB is considering solutions this issue. For updates, see +>[this discussion][minimal_python_install] and [this github issue][issue_167001] + +[minimal_python_install]: https://discourse.llvm.org/t/a-minimal-python-install-for-lldb/88658 +[issue_167001]: https://github.com/llvm/llvm-project/issues/167001 + +> NOTE: Currently (Nov 2025), LLDB's minimum supported Python version is 3.8 with plans to update it to +>3.9 or 3.10 depending on several outside factors. Scripts should ideally be written with only the +>features available in the minimum supported Python version. Please see [this discussion][mrpv] for +>more info. + +[mrpv]: https://discourse.llvm.org/t/rfc-upgrading-llvm-s-minimum-required-python-version/88605/ + +> NOTE: The path to LLDB's python package can be located via the CLI command `lldb -P` + +LLDB provides 3 mechanisms for customizing output: + +* Formats +* Synthetic providers +* Summary providers + +## Formats + +The official documentation is [here](https://lldb.llvm.org/use/variable.html#type-format). In short, +formats allow one to set the default print format for primitive types (e.g. print `25u8` as decimal +`25`, hex `0x19`, or binary `00011001`). + +Rust will almost always need to override `unsigned char`, `signed char`, `char`, `u8`, and `i8`, to +(unsigned) decimal format. + +## Synthetic Providers + +The official documentation is [here](https://lldb.llvm.org/use/variable.html#synthetic-children), +but some information is vague, outdated, or entirely missing. + +Nearly all interaction the user has with variables will be through LLDB's +[`SBValue` objects][sbvalue] which are used both in the Python API, and internally via LLDB's +plugins and CLI. + +[sbvalue]: https://lldb.llvm.org/python_api/lldb.SBValue.html + +A Synthetic Provider is a Python class, written with a specific interface, that is associated with +one or more Rust types. The Synthetic Provider wraps `SBValue` objects and LLDB will call our +class's functions when inspecting the variable. + +The wrapped value is still an `SBValue`, but when calling e.g. `SBValue.GetChildAtIndex`, it will +internally call `SyntheticProvider.get_child_at_index`. You can check if a value has a synthetic +provider via `SBValue.IsSynthetic()`, and which synthetic it is via `SBValue.GetTypeSynthetic()`. If +you want to interact with the underlying non-synthetic value, you can call +`SBValue.GetNonSyntheticValue()`. + + +The expected interface is as follows: + +```python +class SyntheticProvider: + def __init__(self, valobj: SBValue, _lldb_internal): ... + + # optional + def update(self) -> bool: ... + + # optional + def has_children(self) -> bool: ... + + # optional + def num_children(self, max_children: int) -> int: ... + + def get_child_index(self, name: str) -> int: ... + + def get_child_at_index(self, index: int) -> SBValue: ... + + # optional + def get_type_name(self) -> str: ... + + # optional + def get_value(self) -> SBValue: ... +``` + +Below are explanations of the methods, their quirks, and how they should generally be used. If a +method overrides an `SBValue` method, that method will be listed. + +### `__init__` + +This function is called once per object, and must store the `valobj` in the python class so that it +is accessible elsewhere. Very little else should be done here. + +### (optional) `update` + +This function is called prior to LLDB interacting with a variable, but after `__init__`. LLDB tracks +whether `update` has already been called. If it has been, and if it is not possible for the variable +to have changed (e.g. inspecting the same variable a second time without stepping), it will omit the +call to `update`. + +This function has 2 purposes: + +* Store/update any information that may have changed since the last time `update` was run +* Inform LLDB if there were changes to the children such that it should flush the child cache. + +Typical operations include storing the heap pointer, length, capacity, and element type of a `Vec`, +determining an enum variable's variant, or checking which slots of a `HashMap` are occupied. + +The bool returned from this function is somewhat complicated, see: +[`update` caching](#update-caching) below for more info. When in doubt, return `False`/`None`. +Currently (Nov 2025), none of the visualizers return `True`, but that may change as the debug info +test suite is improved. + +#### `update` caching + +LLDB attempts to cache values when possible, including child values. This cache is effectively the +number of child objects, and the addresses of the underlying debugee memory that the child object +represents. By returning `True`, you indicate to LLDB that the number of children and the addresses +of those children have not changed since the last time `update` was run, meaning it can reuse the +cached children. + +**Returning `True` in the wrong circumstances will result in the debugger outputting incorrect +information**. + +Returning `False` indicates that there have been changes, the cache will be flushed, and the +children will be fetched from scratch. It is the safer option if you are unsure. + +The only relationship that matters is parent-to-child. Grandchildren depend on the `update` function +of their direct parent, not that of the grandparent. + +It is important to view the child cache as pointers-to-memory. For example, if a slice's `data_ptr` +value and `length` have not changed, returning `True` is appropriate. Even if the slice is mutable +and elements of it are overwritten (e.g. `slice[0] = 15`), because the child cache consists of +*pointers*, they will reflect the new data at that memory location. + +Conversely, if `data_ptr` has changed, that means it is pointing to a new location in memory, the +child pointers are invalid, and the cache must be flushed. If the `length` has changed, we need to +flush the cache to reflect the new number of children. If `length` has changed but `data_ptr` has +not, it is possible to store the old children in the `SyntheticProvider` itself (e.g. +`list[SBValue]`) and dole those out rather than generating them from scratch, only creating new +children if they do not already exist in the `SyntheticProvider`'s list. + +For further clarification, see [this discussion](https://discourse.llvm.org/t/when-is-it-safe-to-cache-syntheticprovider-update/88608) + +> NOTE: when testing the caching behavior, do not rely on LLDB's heuristic to persist variables when +> stepping. Instead, store the variable in a python object (e.g. `v = lldb.frame.var("var_name")`), +> step forward, and then inspect the stored variable. + +### (optional) `has_children` + +> Overrides `SBValue.MightHaveChildren` + +This is a shortcut used by LLDB to check if the value has children *at all*, without doing +potentially expensive computations to determine how many children there are (e.g. linked list). +Often, this will be a one-liner of `return True`/`return False` or +`return self.valobj.MightHaveChildren()`. + +### (optional) `num_children` + +> Overrides `SBValue.GetNumChildren` + +Returns the total number of children that LLDB should try to access when printing the type. This +number **does not** need to match to total number of synthetic children. + +The `max_children` argument can be returned if calculating the number of children can be expensive +(e.g. linked list). If this is not a consideration, `max_children` can be omitted from the function +signature. + +Additionally, fields can be intentionally "hidden" from LLDB while still being accessible to the +user. For example, one might want a `vec![1, 2, 3]` to display only its elements, but still have the +`len` and `capacity` values accessible on request. By returning `3` from `num_children`, one can +restrict LLDB to only displaying `[1, 2, 3]`, while users can still directly access `v.len` and +`v.capacity`. See: [Example Provider: Vec\](#example-provider-vect) to see an implementation of +this. + +### `get_child_index` + +> Overrides `SBValue.GetIndexOfChildWithName` +> +> Affects `SBValue.GetChildMemberWithName` + +Given a name, returns the index that the child should be accessed at. It is expected that the return +value of this function is passed directly to `get_child_at_index`. As with `num_children`, the +values returned here *can* be arbitrary, so long as they are properly coordinated with +`get_child_at_index`. + +One special value is `$$dereference$$`. Accounting for this pseudo-field will allow LLDB to use the +`SBValue` returned from `get_child_at_index` as the result of a dereference via LLDB's expression +parser (e.g. `*val` and `val->field`) + +### `get_child_at_index` + +> Overrides `SBValue.GetChildAtIndex` + +Given an index, returns a child `SBValue`. Often these are generated via +`SBValue.CreateValueFromAddress`, but less commonly `SBValue.CreateChildAtOffset`, +`SBValue.CreateValueFromExpression`, and `SBValue.CreateValueFromData`. These functions can be a +little finicky, so you may need to fiddle with them to get the output you want. + +In some cases, `SBValue.Clone` is appropriate. It creates a new child that is an exact copy of an +existing child, but with a new name. This is useful for cases like tuples, which have field names of +the style `__0`, `__1`, ... when we would prefer they were named `0`, `1`, ... + +Small alterations can be made to the resulting child before it is returned. This is useful for +`&str`/`String`, where we would prefer if the children were displayed as +`lldb.eFormatBytesWithASCII` rather than just as a decimal value. + +### (optional) `get_type_name` + +> Overrides `SBValue.GetDisplayTypeName` + +Overrides the displayed name of a type. For a synthetic `SBValue` whose type name is overridden, the +original type name can still be retrieved via `SBValue.GetTypeName()` and +`SBValue.GetType().GetName()` + +This can be helpful in shortening the name of common standard library types (e.g. +`std::collections::hash::map::HashMap` -> `HashMap`), or +in normalizing MSVC type names (e.g. `ref$` -> `&str`). + +The string manipulation can be a little tricky, especially on MSVC where we cannot conveniently +access the generic parameters of the type. + +### (optional) `get_value` + +> Overrides `SBValue.GetValue()`, `SBValue.GetValueAsUnsigned()`, `SBValue.GetValueAsSigned()`, +>`SBValue.GetValueAsAddress()`, + +The `SBValue` returned is expected to be a primitive type or pointer, and is treated as the value of +the variable in expressions. + +> IMPORTANT: The `SBValue` returned **must be stored in the `SyntheticProvider`**. There is +>currently (Nov 2025) a bug where if the `SBValue` is acquired within `get_value` and not stored +>anywhere, Python will segfault when LLDB attempts to access the value. + +## Summary Providers + +Summary providers are python functions of the following form: + +```python +def SummaryProvider(valobj: SBValue, _lldb_internal) -> str: ... +``` + +Where the returned string is passed verbatim to the user. If the returned value isn't a string, it +is naively convered to a string (e.g. `return None` prints `"None"`, not an empty string). + +If the `SBValue` passed in is of a type that has a Synthetic Provider, `valobj.IsSynthetic()` will +return `True`, and the synthetic's corresponding functions will be used. If this is undesirable, the +original value can be retrieved via `valobj.GetNonSyntheticValue()`. This can be helpful in cases +like `String`, where individually calling `GetChildAtIndex` in a loop is much slower than accessing +the heap pointer, reading the whole byte array directly from the debugee's memory, and using +Python's `bytes.decode()`. + +### Instance Summaries + +Regular `SummaryProvider` functions take an opaque `SBValue`. That `SBValue` will reflect the type's +`SyntheticProvider` if one exists, but we cannot access the `SyntheticProvider` instance itself, or +any of its internal implementation details. This is deterimental in cases where we need some of +those internal details to help complete the summary. Currently (Nov 2025), in the synthetic we just +run the non-synthetic value through the synthetic provider +(`synth = SyntheticProvider(valobj.GetNonSyntheticValue(), _dict)`), but this is obviously +suboptimal and there are plans to use the method outlined below. + +Instead, we can leverage the Python module's state to allow for instance summaries. Prior art for +this technique exists in the [old CodeLLDB Rust visualizer scripts](https://github.com/vadimcn/codelldb/blob/cf9574977b80e29c6de2c44d12f1071a53a54caf/formatters/rust.py#L110). + +In short: every Synthetic Provider's `__init__` function stores a unique ID and a weak reference to +`self` in a global dictionary. The Synthetic Provider class also implements a `get_summary` +function. The type's `SummaryProvider` is a function that looks up the unique ID in this dictionary, +then calls a `get_summary` on the instance it retrieves. + +```python +import weakref + +SYNTH_BY_ID = weakref.WeakValueDictionary() + +class SyntheticProvider: + valobj: SBValue + + # slots requires opting-in to __weakref__ + __slots__ = ("valobj", "__weakref__") + + def __init__(valobj: SBValue, _dict): + SYNTH_BY_ID[valobj.GetID()] = self + self.valobj = valobj + + def get_summary(self) -> str: + ... + +def InstanceSummaryProvider(valobj: SBValue, _dict) -> str: + # GetNonSyntheticValue should never fail as InstanceSummaryProvider implies an instance of a + # `SyntheticProvider`. No non-synthetic types should ever have this summary assigned to them + # We use GetNonSyntheticValue because the synthetic vaobj has its own unique ID + return SYNTH_BY_ID[valobj.GetNonSyntheticValue().GetID()].get_summary() +``` + +For example, one might use this for the Enum synthetic provider. The summary would like to access +the variant name, but there isn't a convenient way to reflect this via the type name or child-values +of the synthetic. By implementing an instance summary, we can retrieve the variant name via +`self.variant.GetTypeName()` and some string manipulation. + +# Writing Visualizer Scripts + +> IMPORTANT: Unlike GDB and CDB, LLDB can debug executables with either DWARF or PDB debug info. +>Visualizers must be written to account for both formats whenever possible. See: +>[rust-codegen](./rust-codegen.md#dwarf-vs-pdb) for an overview of the differences + +Scripts are injected into LLDB via the CLI command `command script import .py`. Once +injected, classes and functions can be added to the synthetic/summary pool with `type synthetic add` +and `type summary add` respectively. The summaries and synthetics can be associated with a +"category", which is typically named after the language the providers are intended for. The category +we use will be called `Rust`. + +> TIP: all LLDB commands can be prefixed with `help` (e.g. `help type synthetic add`) for a brief +description, list of arguments, and examples. + +Currently (Nov 2025) we use `command source ...`, which executes a series of CLI commands from the +file [`lldb_commands`](https://github.com/rust-lang/rust/blob/main/src/etc/lldb_commands) to add +providers. This file is somewhat unwieldy, and will soon be supplanted by the Python API equivalent +outlined below. + +## `__lldb_init_module` + +This is an optional function of the form: + +```python +def __lldb_init_module(debugger: SBDebugger, _lldb_internal) -> None: ... +``` + +This function is called at the end of `command script import ...`, but before control returns back +to the CLI. It allows the script to initialize its own state. + +Crucially, it is passed a reference to the debugger itself. This allows us to create the `Rust` +category and add providers to it. It can also allow us to conditionally change which providers we +use depending on what version of LLDB the script detects. This is vital for backwards compatibility +once we begin using recognizer functions, as recognizers were added in lldb 19.0. + +## Visualizer Resolution + +The order that visualizers resolve in is listed [here][formatters_101]. In short: + +[formatters_101]: https://lldb.llvm.org/use/variable.html#finding-formatters-101 + +* If there is an exact match (non-regex name, recognizer function, or type already matched to +provider), use that +* If the object is a pointer/reference, try to use the dereferenced type's formatter +* If the object is a typedef, check the underlying type for a formatter +* If none of the above work, iterate through the regex type matchers + +Within each of those steps, **iteration is done backwards** to allow new commands to "override" old +commands. This is important for cases like `Box` vs `Box`, were we want a specialized +synthetic for the former, but a more generalized synthetic for the latter. + +## Minutiae + +LLDB's API is very powerful, but there are some "gotchas" and unintuitive behavior, some of which +will be outlined below. The python implementation can be viewed at the path returned by the CLI +command `lldb -P` in `lldb\__init__.py`. In addition to the +[examples in the lldb repo][synth_examples], there are also [C++ visualizers][plugin_cpp] that can +be used as a reference (e.g. [LibCxxVector, the equivalent to `Vec`][cxx_vector]). While C++'s +visualizers are written in C++ and have access to LLDB's internals, the API and general practices +are very similar. + +[synth_examples]:https://github.com/llvm/llvm-project/tree/main/lldb/examples/synthetic +[plugin_cpp]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/Language/CPlusPlus +[cxx_vector]: https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp + +### `SBValue` + +* Pointer/reference `SBValue`s will effectively "auto-deref" in some cases, acting as if the +children of the pointed-to-object are its own children. +* The non-function fields are typically [`property()`][property] fields that point directly to the +function anyway (e.g. `SBValue.type = property(GetType, None)`). Accessing through these shorthands +is a bit slower to access than just calling the function directly, so they should be avoided. Some +of the properties return special objects with special properties (e.g. `SBValue.member` returns an +object that acts like `dict[str, SBValue]` to access children). Internally, many of these special +objects just allocate a new class instance and call the function on the `SBValue` anyway, resulting +in additional performance loss (e.g. `SBValue.member` internally just implements `__getitem__` which +is the one-liner `return self.valobj.GetChildMemberWithName(name)`) +* `SBValue.GetID` returns a unique `int` for each value for the duration of the debug session. +Synthetic `SBValue`'s have a different ID than their underlying `SBValue`. The underlying ID can be +retrieved via `SBValue.GetNonSyntheticValue().GetID()`. +* When manually calculating an address, `SBValue.GetValueAsAddress` should be preferred over +`SBValue.GetValueAsUnsigned` due to [target-specific behavior][get_address] +* Getting a string representation of an `SBValue` can be tricky because `GetSummary` requires a +summary provider and `GetValue` requires the type be representable by a primitive. In almost all +cases where neither of those conditions are met, the type is a user defined struct that can be +passed through `StructSummaryProvider`. + +[property]: https://docs.python.org/3/library/functions.html#property +[get_address]: https://lldb.llvm.org/python_api/lldb.SBValue.html#lldb.SBValue.GetValueAsAddress + +### `SBType` + +* "Aggregate type" means a non-primitive struct/class/union +* "Template" is equivalent to "Generic" +* Types can be looked up by their name via `SBTarget.FindFirstType(type_name)`. `SBTarget` can be +acquired via `SBValue.GetTarget` +* `SBType.template_args` returns `None` instead of an empty list if the type has no generics +* It is sometimes necessary to transform a type into the type you want via functions like +`SBType.GetArrayType` and `SBType.GetPointerType`. These functions cannot fail. They ask the +underlying LLDB `TypeSystem` plugin for the type, bypassing the debug info completely. Even if the +type does not exist in the debug info at all, these functions can create the appropriate type. +* `SBType.GetCanonicalType` is effectively `SBType.GetTypedefedType` + `SBType.GetUnqualifiedType`. +Unlike `SBType.GetTypedefedType`, it will always return a valid `SBType` regardless of whether or +not the original `SBType` is a typedef. +* `SBType.GetStaticFieldWithName` was added in LLDB 18. Unfortunately, backwards compatibility isn't +always possible since the static fields are otherwise completely inaccessible. + + +# Example Provider: `Vec` + +## SyntheticProvider + +We start with the typical prelude, using `__slots__` since we have known fields. In addition to the +object itself, we also need to store the type of the elements because `Vec`'s heap pointer is a +`*mut u8`, not a `*mut T`. Rust is a statically typed language, so the type of `T` will never +change. That means we can store it during initialization. The heap pointer, length, and capacity +*can* change though, and thus are default initialized here. + +```python +import lldb + +class VecSyntheticProvider: + valobj: SBValue + data_ptr: SBValue + len: int + cap: int + element_type: SBType + + __slots__ = ( + "valobj", + "data_ptr", + "len", + "cap", + "element_type", + "__weakref__", + ) + + def __init__(valobj: SBValue, _dict) -> None: + self.valobj = valobj + # invalid type is a better default than `None` + self.element_type = SBType() + + # special handling to account for DWARF/PDB differences + if (arg := valobj.GetType().GetTemplateArgumentType(0)): + self.element_type = arg + else: + arg_name = next(get_template_args(valobj.GetTypeName())) + self.element_type = resolve_msvc_template_arg(arg_name, valobj.GetTarget()) +``` + +For the implementation of `get_template_args` and `resolve_msvc_template_arg`, please see: +[`lldb_providers.py`](https://github.com/rust-lang/rust/blob/main/src/etc/lldb_providers.py#L136). + +Next, the update function. We check if the pointer or length have changed. We can ommit checking the +capacity, as the number of children will remain the same unless `len` changes. If changing the +capacity resulted in a reallocation, `data_ptr`'s address would be different. + +If `data_ptr` and `length` haven't changed, we can take advantage of LLDB's caching and return +early. If they have changed, we store the new values and tell LLDB to flush the cache. + +```python +def update(self): + ptr = self.valobj.GetChildMemberWithName("data_ptr") + len = self.valobj.GetChildMemberWithName("length").GetValueAsUnsigned() + + if ( + self.data_ptr.GetValueAsAddress() == ptr.GetValueAsAddress() + and self.len == len + ): + # Our child address offsets and child count are still valid + # so we can reuse cached children + return True + + self.data_ptr = ptr + self.len = len + + return False +``` + +`has_children` and `num_children` are both straightforward: + +```python +def has_children(self) -> bool: + return True + +def num_children(self) -> int: + return self.len +``` + +When accessing elements, we expect values of the format `[0]`, `[1]`, etc. to mimic indexing. +Additionally, we still want the user to be able to quickly access the length and capacity, as they +can be very useful when debugging. We assign these values `u32::MAX - 1` and `u32::MAX - 2` +respectively, as we can almost surely guarantee that they will not overlap with element values. Note +that we can account for both the full and shorthand `capacity` name. + +```python + def get_child_index(self, name: str) -> int: + index = name.lstrip("[").rstrip("]") + if index.isdigit(): + return int(index) + if name == "len": + return lldb.UINT32_MAX - 1 + if name == "cap" or name == "capacity": + return lldb.UINT32_MAX - 2 + + return -1 +``` + +We now have to properly coordinate `get_child_at_index` so that the elements, length, and capacity +are all accessible. + +```python +def get_child_at_index(self, index: int) -> SBValue: + if index == UINT32_MAX - 1: + return self.valobj.GetChildMemberWithName("len") + if index == UINT32_MAX - 2: + return ( + self.valobj.GetChildMemberWithName("buf") + .GetChildMemberWithName("inner") + .GetChildMemberWithName("cap") + .GetChildAtIndex(0) + .Clone("capacity") + ) + addr = self.data_ptr.GetValueAsAddress() + addr += index * self.element_type.GetByteSize() + return self.valobj.CreateValueFromAddress(f"[{index}]", addr, self.element_type) +``` + +For the type's display name, we can strip the path qualifier. User defined types named +`Vec` will end up fully qualified, so there shouldn't be any ambiguity. We can also remove the +allocator generic, as it's very very rarely useful. We use `get_template_args` instead of +`self.element_type.GetName()` for 3 reasons: + +1. If we fail to resolve the element type for any reason, `self.valobj`'s type name can still let +the user know what the real type of the element is +2. Type names are not subject to the limitations of DWARF and PDB nodes, so the template type in +the name will reflect things like `*const`/`*mut` and `&`/`&mut`. +3. We do not currently (Nov 2025) normalize MSVC type names, but once we do, we will need to work with the +string-names of types anyway. It's also much easier to cache a string-to-string conversion compared +to an `SBType`-to-string conversion. + +```python +def get_type_name(self) -> str: + return f"Vec<{next(get_template_args(self.valobj))}>" +``` + +There isn't an appropriate primitive value with which to represent a `Vec`, so we simply ommit +the `get_value` function. + +## SummaryProvider + +The summary provider is very simple thanks to our synthetic provider. The only real hiccup is that +`GetSummary` only returns a value if the object's type has a `SummaryProvider`. If it doesn't, it +will return an empty string which is not ideal. In a full set of visualizer scripts, we can ensure +that every type that doesn't have a `GetSummary()` or a `GetValue()` is a struct, and then delegate +to a generic `StructSummaryProvider`. For this demonstration, I will gloss over that detail. + +```python +def VecSummaryProvider(valobj: SBValue, _lldb_internal) -> str: + children = [] + for i in range(valobj.GetNumChildren()): + child = valobj.GetChildAtIndex(i) + summary = child.GetSummary() + if summary is None: + summary = child.GetValue() + if summary is None: + summary = "{...}" + + children.append(summary) + + return f"vec![{", ".join(children)}]" +``` + +## Enabling the providers + +Assume this synthetic is imported into `lldb_lookup.py` + +With CLI commands: + +```txt +type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -x "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust +``` + +With `__lldb_init_module`: + +```python +def __lldb_init_module(debugger: SBDebugger, _dict: LLDBOpaque): + # Ensure the category exists and is enabled + rust_cat = debugger.GetCategory("Rust") + + if not rust_cat.IsValid(): + rust_cat = debugger.CreateCategory("Rust") + + rust_cat.SetEnabled(True) + + # Register Vec providers + vec_regex = r"^(alloc::([a-z_]+::)+)Vec<.+>$" + sb_name = lldb.SBTypeNameSpecifier(vec_regex, is_regex=True) + + sb_synth = lldb.SBTypeSynthetic.CreateWithClassName("lldb_lookup.VecSyntheticProvider") + sb_synth.SetOptions(lldb.eTypeOptionCascade) + + sb_summary = lldb.SBTypeSummary.CreateWithFunctionName("lldb_lookup.VecSummaryProvider") + sb_summary.SetOptions(lldb.eTypeOptionCascade) + + rust_cat.AddTypeSynthetic(sb_name, sb_synth) + rust_cat.AddSummary(sb_name, sb_summary) +``` + +## Output + +Without providers: + +```text +(lldb) v vec_v +(alloc::vec::Vec) vec_v = { + buf = { + inner = { + ptr = { + pointer = (pointer = "\n") + _marker = {} + } + cap = (__0 = 5) + alloc = {} + } + _marker = {} + } + len = 5 +} +(lldb) v vec_v[0] +error: :1:6: subscripted value is not an array or pointer + 1 | vec_v[0] + | ^ +``` + +With providers (`v ` prints the summary and then a list of all children): + +```text +(lldb) v vec_v +(Vec) vec_v = vec![10, 20, 30, 40, 50] { + [0] = 10 + [1] = 20 + [2] = 30 + [3] = 40 + [4] = 50 +} +(lldb) v vec_v[0] +(int) vec_v[0] = 10 +``` + +We can also confirm that the "hidden" length and capacity are still accessible: + +```text +(lldb) v vec_v.len +(unsigned long long) vec_v.len = 5 +(lldb) v vec_v.capacity +(unsigned long long) vec_v.capacity = 5 +(lldb) v vec_v.cap +(unsigned long long) vec_v.cap = 5 +``` \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md new file mode 100644 index 0000000000000..cc052b6b965f1 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md @@ -0,0 +1,12 @@ +# (WIP) LLVM Codegen + +When Rust calls an LLVM `DIBuilder` function, LLVM translates the given information to a +["debug record"][dbg_record] that is format-agnostic. These records can be inspected in the LLVM-IR. + +[dbg_record]: https://llvm.org/docs/SourceLevelDebugging.html#debug-records + +It is important to note that tags within the debug records are **always stored as DWARF tags**. If +the target calls for PDB debug info, during codegen the debug records will then be passed through +[a module that translates the DWARF tags to their CodeView counterparts][cv]. + +[cv]:https://github.com/llvm/llvm-project/blob/main/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/natvis-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/natvis-visualizers.md new file mode 100644 index 0000000000000..653e7d5d65555 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/natvis-visualizers.md @@ -0,0 +1,3 @@ +# (WIP) CDB - Natvis + +Official documentation for Natvis can be found [here](https://learn.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects) and [here](https://code.visualstudio.com/docs/cpp/natvis) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md new file mode 100644 index 0000000000000..6d5dfe08cb150 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md @@ -0,0 +1,183 @@ +# Rust Codegen + +The first phase in debug info generation requires Rust to inspect the MIR of the program and +communicate it to LLVM. This is primarily done in [`rustc_codegen_llvm/debuginfo`][llvm_di], though +some type-name processing exists in [`rustc_codegen_ssa/debuginfo`][ssa_di]. Rust communicates to +LLVM via the `DIBuilder` API - a thin wrapper around LLVM's internals that exists in +[rustc_llvm][rustc_llvm]. + +[llvm_di]: https://github.com/rust-lang/rust/tree/main/compiler/rustc_codegen_llvm/src/debuginfo +[ssa_di]: https://github.com/rust-lang/rust/tree/main/compiler/rustc_codegen_ssa/src/debuginfo +[rustc_llvm]: https://github.com/rust-lang/rust/tree/main/compiler/rustc_llvm + +# Type Information + +Type information typically consists of the type name, size, alignment, as well as things like +fields, generic parameters, and storage modifiers if they are relevant. Much of this work happens in +[rustc_codegen_llvm/src/debuginfo/metadata][di_metadata]. + +[di_metadata]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs + +It is important to keep in mind that the goal is not necessarily "represent types exactly how they +appear in Rust", rather it is to represent them in a way that allows debuggers to most accurately +reconstruct the data during debugging. This distinction is vital to understanding the core work that +occurs on this layer; many changes made here will be for the purpose of working around debugger +limitations when no other option will work. + +## Quirks + +Rust's generated DI nodes "pretend" to be C/C++ for both CDB and LLDB's sake. This can result in +some unintuitive and non-idiomatic debug info. + +### Pointers and Reference + +Wide pointers/references/`Box` are treated as a struct with 2 fields: `data_ptr` and `length`. + +All non-wide pointers, references, and `Box` pointers are output as pointer nodes, and no +distinction is made between `mut` and non-`mut`. Several attempts have been made to rectify this, +but unfortunately there is not a straightforward solution. Using the `reference` DI nodes of the +respective formats has pitfalls. There is a semantic difference between C++ references and Rust +references that is unreconcilable. + +>From [cppreference](https://en.cppreference.com/w/cpp/language/reference.html): +> +>References are not objects; **they do not necessarily occupy storage**, although the compiler may +>allocate storage if it is necessary to implement the desired semantics (e.g. a non-static data +>member of reference type usually increases the size of the class by the amount necessary to store +>a memory address). +> +>Because references are not objects, **there are no arrays of references, no pointers to references, and no references to references** + +The current proposed solution is to simply [typedef the pointer nodes][issue_144394]. + +[issue_144394]: https://github.com/rust-lang/rust/pull/144394 + +Using the `const` qualifier to denote non-`mut` poses potential issues due to LLDB's internal +optimizations. In short, LLDB attempts to cache the child-values of variables (e.g. struct fields, +array elements) when stepping through code. A heuristic is used to determine which values are safely +cache-able, and `const` is part of that heuristic. Research has not been done into how this would +interact with things like Rust's interrior mutability constructs. + +### DWARF vs PDB + +While most of the type information is fairly straight forward, one notable issue is the debug info +format of the target. Each format has different semantics and limitations, as such they require +slightly different debug info in some cases. This is gated by calls to +[`cpp_like_debuginfo`][cpp_like]. + +[cpp_like]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs#L813 + +### Naming + +Rust attempts to communicate type names as accurately as possible, but debuggers and debug info +formats do not always respect that. + +Due to limitations in MSVC's expression parser, the following name transformations are made for PDB +debug info: + +| Rust name | MSVC name | +| --- | --- | +| `&str`/`&mut str` | `ref$`/`ref_mut$` | +| `&[T]`/`&mut [T]` | `ref$ >`/`ref_mut$ >`* | +| `[T; N]` | `array$` | +| `RustEnum` | `enum2$` | +| `(T1, T2)` | `tuple$`| +| `*const T` | `ptr_const$` | +| `*mut T` | `ptr_mut$` | +| `usize` | `size_t`** | +| `isize` | `ptrdiff_t`** | +| `uN` | `unsigned __intN`** | +| `iN` | `__intN`** | +| `f32` | `float`** | +| `f64` | `double`** | +| `f128` | `fp128`** | + +> \* MSVC's expression parser will treat `>>` as a right shift. It is necessary to separate +>consecutive `>`'s with a space (`> >`) in type names. +> +> ** While these type names are generated as part of the debug info node (which is then wrapped in +>a typedef node with the Rust name), once the LLVM-IR node is converted to a CodeView node, the type +>name information is lost. This is because CodeView has special shorthand nodes for primitive types, +>and those shorthand nodes to not have a "name" field. + +### Generics + +Rust outputs generic *type* information (`T` in `ArrayVec`), but not generic *value* +information (`N` in `ArrayVec`). + +CodeView does not have a leaf node for generics/C++ templates, so all generic information is lost +when generating PDB debug info. There are workarounds that allow the debugger to retrieve the +generic arguments via the type name, but it is fragile solution at best. Efforts are being made to +contact Microsoft to correct this deficiency, and/or to use one of the unused CodeView node types as +a suitable equivalent. + +### Type aliases + +Rust outputs typedef nodes in several cases to help account for debugger limitiations, but it does +not currently output nodes for [type aliases in the source code][type_aliases]. + +[type_aliases]: https://doc.rust-lang.org/reference/items/type-aliases.html + +### Enums + +Enum DI nodes are generated in [rustc_codegen_llvm/src/debuginfo/metadata/enums][di_metadata_enums] + +[di_metadata_enums]: https://github.com/rust-lang/rust/tree/main/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums + +#### DWARF + +DWARF has a dedicated node for discriminated unions: `DW_TAG_variant`. It is a container that +references `DW_TAG_variant_part` nodes that may or may not contain a discriminant value. The +hierarchy looks as follows: + +```txt +DW_TAG_structure_type (top-level type for the coroutine) + DW_TAG_variant_part (variant part) + DW_AT_discr (reference to discriminant DW_TAG_member) + DW_TAG_member (discriminant member) + DW_TAG_variant (variant 1) + DW_TAG_variant (variant 2) + DW_TAG_variant (variant 3) + DW_TAG_structure_type (type of variant 1) + DW_TAG_structure_type (type of variant 2) + DW_TAG_structure_type (type of variant 3) +``` + +#### PDB +PDB does not have a dedicated node, so it generates the C equivalent of a discriminated union: + +```c +union enum2$ { + enum VariantNames { + First, + Second + }; + struct Variant0 { + struct First { + // fields + }; + static const enum2$::VariantNames NAME; + static const unsigned long DISCR_EXACT; + enum2$::Variant0::First value; + }; + struct Variant1 { + struct Second { + // fields + }; + static enum2$::VariantNames NAME; + static unsigned long DISCR_EXACT; + enum2$::Variant1::Second value; + }; + enum2$::Variant0 variant0; + enum2$::Variant1 variant1; + unsigned long tag; +} +``` + +An important note is that due to limitations in LLDB, the `DISCR_*` value generated is always a +`u64` even if the value is not `#[repr(u64)]`. This is largely a non-issue for LLDB because the +`DISCR_*` value and the `tag` are read into `uint64_t` values regardless of their type. + +# Source Information + +TODO \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/testing.md b/src/doc/rustc-dev-guide/src/debuginfo/testing.md new file mode 100644 index 0000000000000..f58050875e1a0 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/debuginfo/testing.md @@ -0,0 +1,8 @@ +# (WIP) Testing + +The debug info test suite is undergoing a substantial rewrite. This section will be filled out as +the rewrite makes progress. + +Please see [this tracking issue][148483] for more information. + +[148483]: https://github.com/rust-lang/rust/issues/148483 \ No newline at end of file From aca2dc0c064e0d7c8f83f3f4df8e3238724165f1 Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Sun, 23 Nov 2025 01:52:14 -0600 Subject: [PATCH 07/64] fix typos and footnotes --- src/doc/rustc-dev-guide/src/SUMMARY.md | 2 +- .../src/debuginfo/lldb-visualizers.md | 2 +- .../src/debuginfo/rust-codegen.md | 32 +++++++++---------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index bec587f0eec98..c85e37e134dd2 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -231,7 +231,7 @@ - [Debug Info](./debuginfo/intro.md) - [Rust Codegen](./debuginfo/rust-codegen.md) - [LLVM Codegen](./debuginfo/llvm-codegen.md) - - [Debugger Interanls](./debuginfo/debugger-internals.md) + - [Debugger Internals](./debuginfo/debugger-internals.md) - [LLDB Internals](./debuginfo/lldb-internals.md) - [GDB Internals](./debuginfo/gdb-internals.md) - [Debugger Visualizers](./debuginfo/debugger-visualizers.md) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md index c7bcc25029ef0..bb27c0e97369f 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md @@ -1,7 +1,7 @@ # LLDB - Python Providers > NOTE: LLDB's C++<->Python FFI expects a version of python designated at the time LLDB was ->compiled. LLDB is careful to correspond this version to the minimum in typical Linux and MacOs +>compiled. LLDB is careful to correspond this version to the minimum in typical Linux and macOS >distributions, but on Windows there is no easy solution. If you recieve an import error regarding >`_lldb` not existing, a mismatched Python version is likely the cause. > diff --git a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md index 6d5dfe08cb150..00a03e3657f1b 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md @@ -78,27 +78,27 @@ debug info: | Rust name | MSVC name | | --- | --- | | `&str`/`&mut str` | `ref$`/`ref_mut$` | -| `&[T]`/`&mut [T]` | `ref$ >`/`ref_mut$ >`* | +| `&[T]`/`&mut [T]` | `ref$ >`/`ref_mut$ >`[^1] | | `[T; N]` | `array$` | | `RustEnum` | `enum2$` | | `(T1, T2)` | `tuple$`| | `*const T` | `ptr_const$` | | `*mut T` | `ptr_mut$` | -| `usize` | `size_t`** | -| `isize` | `ptrdiff_t`** | -| `uN` | `unsigned __intN`** | -| `iN` | `__intN`** | -| `f32` | `float`** | -| `f64` | `double`** | -| `f128` | `fp128`** | - -> \* MSVC's expression parser will treat `>>` as a right shift. It is necessary to separate ->consecutive `>`'s with a space (`> >`) in type names. -> -> ** While these type names are generated as part of the debug info node (which is then wrapped in ->a typedef node with the Rust name), once the LLVM-IR node is converted to a CodeView node, the type ->name information is lost. This is because CodeView has special shorthand nodes for primitive types, ->and those shorthand nodes to not have a "name" field. +| `usize` | `size_t`[^2] | +| `isize` | `ptrdiff_t`[^2] | +| `uN` | `unsigned __intN`[^2] | +| `iN` | `__intN`[^2] | +| `f32` | `float`[^2] | +| `f64` | `double`[^2] | +| `f128` | `fp128`[^2] | + +[^1]: MSVC's expression parser will treat `>>` as a right shift. It is necessary to separate +consecutive `>`'s with a space (`> >`) in type names. + +[^2]: While these type names are generated as part of the debug info node (which is then wrapped in +a typedef node with the Rust name), once the LLVM-IR node is converted to a CodeView node, the type +name information is lost. This is because CodeView has special shorthand nodes for primitive types, +and those shorthand nodes to not have a "name" field. ### Generics From 5d997ffc644fce728756e17af8c3f8e9989bb0da Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Sun, 23 Nov 2025 01:54:38 -0600 Subject: [PATCH 08/64] Add section for `#![debugger_visualizer]` --- .../src/debuginfo/debugger-visualizers.md | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md index 07e3861a500b3..831acbd2f8f8e 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md @@ -13,6 +13,55 @@ debug info, but can be derived from invariants about the language and the type i example is allowing one to interact with the elements of a `Vec` instead of just it's `*mut u8` heap pointer, length, and capacity. +## `rust-lldb`, `rust-gdb`, and `rust-windbg.cmd` + +These support scripts are distributed with Rust toolchains. They locate the appropriate debugger and +the toolchain's visualizer scripts, then launch the debugger with the appropriate arguments to load +the visualizer scripts before a debugee is launched/attached to. + +## `#![debugger_visualizer]` + +[This attribute][dbg_vis_attr] allows Rust library authors to include pretty printers for their +types within the library itself. These pretty printers are of the same format as typical +visualizers, but are embedded directly into the compiled binary. These scripts are loaded +automatically by the debugger, allowing a seamless experience for users. This attribute currently +works for GDB and natvis scripts. + +[dbg_vis_attr]: https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute + +GDB python scripts are embedded in the `.debug_gdb_scripts` section of the binary. More information +can be found [here](https://sourceware.org/gdb/current/onlinedocs/gdb.html/dotdebug_005fgdb_005fscripts-section.html). Rustc accomplishes this in [`rustc_codegen_llvm/src/debuginfo/gdb.rs`][gdb_rs] + +[gdb_rs]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs + +Natvis files can be embedded in the PDB debug info using the [`/NATVIS` linker option][linker_opt], +and have the [highest priority][priority] when a type is resolving which visualizer to use. The +files specified by the attribute are collected into +[`CrateInfo::natvis_debugger_visualizers`][natvis] which are then added as linker arguments in +[`rustc_codegen_ssa/src/back/linker.rs`][linker_rs] + +[linker_opt]: https://learn.microsoft.com/en-us/cpp/build/reference/natvis-add-natvis-to-pdb?view=msvc-170 +[priority]: https://learn.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects?view=visualstudio#BKMK_natvis_location +[natvis]: https://github.com/rust-lang/rust/blob/e0e204f3e97ad5f79524b9c259dc38df606ed82c/compiler/rustc_codegen_ssa/src/lib.rs#L212 +[linker_rs]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_ssa/src/back/linker.rs#L1106 + +LLDB is not currently supported, but there are a few methods that could potentially allow support in +the future. Officially, the intended method is via a [formatter bytecode][bytecode]. This was +created to offer a comparable experience to GDB's, but without the safety concerns associated with +embedding an entire python script. The opcodes are limited, but it works with `SBValue` and `SBType` +in roughly the same way as python visualizer scripts. Implementing this would require writing some +sort of DSL/mini compiler. + +[bytecode]: https://lldb.llvm.org/resources/formatterbytecode.html + +Alternatively, it might be possible to copy GDB's strategy entirely: create a bespoke section in the +binary and embed a python script in it. LLDB will not load it automatically, but the python API does +allow one to access the [raw sections of the debug info][SBSection]. With this, it may be possible +to extract the python script from our bespoke section and then load it in during the startup of +Rust's visualizer scripts. + +[SBSection]: https://lldb.llvm.org/python_api/lldb.SBSection.html#sbsection + ## Performance Before tackling the visualizers themselves, it's important to note that these are part of a From c15b8f6c33db4594f783a4f0e55766c19aa85af2 Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Sun, 23 Nov 2025 20:33:40 -0600 Subject: [PATCH 09/64] Add additional LLDB plugin example --- src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md | 3 +++ src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md index 301dda9778d50..e104f1d245327 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md @@ -15,6 +15,9 @@ Here are some existing implementations of LLDB's plugin API: * [Apple's fork with support for Swift](https://github.com/swiftlang/llvm-project) * [CodeLLDB's former fork with support for Rust](https://archive.softwareheritage.org/browse/origin/directory/?branch=refs/heads/codelldb/16.x&origin_url=https://github.com/vadimcn/llvm-project&path=lldb/source/Plugins/TypeSystem/Rust×tamp=2023-09-11T04:55:10Z) * [A work in progress reimplementation of Rust support](https://github.com/Walnut356/llvm-project/tree/lldbrust/19.x) +* [A Rust expression parser plugin](https://github.com/tromey/lldb/tree/a0fc10ce0dacb3038b7302fff9f6cb8cb34b37c6/source/Plugins/ExpressionParser/Rust). +This was written before the `TypeSystem` API was created. Due to the freeform nature of expression parsing, the +underlyng lexing, parsing, function calling, etc. should still offer valuable insights. ## Rust Support and TypeSystemClang diff --git a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md index 00a03e3657f1b..73fa68d36076a 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md @@ -56,7 +56,7 @@ Using the `const` qualifier to denote non-`mut` poses potential issues due to LL optimizations. In short, LLDB attempts to cache the child-values of variables (e.g. struct fields, array elements) when stepping through code. A heuristic is used to determine which values are safely cache-able, and `const` is part of that heuristic. Research has not been done into how this would -interact with things like Rust's interrior mutability constructs. +interact with things like Rust's interior mutability constructs. ### DWARF vs PDB From 0f5b29a4d46ca2a89f1979242f7abfa104b28c50 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 1 Dec 2025 13:29:33 +0100 Subject: [PATCH 10/64] add invariant --- src/doc/rustc-dev-guide/src/solve/invariants.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/solve/invariants.md b/src/doc/rustc-dev-guide/src/solve/invariants.md index 8ec15f339e51b..bdf974099f2f0 100644 --- a/src/doc/rustc-dev-guide/src/solve/invariants.md +++ b/src/doc/rustc-dev-guide/src/solve/invariants.md @@ -116,6 +116,12 @@ We do however break this invariant in a few cases, some of which are due to bugs - the builtin trait object trait implementation can overlap with a user-defined impl: [#57893](https://github.com/rust-lang/rust/issues/57893) +### Goals with can be proven in a non-empty environment also hold during monomorphization ✅ + +If a goal can be proven in a generic environment, the goal should still hold after instantiating +it with fully concrete types and no where-clauses in scope. + +This is assumed by codegen whicih ICEs when encountering non-overflow ambiguity. This invariant is currently broken by specialization ([#147507](https://github.com/rust-lang/rust/issues/147507)) and by marker traits ([#149502](https://github.com/rust-lang/rust/issues/149502)). #### The type system is complete during the implicit negative overlap check in coherence ✅ From b3381908ba29b10fc84b52ab31d32acaed36bb71 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 1 Dec 2025 21:38:23 +0100 Subject: [PATCH 11/64] Update src/solve/invariants.md Co-authored-by: Tshepang Mbambo --- src/doc/rustc-dev-guide/src/solve/invariants.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/solve/invariants.md b/src/doc/rustc-dev-guide/src/solve/invariants.md index bdf974099f2f0..d6e360cbc6820 100644 --- a/src/doc/rustc-dev-guide/src/solve/invariants.md +++ b/src/doc/rustc-dev-guide/src/solve/invariants.md @@ -121,7 +121,7 @@ We do however break this invariant in a few cases, some of which are due to bugs If a goal can be proven in a generic environment, the goal should still hold after instantiating it with fully concrete types and no where-clauses in scope. -This is assumed by codegen whicih ICEs when encountering non-overflow ambiguity. This invariant is currently broken by specialization ([#147507](https://github.com/rust-lang/rust/issues/147507)) and by marker traits ([#149502](https://github.com/rust-lang/rust/issues/149502)). +This is assumed by codegen which ICEs when encountering non-overflow ambiguity. This invariant is currently broken by specialization ([#147507](https://github.com/rust-lang/rust/issues/147507)) and by marker traits ([#149502](https://github.com/rust-lang/rust/issues/149502)). #### The type system is complete during the implicit negative overlap check in coherence ✅ From bbb2f274bb153e6b1f9ec02f5d3cde783bb9fff8 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Tue, 2 Dec 2025 17:06:10 +0900 Subject: [PATCH 12/64] Mention sharing the solver with rust-analyzer --- src/doc/rustc-dev-guide/src/SUMMARY.md | 1 + .../sharing-crates-with-rust-analyzer.md | 192 ++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 src/doc/rustc-dev-guide/src/solve/sharing-crates-with-rust-analyzer.md diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index c136d37160c53..1490db8809196 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -185,6 +185,7 @@ - [Proof trees](./solve/proof-trees.md) - [Opaque types](./solve/opaque-types.md) - [Significant changes and quirks](./solve/significant-changes.md) + - [Sharing the trait solver with rust-analyzer](./solve/sharing-crates-with-rust-analyzer.md) - [`Unsize` and `CoerceUnsized` traits](./traits/unsize.md) - [Variance](./variance.md) - [Coherence checking](./coherence.md) diff --git a/src/doc/rustc-dev-guide/src/solve/sharing-crates-with-rust-analyzer.md b/src/doc/rustc-dev-guide/src/solve/sharing-crates-with-rust-analyzer.md new file mode 100644 index 0000000000000..bf0d4fe3a11b7 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/solve/sharing-crates-with-rust-analyzer.md @@ -0,0 +1,192 @@ +# Sharing the trait solver with rust-analyzer + +rust-analyzer can be viewed as a compiler frontend: it performs tasks similar to the parts of rustc +that run before code generation, such as parsing, lexing, AST construction and lowering, HIR +lowering, and even limited MIR building and const evaluation. + +However, because rust-analyzer is primarily a language server, its architecture differs in several +important ways from that of rustc. +Despite these differences, a substantial portion of its responsibilities—most notably type +inference and trait solving—overlap with the compiler. + +To avoid duplication and to maintain consistency between the two implementations, rust-analyzer +reuses several crates from rustc, relying on shared abstractions wherever possible. + +## Shared Crates + +Currently, rust-analyzer depends on several `rustc_*` crates from the compiler: + +- `rustc_abi` +- `rustc_ast_ir` +- `rustc_index` +- `rustc_lexer` +- `rustc_next_trait_solver` +- `rustc_parse_format` +- `rustc_pattern_analysis` +- `rustc_type_ir` + +Since these crates are not published on `crates.io` as part of the compiler's normal distribution +process, rust-analyzer maintains its own publishing pipeline. +It uses the [rustc-auto-publish script][rustc-auto-publish] to publish these crates to `crates.io` +with the prefix `ra-ap-rustc_*` +(for example: https://crates.io/crates/ra-ap-rustc_next_trait_solver). +rust-analyzer then depends on these re-published crates in its own build. + +For trait solving specifically, the primary shared crates are `rustc_type_ir` and +`rustc_next_trait_solver`, which provide the core IR and solver logic used by both compiler +frontends. + +## The Abstraction Layer + +Because rust-analyzer is a language server, it must handle frequently changing source code and +partially invalid or incomplete source codes. +This requires an infrastructure quite different from rustc's, especially in the layers between +the source code and the HIR—for example, `Ty` and its backing interner. + +To bridge these differences, the compiler provides `rustc_type_ir` as an abstraction layer shared +between rustc and rust-analyzer. +This crate defines the fundamental interfaces used to represent types, predicates, and the context +required by the trait solver. +Both rustc and rust-analyzer implement these traits for their own concrete type representations, +and `rustc_next_trait_solver` is written to be generic over these abstractions. + +In addition to these interfaces, `rustc_type_ir` also includes several non-trivial components built +on top of the abstraction layer—such as elaboration logic and the search graph machinery used by the +solver. + +## Design Concepts + +`rustc_next_trait_solver` is intended to depend only on the abstract interfaces defined in +`rustc_type_ir`. +To support this, the type-system traits in `rustc_type_ir` must expose every interface the solver +requires—for example, [creating a new inference type variable][ir new_infer] +([rustc][rustc new_infer], [rust-analyzer][r-a new_infer]). +For items that do not need compiler-specific representations, `rustc_type_ir` defines them directly +as structs or enums parameterized over these traits—for example, [`TraitRef`][ir tr]. + +The following are some notable items from the `rustc_type_ir` crate. + +### `trait Interner` + +The central trait in this design is [`Interner`][ir interner], which specifies all +implementation-specific details for both rustc and rust-analyzer. +Among its essential responsibilities: + +- it **specifies** the concrete types used by the implementation via its + [associated types][ir interner assocs]; these form the backbone of how each compiler frontend + instantiates the shared IR, +- it provides the context required by the solver (e.g., querying [lang items][ir require_lang_item], + enumerating [all blanket impls for a trait][ir for_each_blanket_impl]); +- and it must implement [`IrPrint`][ir irprint] for formatting and tracing. + In practice, these `IrPrint` impls simply route to existing formatting logic inside rustc or + rust-analyzer. + +In rustc, [`TyCtxt` implements `Interner`][rustc interner impl]: it exposes the rustc's query +methods, and the required `Interner` trait methods are implemented by invoking those queries. +In rust-analyzer, the implementing type is named [`DbInterner`][r-a interner impl] (as it performs +most interning through the [salsa] database), and most of its methods are backed by salsa queries +rather than rustc queries. + +### `mod inherent` + +Another notable item in `rustc_type_ir` is the [`inherent` module][ir inherent]. +This module provides *forward definitions* of inherent methods—expressed as traits—corresponding to +methods that exist on compiler-specific types such as `Ty` or `GenericArg`. +These definitions allow the generic crates (such as `rustc_next_trait_solver`) to call methods that +are implemented differently in rustc and rust-analyzer. + +Code in generic crates should import these definitions with: + +```rust +use inherent::*; +``` + +These forward definitions **must never be used inside the concrete implementations themselves**. +Crates that implement the traits from `mod inherent` should call the actual inherent methods on +their concrete types once those types are nameable. + +You can find rustc’s implementations of these traits in the +[rustc_middle::ty::inherent][rustc inherent impl] module. +For rust-analyzer, the corresponding implementations are located across several modules under +`hir_ty::next_solver`, such as [hir_ty::next_solver::region][r-a inherent impl]. + +### `trait InferCtxtLike` and `trait SolverDelegate` + +These two traits correspond to the role of [`InferCtxt`][rustc inferctxt] in rustc. + +[`InferCtxtLike`][ir inferctxtlike] must be defined in `rustc_infer` due to coherence +constraints(orphan rules). +As a result, it cannot provide functionality that lives in `rustc_trait_selection`. +Instead, behavior that depends on trait-solving logic is abstracted into a separate trait, +[`SolverDelegate`][ir solverdelegate]. +Its implementator in rustc is [simply a newtype struct over `InferCtxt`][rustc solverdelegate impl] +in `rustc_trait_selection`. + +(In rust-analyzer, it is also implemented for a newtype wrapper over its own +[`InferCtxt`][r-a inferctxtlike impl], primarily to mirror rustc’s structure, although this is not +strictly necessary because all solver-related logic already resides in the `hir-ty` crate.) + +In the long term, the ideal design is to move all of the logic currently expressed through +`SolverDelegate` into `rustc_next_trait_solver`, with any required core operations added directly to +`InferCtxtLike`. +This would allow more of the solver’s behavior to live entirely inside the shared solver crate. + +### `rustc_type_ir::search_graph::{Cx, Delegate}` + +The abstraction traits [`Cx`][ir searchgraph cx impl] and [`Delegate`][ir searchgraph delegate impl] +are already implemented within `rustc_next_trait_solver` itself. +Therefore, users of the shared crates—both rustc and rust-analyzer—do not need to provide their own +implementations. + +These traits exist primarily to support fuzzing of the search graph independently of the full trait +solver. +This infrastructure is used by the external fuzzing project: +. + +## Long-term plans for supporting rust-analyzer + +In general, we aim to support rust-analyzer just as well as rustc in these shared crates—provided +doing so does not substantially harm rustc's performance or maintainability. +(e.g., [#145377][pr 145377], [#146111][pr 146111], [#146182][pr 146182] and [#147723][pr 147723]) + +Shared crates that require nightly-only features must guard such code behind a `nightly` feature +flag, since rust-analyzer is built with the stable toolchain. + +Looking forward, we plan to uplift more shared logic into `rustc_type_ir`. +There are still duplicated implementations between rustc and rust-analyzer—such as `ObligationCtxt` +([rustc][rustc oblctxt], [rust-analyzer][r-a oblctxt]) and type coercion logic +([rustc][rustc coerce], [rust-analyzer][r-a coerce])—that we would like to unify over time. + +[rustc-auto-publish]: https://github.com/rust-analyzer/rustc-auto-publish +[ir new_infer]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/inherent/trait.Ty.html#tymethod.new_infer +[rustc new_infer]: https://github.com/rust-lang/rust/blob/63b1db05801271e400954e41b8600a3cf1482363/compiler/rustc_middle/src/ty/sty.rs#L413-L420 +[r-a new_infer]: https://github.com/rust-lang/rust-analyzer/blob/34f47d9298c478c12c6c4c0348771d1b05706e09/crates/hir-ty/src/next_solver/ty.rs#L59-L92 +[ir tr]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/struct.TraitRef.html +[ir interner]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/trait.Interner.html +[ir interner assocs]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/trait.Interner.html#required-associated-types +[ir require_lang_item]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/trait.Interner.html#tymethod.require_lang_item +[ir for_each_blanket_impl]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/trait.Interner.html#tymethod.for_each_blanket_impl +[ir irprint]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/ir_print/trait.IrPrint.html +[rustc interner impl]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#impl-Interner-for-TyCtxt%3C'tcx%3E +[r-a interner impl]: https://github.com/rust-lang/rust-analyzer/blob/a50c1ccc9cf3dab1afdc857a965a9992fbad7a53/crates/hir-ty/src/next_solver/interner.rs +[salsa]: https://github.com/salsa-rs/salsa +[ir inherent]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/inherent/index.html +[rustc inherent impl]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_middle/ty/inherent/index.html +[r-a inherent impl]: https://github.com/rust-lang/rust-analyzer/blob/a50c1ccc9cf3dab1afdc857a965a9992fbad7a53/crates/hir-ty/src/next_solver/region.rs +[ir inferctxtlike]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_type_ir/trait.InferCtxtLike.html +[rustc inferctxt]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html +[rustc inferctxtlike impl]: https://doc.rust-lang.org/1.91.1/nightly-rustc/src/rustc_infer/infer/context.rs.html#14-332 +[r-a inferctxtlike impl]: https://github.com/rust-lang/rust-analyzer/blob/a50c1ccc9cf3dab1afdc857a965a9992fbad7a53/crates/hir-ty/src/next_solver/infer/context.rs +[ir solverdelegate]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_next_trait_solver/delegate/trait.SolverDelegate.html +[rustc solverdelegate impl]: https://doc.rust-lang.org/1.91.1/nightly-rustc/rustc_trait_selection/solve/delegate/struct.SolverDelegate.html +[r-a solverdelegate impl]: https://github.com/rust-lang/rust-analyzer/blob/a50c1ccc9cf3dab1afdc857a965a9992fbad7a53/crates/hir-ty/src/next_solver/solver.rs#L27-L330 +[ir searchgraph cx impl]: https://doc.rust-lang.org/1.91.1/nightly-rustc/src/rustc_type_ir/interner.rs.html#550-575 +[ir searchgraph delegate impl]: https://doc.rust-lang.org/1.91.1/nightly-rustc/src/rustc_next_trait_solver/solve/search_graph.rs.html#20-123 +[pr 145377]: https://github.com/rust-lang/rust/pull/145377 +[pr 146111]: https://github.com/rust-lang/rust/pull/146111 +[pr 146182]: https://github.com/rust-lang/rust/pull/146182 +[pr 147723]: https://github.com/rust-lang/rust/pull/147723 +[rustc oblctxt]: https://github.com/rust-lang/rust/blob/63b1db05801271e400954e41b8600a3cf1482363/compiler/rustc_trait_selection/src/traits/engine.rs#L48-L386 +[r-a oblctxt]: https://github.com/rust-lang/rust-analyzer/blob/34f47d9298c478c12c6c4c0348771d1b05706e09/crates/hir-ty/src/next_solver/obligation_ctxt.rs +[rustc coerce]: https://github.com/rust-lang/rust/blob/63b1db05801271e400954e41b8600a3cf1482363/compiler/rustc_hir_typeck/src/coercion.rs +[r-a coerce]: https://github.com/rust-lang/rust-analyzer/blob/34f47d9298c478c12c6c4c0348771d1b05706e09/crates/hir-ty/src/infer/coerce.rs \ No newline at end of file From ac2a424fb36a2c894c08e19ae28e6c30d01ec70e Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 8 Dec 2025 19:03:21 +0100 Subject: [PATCH 13/64] Remove `[no-mentions]` handler in our triagebot config https://github.blog/changelog/2025-11-07-removing-notifications-for-mentions-in-commit-messages/ --- src/doc/rustc-dev-guide/triagebot.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/triagebot.toml b/src/doc/rustc-dev-guide/triagebot.toml index 4a88523915209..fbfe742341480 100644 --- a/src/doc/rustc-dev-guide/triagebot.toml +++ b/src/doc/rustc-dev-guide/triagebot.toml @@ -53,10 +53,6 @@ allow-unauthenticated = [ # Documentation at: https://forge.rust-lang.org/triagebot/note.html [note] -# Prevents mentions in commits to avoid users being spammed -# Documentation at: https://forge.rust-lang.org/triagebot/no-mentions.html -[no-mentions] - # Canonicalize issue numbers to avoid closing the wrong issue # when commits are included in subtrees, as well as warning links in commits. # Documentation at: https://forge.rust-lang.org/triagebot/issue-links.html From d1d1181789b2139d2c685ac69913858023f7aaa6 Mon Sep 17 00:00:00 2001 From: xiaolinny Date: Tue, 9 Dec 2025 17:07:18 +0800 Subject: [PATCH 14/64] chore: fix some minor issues in the comments Signed-off-by: xiaolinny --- library/std/src/io/buffered/tests.rs | 2 +- .../src/rustdoc-internals/rustdoc-json-test-suite.md | 10 +++++----- .../repeat-expr/copy-check-deferred-after-fallback.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs index 068dca819775a..fc77b02a8e828 100644 --- a/library/std/src/io/buffered/tests.rs +++ b/library/std/src/io/buffered/tests.rs @@ -172,7 +172,7 @@ fn test_buffered_reader_stream_position_panic() { // cause internal buffer to be filled but read only partially let mut buffer = [0, 0]; assert!(reader.read_exact(&mut buffer).is_ok()); - // rewinding the internal reader will cause buffer to loose sync + // rewinding the internal reader will cause buffer to lose sync let inner = reader.get_mut(); assert!(inner.seek(SeekFrom::Start(0)).is_ok()); // overflow when subtracting the remaining buffer size from current position diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md index e19a8204ab41a..5781a12ca44c1 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md @@ -4,7 +4,7 @@ This page is specifically about the test suite named `rustdoc-json`, which tests For other test suites used for testing rustdoc, see [§Rustdoc test suites](../tests/compiletest.md#rustdoc-test-suites). Tests are run with compiletest, and have access to the usual set of [directives](../tests/directives.md). -Frequenly used directives here are: +Frequently used directives here are: - [`//@ aux-build`][aux-build] to have dependencies. - `//@ edition: 2021` (or some other edition). @@ -23,8 +23,8 @@ Also, talk about how it works ## jsondocck -[jsondocck] processes direcives given in comments, to assert that the values in the output are expected. -It's alot like [htmldocck](./rustdoc-test-suite.md) in that way. +[jsondocck] processes directives given in comments, to assert that the values in the output are expected. +It's a lot like [htmldocck](./rustdoc-test-suite.md) in that way. It uses [JSONPath] as a query language, which takes a path, and returns a *list* of values that that path is said to match to. @@ -48,7 +48,7 @@ These are defined in [`directive.rs`]. Values can be either JSON values, or variables. - JSON values are JSON literals, e.g. `true`, `"string"`, `{"key": "value"}`. - These often need to be quoted using `'`, to be processed as 1 value. See [§Argument spliting](#argument-spliting) + These often need to be quoted using `'`, to be processed as 1 value. See [§Argument splitting](#argument-splitting) - Variables can be used to store the value in one path, and use it in later queries. They are set with the `//@ set = ` directive, and accessed with `$` @@ -57,7 +57,7 @@ Values can be either JSON values, or variables. //@ is $.some.other.path $foo ``` -### Argument spliting +### Argument splitting Arguments to directives are split using the [shlex] crate, which implements POSIX shell escaping. This is because both `` and `` arguments to [directives](#directives) frequently have both diff --git a/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs index a6bd5b299c96a..02cd9f4a3b296 100644 --- a/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs +++ b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs @@ -1,6 +1,6 @@ // Test when deferring repeat expr copy checks to end of typechecking whether they're // checked before integer fallback occurs or not. We accomplish this by having a repeat -// count that can only be inferred after integer fallback has occured. This test will +// count that can only be inferred after integer fallback has occurred. This test will // pass if we were to check repeat exprs after integer fallback. use std::marker::PhantomData; From 92f21a806d3ce3eac22d7b46903064ade92faf93 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Mon, 8 Dec 2025 05:52:18 +0900 Subject: [PATCH 15/64] moved tests --- .../issue-46472.rs => borrowck/return-ref-to-temporary.rs} | 0 .../return-ref-to-temporary.stderr} | 0 .../issue-19499.rs => closures/closure-upvar-trait-caching.rs} | 0 .../ui/{issues/issue-24779.rs => closures/nested-closure-call.rs} | 0 .../repeated-debug-opt-flags.rs} | 0 tests/ui/{issues/issue-23253.rs => enum/enum-variant-no-field.rs} | 0 .../issue-23253.stderr => enum/enum-variant-no-field.stderr} | 0 .../issue-50442.rs => enum/enum-with-uninhabited-variant.rs} | 0 tests/ui/{issues/issue-18110.rs => expr/return-in-block-tuple.rs} | 0 .../{issues/issue-19398.rs => extern/extern-rust-trait-method.rs} | 0 .../ui/{issues/issue-3656.rs => ffi/ffi-struct-size-alignment.rs} | 0 tests/ui/{issues/issue-11382.rs => fmt/println-float.rs} | 0 .../ui/{issues/issue-43205.rs => indexing/ref-array-indexing.rs} | 0 .../trait-method-lifetime-suggestion.rs} | 0 .../trait-method-lifetime-suggestion.stderr} | 0 ...{lint-missing-doc-crate.rs => lint-missing-doc-crate-flags.rs} | 0 ...ssing-doc-crate.stderr => lint-missing-doc-crate-flags.stderr} | 0 .../issue-10656.rs => lint/lint-missing-docs-crate-attr.rs} | 0 .../lint-missing-docs-crate-attr.stderr} | 0 .../{issues/issue-19734.rs => macros/undefined-macro-in-impl.rs} | 0 .../issue-19734.stderr => macros/undefined-macro-in-impl.stderr} | 0 .../issue-4968.rs => match/match-const-tuple-type-mismatch.rs} | 0 .../match-const-tuple-type-mismatch.stderr} | 0 .../ui/{issues/issue-18464.rs => match/match-range-char-const.rs} | 0 tests/ui/{issues/issue-17933.rs => match/match-static-pattern.rs} | 0 .../issue-17933.stderr => match/match-static-pattern.stderr} | 0 tests/ui/{issues/issue-16783.rs => moves/array-copy-move.rs} | 0 tests/ui/{issues/issue-17373.rs => never_type/never-deref.rs} | 0 .../{issues/issue-17373.stderr => never_type/never-deref.stderr} | 0 .../issue-22644.rs => parser/cast-angle-bracket-precedence.rs} | 0 .../cast-angle-bracket-precedence.stderr} | 0 .../issue-27033.rs => pattern/match-at-pattern-shadows-name.rs} | 0 .../match-at-pattern-shadows-name.stderr} | 0 .../module-used-as-struct-constructor.rs} | 0 .../module-used-as-struct-constructor.stderr} | 0 .../issue-34047.rs => shadowed/match-binding-shadows-const.rs} | 0 .../match-binding-shadows-const.stderr} | 0 .../{issues/issue-17450.rs => statics/static-mut-unsafe-init.rs} | 0 .../issue-21291.rs => threads-sendsync/thread-join-unwrap.rs} | 0 .../issue-20162.rs => trait-bounds/sort-missing-ord-bound.rs} | 0 .../sort-missing-ord-bound.stderr} | 0 .../solver-cycles/assoc-equality-cycle.rs} | 0 .../solver-cycles/assoc-equality-cycle.stderr} | 0 .../issue-20772.rs => traits/solver-cycles/self-item-cycle.rs} | 0 .../solver-cycles/self-item-cycle.stderr} | 0 .../{issues/issue-18159.rs => typeck/missing-type-annotation.rs} | 0 .../issue-18159.stderr => typeck/missing-type-annotation.stderr} | 0 .../ui/{issues/issue-49854.rs => typeck/osstring-str-equality.rs} | 0 .../issue-18532.rs => typeck/return-expression-invalid-callee.rs} | 0 .../return-expression-invalid-callee.stderr} | 0 50 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-46472.rs => borrowck/return-ref-to-temporary.rs} (100%) rename tests/ui/{issues/issue-46472.stderr => borrowck/return-ref-to-temporary.stderr} (100%) rename tests/ui/{issues/issue-19499.rs => closures/closure-upvar-trait-caching.rs} (100%) rename tests/ui/{issues/issue-24779.rs => closures/nested-closure-call.rs} (100%) rename tests/ui/{issues/issue-24945-repeat-dash-opts.rs => codegen/repeated-debug-opt-flags.rs} (100%) rename tests/ui/{issues/issue-23253.rs => enum/enum-variant-no-field.rs} (100%) rename tests/ui/{issues/issue-23253.stderr => enum/enum-variant-no-field.stderr} (100%) rename tests/ui/{issues/issue-50442.rs => enum/enum-with-uninhabited-variant.rs} (100%) rename tests/ui/{issues/issue-18110.rs => expr/return-in-block-tuple.rs} (100%) rename tests/ui/{issues/issue-19398.rs => extern/extern-rust-trait-method.rs} (100%) rename tests/ui/{issues/issue-3656.rs => ffi/ffi-struct-size-alignment.rs} (100%) rename tests/ui/{issues/issue-11382.rs => fmt/println-float.rs} (100%) rename tests/ui/{issues/issue-43205.rs => indexing/ref-array-indexing.rs} (100%) rename tests/ui/{issues/issue-17758.rs => lifetimes/trait-method-lifetime-suggestion.rs} (100%) rename tests/ui/{issues/issue-17758.stderr => lifetimes/trait-method-lifetime-suggestion.stderr} (100%) rename tests/ui/lint/{lint-missing-doc-crate.rs => lint-missing-doc-crate-flags.rs} (100%) rename tests/ui/lint/{lint-missing-doc-crate.stderr => lint-missing-doc-crate-flags.stderr} (100%) rename tests/ui/{issues/issue-10656.rs => lint/lint-missing-docs-crate-attr.rs} (100%) rename tests/ui/{issues/issue-10656.stderr => lint/lint-missing-docs-crate-attr.stderr} (100%) rename tests/ui/{issues/issue-19734.rs => macros/undefined-macro-in-impl.rs} (100%) rename tests/ui/{issues/issue-19734.stderr => macros/undefined-macro-in-impl.stderr} (100%) rename tests/ui/{issues/issue-4968.rs => match/match-const-tuple-type-mismatch.rs} (100%) rename tests/ui/{issues/issue-4968.stderr => match/match-const-tuple-type-mismatch.stderr} (100%) rename tests/ui/{issues/issue-18464.rs => match/match-range-char-const.rs} (100%) rename tests/ui/{issues/issue-17933.rs => match/match-static-pattern.rs} (100%) rename tests/ui/{issues/issue-17933.stderr => match/match-static-pattern.stderr} (100%) rename tests/ui/{issues/issue-16783.rs => moves/array-copy-move.rs} (100%) rename tests/ui/{issues/issue-17373.rs => never_type/never-deref.rs} (100%) rename tests/ui/{issues/issue-17373.stderr => never_type/never-deref.stderr} (100%) rename tests/ui/{issues/issue-22644.rs => parser/cast-angle-bracket-precedence.rs} (100%) rename tests/ui/{issues/issue-22644.stderr => parser/cast-angle-bracket-precedence.stderr} (100%) rename tests/ui/{issues/issue-27033.rs => pattern/match-at-pattern-shadows-name.rs} (100%) rename tests/ui/{issues/issue-27033.stderr => pattern/match-at-pattern-shadows-name.stderr} (100%) rename tests/ui/{issues/issue-17001.rs => resolve/module-used-as-struct-constructor.rs} (100%) rename tests/ui/{issues/issue-17001.stderr => resolve/module-used-as-struct-constructor.stderr} (100%) rename tests/ui/{issues/issue-34047.rs => shadowed/match-binding-shadows-const.rs} (100%) rename tests/ui/{issues/issue-34047.stderr => shadowed/match-binding-shadows-const.stderr} (100%) rename tests/ui/{issues/issue-17450.rs => statics/static-mut-unsafe-init.rs} (100%) rename tests/ui/{issues/issue-21291.rs => threads-sendsync/thread-join-unwrap.rs} (100%) rename tests/ui/{issues/issue-20162.rs => trait-bounds/sort-missing-ord-bound.rs} (100%) rename tests/ui/{issues/issue-20162.stderr => trait-bounds/sort-missing-ord-bound.stderr} (100%) rename tests/ui/{issues/issue-21177.rs => traits/solver-cycles/assoc-equality-cycle.rs} (100%) rename tests/ui/{issues/issue-21177.stderr => traits/solver-cycles/assoc-equality-cycle.stderr} (100%) rename tests/ui/{issues/issue-20772.rs => traits/solver-cycles/self-item-cycle.rs} (100%) rename tests/ui/{issues/issue-20772.stderr => traits/solver-cycles/self-item-cycle.stderr} (100%) rename tests/ui/{issues/issue-18159.rs => typeck/missing-type-annotation.rs} (100%) rename tests/ui/{issues/issue-18159.stderr => typeck/missing-type-annotation.stderr} (100%) rename tests/ui/{issues/issue-49854.rs => typeck/osstring-str-equality.rs} (100%) rename tests/ui/{issues/issue-18532.rs => typeck/return-expression-invalid-callee.rs} (100%) rename tests/ui/{issues/issue-18532.stderr => typeck/return-expression-invalid-callee.stderr} (100%) diff --git a/tests/ui/issues/issue-46472.rs b/tests/ui/borrowck/return-ref-to-temporary.rs similarity index 100% rename from tests/ui/issues/issue-46472.rs rename to tests/ui/borrowck/return-ref-to-temporary.rs diff --git a/tests/ui/issues/issue-46472.stderr b/tests/ui/borrowck/return-ref-to-temporary.stderr similarity index 100% rename from tests/ui/issues/issue-46472.stderr rename to tests/ui/borrowck/return-ref-to-temporary.stderr diff --git a/tests/ui/issues/issue-19499.rs b/tests/ui/closures/closure-upvar-trait-caching.rs similarity index 100% rename from tests/ui/issues/issue-19499.rs rename to tests/ui/closures/closure-upvar-trait-caching.rs diff --git a/tests/ui/issues/issue-24779.rs b/tests/ui/closures/nested-closure-call.rs similarity index 100% rename from tests/ui/issues/issue-24779.rs rename to tests/ui/closures/nested-closure-call.rs diff --git a/tests/ui/issues/issue-24945-repeat-dash-opts.rs b/tests/ui/codegen/repeated-debug-opt-flags.rs similarity index 100% rename from tests/ui/issues/issue-24945-repeat-dash-opts.rs rename to tests/ui/codegen/repeated-debug-opt-flags.rs diff --git a/tests/ui/issues/issue-23253.rs b/tests/ui/enum/enum-variant-no-field.rs similarity index 100% rename from tests/ui/issues/issue-23253.rs rename to tests/ui/enum/enum-variant-no-field.rs diff --git a/tests/ui/issues/issue-23253.stderr b/tests/ui/enum/enum-variant-no-field.stderr similarity index 100% rename from tests/ui/issues/issue-23253.stderr rename to tests/ui/enum/enum-variant-no-field.stderr diff --git a/tests/ui/issues/issue-50442.rs b/tests/ui/enum/enum-with-uninhabited-variant.rs similarity index 100% rename from tests/ui/issues/issue-50442.rs rename to tests/ui/enum/enum-with-uninhabited-variant.rs diff --git a/tests/ui/issues/issue-18110.rs b/tests/ui/expr/return-in-block-tuple.rs similarity index 100% rename from tests/ui/issues/issue-18110.rs rename to tests/ui/expr/return-in-block-tuple.rs diff --git a/tests/ui/issues/issue-19398.rs b/tests/ui/extern/extern-rust-trait-method.rs similarity index 100% rename from tests/ui/issues/issue-19398.rs rename to tests/ui/extern/extern-rust-trait-method.rs diff --git a/tests/ui/issues/issue-3656.rs b/tests/ui/ffi/ffi-struct-size-alignment.rs similarity index 100% rename from tests/ui/issues/issue-3656.rs rename to tests/ui/ffi/ffi-struct-size-alignment.rs diff --git a/tests/ui/issues/issue-11382.rs b/tests/ui/fmt/println-float.rs similarity index 100% rename from tests/ui/issues/issue-11382.rs rename to tests/ui/fmt/println-float.rs diff --git a/tests/ui/issues/issue-43205.rs b/tests/ui/indexing/ref-array-indexing.rs similarity index 100% rename from tests/ui/issues/issue-43205.rs rename to tests/ui/indexing/ref-array-indexing.rs diff --git a/tests/ui/issues/issue-17758.rs b/tests/ui/lifetimes/trait-method-lifetime-suggestion.rs similarity index 100% rename from tests/ui/issues/issue-17758.rs rename to tests/ui/lifetimes/trait-method-lifetime-suggestion.rs diff --git a/tests/ui/issues/issue-17758.stderr b/tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr similarity index 100% rename from tests/ui/issues/issue-17758.stderr rename to tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr diff --git a/tests/ui/lint/lint-missing-doc-crate.rs b/tests/ui/lint/lint-missing-doc-crate-flags.rs similarity index 100% rename from tests/ui/lint/lint-missing-doc-crate.rs rename to tests/ui/lint/lint-missing-doc-crate-flags.rs diff --git a/tests/ui/lint/lint-missing-doc-crate.stderr b/tests/ui/lint/lint-missing-doc-crate-flags.stderr similarity index 100% rename from tests/ui/lint/lint-missing-doc-crate.stderr rename to tests/ui/lint/lint-missing-doc-crate-flags.stderr diff --git a/tests/ui/issues/issue-10656.rs b/tests/ui/lint/lint-missing-docs-crate-attr.rs similarity index 100% rename from tests/ui/issues/issue-10656.rs rename to tests/ui/lint/lint-missing-docs-crate-attr.rs diff --git a/tests/ui/issues/issue-10656.stderr b/tests/ui/lint/lint-missing-docs-crate-attr.stderr similarity index 100% rename from tests/ui/issues/issue-10656.stderr rename to tests/ui/lint/lint-missing-docs-crate-attr.stderr diff --git a/tests/ui/issues/issue-19734.rs b/tests/ui/macros/undefined-macro-in-impl.rs similarity index 100% rename from tests/ui/issues/issue-19734.rs rename to tests/ui/macros/undefined-macro-in-impl.rs diff --git a/tests/ui/issues/issue-19734.stderr b/tests/ui/macros/undefined-macro-in-impl.stderr similarity index 100% rename from tests/ui/issues/issue-19734.stderr rename to tests/ui/macros/undefined-macro-in-impl.stderr diff --git a/tests/ui/issues/issue-4968.rs b/tests/ui/match/match-const-tuple-type-mismatch.rs similarity index 100% rename from tests/ui/issues/issue-4968.rs rename to tests/ui/match/match-const-tuple-type-mismatch.rs diff --git a/tests/ui/issues/issue-4968.stderr b/tests/ui/match/match-const-tuple-type-mismatch.stderr similarity index 100% rename from tests/ui/issues/issue-4968.stderr rename to tests/ui/match/match-const-tuple-type-mismatch.stderr diff --git a/tests/ui/issues/issue-18464.rs b/tests/ui/match/match-range-char-const.rs similarity index 100% rename from tests/ui/issues/issue-18464.rs rename to tests/ui/match/match-range-char-const.rs diff --git a/tests/ui/issues/issue-17933.rs b/tests/ui/match/match-static-pattern.rs similarity index 100% rename from tests/ui/issues/issue-17933.rs rename to tests/ui/match/match-static-pattern.rs diff --git a/tests/ui/issues/issue-17933.stderr b/tests/ui/match/match-static-pattern.stderr similarity index 100% rename from tests/ui/issues/issue-17933.stderr rename to tests/ui/match/match-static-pattern.stderr diff --git a/tests/ui/issues/issue-16783.rs b/tests/ui/moves/array-copy-move.rs similarity index 100% rename from tests/ui/issues/issue-16783.rs rename to tests/ui/moves/array-copy-move.rs diff --git a/tests/ui/issues/issue-17373.rs b/tests/ui/never_type/never-deref.rs similarity index 100% rename from tests/ui/issues/issue-17373.rs rename to tests/ui/never_type/never-deref.rs diff --git a/tests/ui/issues/issue-17373.stderr b/tests/ui/never_type/never-deref.stderr similarity index 100% rename from tests/ui/issues/issue-17373.stderr rename to tests/ui/never_type/never-deref.stderr diff --git a/tests/ui/issues/issue-22644.rs b/tests/ui/parser/cast-angle-bracket-precedence.rs similarity index 100% rename from tests/ui/issues/issue-22644.rs rename to tests/ui/parser/cast-angle-bracket-precedence.rs diff --git a/tests/ui/issues/issue-22644.stderr b/tests/ui/parser/cast-angle-bracket-precedence.stderr similarity index 100% rename from tests/ui/issues/issue-22644.stderr rename to tests/ui/parser/cast-angle-bracket-precedence.stderr diff --git a/tests/ui/issues/issue-27033.rs b/tests/ui/pattern/match-at-pattern-shadows-name.rs similarity index 100% rename from tests/ui/issues/issue-27033.rs rename to tests/ui/pattern/match-at-pattern-shadows-name.rs diff --git a/tests/ui/issues/issue-27033.stderr b/tests/ui/pattern/match-at-pattern-shadows-name.stderr similarity index 100% rename from tests/ui/issues/issue-27033.stderr rename to tests/ui/pattern/match-at-pattern-shadows-name.stderr diff --git a/tests/ui/issues/issue-17001.rs b/tests/ui/resolve/module-used-as-struct-constructor.rs similarity index 100% rename from tests/ui/issues/issue-17001.rs rename to tests/ui/resolve/module-used-as-struct-constructor.rs diff --git a/tests/ui/issues/issue-17001.stderr b/tests/ui/resolve/module-used-as-struct-constructor.stderr similarity index 100% rename from tests/ui/issues/issue-17001.stderr rename to tests/ui/resolve/module-used-as-struct-constructor.stderr diff --git a/tests/ui/issues/issue-34047.rs b/tests/ui/shadowed/match-binding-shadows-const.rs similarity index 100% rename from tests/ui/issues/issue-34047.rs rename to tests/ui/shadowed/match-binding-shadows-const.rs diff --git a/tests/ui/issues/issue-34047.stderr b/tests/ui/shadowed/match-binding-shadows-const.stderr similarity index 100% rename from tests/ui/issues/issue-34047.stderr rename to tests/ui/shadowed/match-binding-shadows-const.stderr diff --git a/tests/ui/issues/issue-17450.rs b/tests/ui/statics/static-mut-unsafe-init.rs similarity index 100% rename from tests/ui/issues/issue-17450.rs rename to tests/ui/statics/static-mut-unsafe-init.rs diff --git a/tests/ui/issues/issue-21291.rs b/tests/ui/threads-sendsync/thread-join-unwrap.rs similarity index 100% rename from tests/ui/issues/issue-21291.rs rename to tests/ui/threads-sendsync/thread-join-unwrap.rs diff --git a/tests/ui/issues/issue-20162.rs b/tests/ui/trait-bounds/sort-missing-ord-bound.rs similarity index 100% rename from tests/ui/issues/issue-20162.rs rename to tests/ui/trait-bounds/sort-missing-ord-bound.rs diff --git a/tests/ui/issues/issue-20162.stderr b/tests/ui/trait-bounds/sort-missing-ord-bound.stderr similarity index 100% rename from tests/ui/issues/issue-20162.stderr rename to tests/ui/trait-bounds/sort-missing-ord-bound.stderr diff --git a/tests/ui/issues/issue-21177.rs b/tests/ui/traits/solver-cycles/assoc-equality-cycle.rs similarity index 100% rename from tests/ui/issues/issue-21177.rs rename to tests/ui/traits/solver-cycles/assoc-equality-cycle.rs diff --git a/tests/ui/issues/issue-21177.stderr b/tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr similarity index 100% rename from tests/ui/issues/issue-21177.stderr rename to tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr diff --git a/tests/ui/issues/issue-20772.rs b/tests/ui/traits/solver-cycles/self-item-cycle.rs similarity index 100% rename from tests/ui/issues/issue-20772.rs rename to tests/ui/traits/solver-cycles/self-item-cycle.rs diff --git a/tests/ui/issues/issue-20772.stderr b/tests/ui/traits/solver-cycles/self-item-cycle.stderr similarity index 100% rename from tests/ui/issues/issue-20772.stderr rename to tests/ui/traits/solver-cycles/self-item-cycle.stderr diff --git a/tests/ui/issues/issue-18159.rs b/tests/ui/typeck/missing-type-annotation.rs similarity index 100% rename from tests/ui/issues/issue-18159.rs rename to tests/ui/typeck/missing-type-annotation.rs diff --git a/tests/ui/issues/issue-18159.stderr b/tests/ui/typeck/missing-type-annotation.stderr similarity index 100% rename from tests/ui/issues/issue-18159.stderr rename to tests/ui/typeck/missing-type-annotation.stderr diff --git a/tests/ui/issues/issue-49854.rs b/tests/ui/typeck/osstring-str-equality.rs similarity index 100% rename from tests/ui/issues/issue-49854.rs rename to tests/ui/typeck/osstring-str-equality.rs diff --git a/tests/ui/issues/issue-18532.rs b/tests/ui/typeck/return-expression-invalid-callee.rs similarity index 100% rename from tests/ui/issues/issue-18532.rs rename to tests/ui/typeck/return-expression-invalid-callee.rs diff --git a/tests/ui/issues/issue-18532.stderr b/tests/ui/typeck/return-expression-invalid-callee.stderr similarity index 100% rename from tests/ui/issues/issue-18532.stderr rename to tests/ui/typeck/return-expression-invalid-callee.stderr From f4ee932b88cc67478e2abff48a766a2b9590d27d Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Wed, 10 Dec 2025 16:05:42 +0000 Subject: [PATCH 16/64] initial const generics docs --- src/doc/rustc-dev-guide/src/SUMMARY.md | 1 + src/doc/rustc-dev-guide/src/const-generics.md | 222 ++++++++++++++++++ .../src/hir/ambig-unambig-ty-and-consts.md | 66 +++++- .../rustc-dev-guide/src/solve/invariants.md | 5 + 4 files changed, 285 insertions(+), 9 deletions(-) create mode 100644 src/doc/rustc-dev-guide/src/const-generics.md diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index c136d37160c53..cdf61390baf04 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -191,6 +191,7 @@ - [HIR Type checking](./hir-typeck/summary.md) - [Coercions](./hir-typeck/coercions.md) - [Method lookup](./hir-typeck/method-lookup.md) +- [Const Generics](./const-generics.md) - [Opaque types](./opaque-types-type-alias-impl-trait.md) - [Inference details](./opaque-types-impl-trait-inference.md) - [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md) diff --git a/src/doc/rustc-dev-guide/src/const-generics.md b/src/doc/rustc-dev-guide/src/const-generics.md new file mode 100644 index 0000000000000..ffde2051e07dd --- /dev/null +++ b/src/doc/rustc-dev-guide/src/const-generics.md @@ -0,0 +1,222 @@ +# Const Generics + +## Kinds of const arguments + +Most of the kinds of `ty::Const` that exist have direct parallels to kinds of types that exist, for example `ConstKind::Param` is equivalent to `TyKind::Param`. + +The main interesting points here are: +- [`ConstKind::Unevaluated`], this is equivalent to `TyKind::Alias` and in the long term should be renamed (as well as introducing an `AliasConstKind` to parallel `ty::AliasKind`). +- [`ConstKind::Value`], this is the final value of a `ty::Const` after monomorphization. This is similar-ish to fully concrete to things like `TyKind::Str` or `TyKind::ADT`. + +For a complete list of *all* kinds of const arguments and how they are actually represented in the type system, see the [`ConstKind`] type. + +Inference Variables are quite boring and treated equivalently to type inference variables almost everywhere. Const Parameters are also similarly boring and equivalent to uses of type parameters almost everywhere. However, there are some interesting subtleties with how they are handled during parsing, name resolution, and AST lowering: [ambig-unambig-ty-and-consts]. + +## Anon Consts + +Anon Consts (short for anonymous const items) are how arbitrary expression are represented in const generics, for example an array length of `1 + 1` or `foo()` or even just `0`. These are unique to const generics and have no real type equivalent. + +### Desugaring + +```rust +struct Foo; +type Alias = [u8; 1 + 1]; +``` + +In this example we have a const argument of `1 + 1` (the array length) which is represented as an *anon const*. The desugaring would look something like: +```rust +struct Foo; + +const ANON: usize = 1 + 1; +type Alias = [u8; ANON]; +``` + +Where the array length in `[u8; ANON]` isn't itself an anon const containing a usage of `ANON`, but a kind of "direct" usage of the `ANON` const item ([`ConstKind::Unevaluated`]). + +Anon consts do not inherit any generic parameters of the item they are inside of: +```rust +struct Foo; +type Alias = [T; 1 + 1]; + +// Desugars To; + +struct Foo; + +const ANON: usize = 1 + 1; +type Alias = [T; ANON]; +``` + +Note how the `ANON` const has no generic parameters or where clauses, even though `Alias` has both a type parameter `T` and a where clauses `T: Sized`. This desugaring is part of how we enforce that anon consts can't make use of generic parameters. + +While it's useful to think of anon consts as being desugared to real const items, the compiler does not actually implement things this way. + +At AST lowering time we do not yet know the *type* of the anon const, so we can't desugar to a real HIR item with an explicitly written type. To work around this we have [`DefKind::AnonConst`] and [`hir::Node::AnonConst`] which are used to represent these anonymous const items that can't actually be desugared. + +The types of these anon consts are obtainable from the [`type_of`] query. However, the `type_of` query does not actually contain logic for computing the type (infact it just ICEs when called), instead HIR Ty lowering is responsible for *feeding* the value of the `type_of` query for any anon consts that get lowered. HIR Ty lowering can determine the type of the anon const by looking at the type of the Const Parameter that the anon const is an argument to. + +TODO: write a chapter on query feeding and link it here + +In some sense the desugarings from the previous examples are to: +```rust +struct Foo; +type Alias = [u8; 1 + 1]; + +// sort-of desugars to psuedo-rust: +struct Foo; + +const ANON = 1 + 1; +type Alias = [u8; ANON]; +``` + +Where when we go through HIR ty lowering for the array type in `Alias`, we will lower the array length too and feed `type_of(ANON) -> usize`. Effectively setting the type of the `ANON` const item during some later part of the compiler rather than when constructing the HIR. + +After all of this desugaring has taken place the final representation in the type system (ie as a `ty::Const`) is a `ConstKind::Unevaluated` with the `DefId` of the `AnonConst`. This is equivalent to how we would representa a usage of an actual const item if we were to represent them without going through an anon const (e.g. when `min_generic_const_args` is enabled). + +This allows the representation for const "aliases" to be the same as the representation of `TyKind::Alias`. Having a proper HIR body also allows for a *lot* of code re-use, e.g. we can reuse HIR typechecking and all of the lowering steps to MIR where we can then reuse const eval. + +### Enforcing lack of Generic Parameters + +There are three ways that we enforce anon consts can't use generic parameters: +1. Name Resolution will not resolve paths to generic parameters when inside of an anon const +2. HIR Ty lowering will error when a `Self` type alias to a type referencing generic parameters is encountered inside of an anon const +3. Anon Consts do not inherit where clauses or generics from their parent definition (ie [`generics_of`] does not contain a parent for anon consts) + +```rust +// *1* Errors in name resolution +type Alias = [u8; N + 1]; +//~^ ERROR: generic parameters may not be used in const operations + +// *2* Errors in HIR Ty lowering: +struct Foo(T); +impl Foo { + fn assoc() -> [u8; { let a: Self; 0 }] {} + //~^ ERROR: generic `Self` types are currently not permitted in anonymous constants +} + +// *3* Errors due to lack of where clauses on the desugared anon const +trait Trait { + const ASSOC: usize; +} +fn foo() -> [u8; <()>::ASSOC] +//~^ ERROR: no associated item named `ASSOC` found for unit type `()` +where + (): Trait {} +``` + +The second point is particularly subtle as it is very easy to get HIR Ty lowering wrong and not properly enforce that anon consts can't use generic parameters. The existing check is too conservative and accidentally permits some generic parameters to wind up in the body of the anon const [#144547](https://github.com/rust-lang/rust/issues/144547). + +Erroneously allowing generic parameters in anon consts can sometimes lead to ICEs but can also lead to accepting illformed programs. + +The third point is also somewhat subtle, by not inheriting any of the where clauses of the parent item we can't wind up with the trait solving inferring inference variables to generic parameters based off where clauses in scope that mention generic parameters. For example inferring `?x=T` from the expression `<() as Trait>::ASSOC` and an in scope where clause of `(): Trait`. + +This also makes it much more likely that the compiler will ICE or atleast incidentally emit some kind of error if we *do* accidentally allow generic parameters in an anon const, as the anon const will have none of the necessary information in its environment to properly handle the generic parameters. + +```rust +fn foo() { + let a = [1_u8; size_of::<*mut T>()]; +} +``` + +The one exception to all of the above is repeat counts of array expressions. As a *backwards compatibility hack* we allow the repeat count const argument to use generic parameters. + +However, to avoid most of the problems involved in allowing generic parameters in anon const const arguments we require that the constant be evaluated before monomorphization (e.g. during type checking). In some sense we only allow generic parameters here when they are semantically unused. + +In the previous example the anon const can be evaluated for any type parameter `T` because raw pointers to sized types always have the same size (e.g. `8` on 64bit platforms). + +When detecting that we evaluated an anon const that syntactically contained generic parameters, but did not actually depend on them for evaluation to succeed, we emit the [`const_evaluatable_unchecked` FCW][cec_fcw]. This is intended to become a hard error once we stabilize more ways of using generic parameters in const arguments, for example `min_generic_const_args` or (the now dead) `generic_const_exprs`. + +The implementation for this FCW can be found here: [`const_eval_resolve_for_typeck`] + +### Incompatibilities with `generic_const_parameter_types` + +Supporting const paramters such as `const N: [u8; M]` or `const N: Foo` does not work very nicely with the current anon consts setup. There are two reasons for this: +1. As anon consts cannot use generic parameters, their type *also* can't reference generic parameters. This means it is fundamentally not possible to use an anon const as an argument to a const parameeter whose type still references generic parameters. + + ```rust + #![feature(adt_const_params, generic_const_parameter_types)] + + fn foo() {} + + fn bar() { + // There is no way to specify the const argument to `M` + foo::(); + } + ``` + +2. We currently require knowing the type of anon consts when lowering them during HIR ty lowering. With generic const parameter types it may be the case that the currently known type contains inference variables (ie may not be fully known yet). + + ```rust + #![feature(adt_const_params, generic_const_parameter_types)] + + fn foo() {} + + fn bar() { + // The const argument to `N` must be explicitly specified + // even though it is able to be inferred + foo::<_, { [1_u8; 3] }>(); + } + ``` + +It is currently unclear what the right way to make `generic_const_parameter_types` work nicely with the rest of const generics is. + +`generic_const_exprs` would have allowed for anon consts with types referencing generic parameters, but that design wound up unworkable. + +`min_generic_const_args` will allow for some expressions (for example array construction) to be representable without an anon const and therefore without running into these issues, though whether this is *enough* has yet to be determined. + +## Checking types of Const Arguments + +In order for a const argument to be well formed it must have the same type as the const parameter it is an argument to. For example a const argument of type `bool` for an array length is not well formed, as an array's length parameter has type `usize`. + +```rust +type Alias = [u8; B]; +//~^ ERROR: +``` + +To check this we have [`ClauseKind::ConstArgHasType(ty::Const, Ty)`][const_arg_has_type], where for each Const Parameter defined on an item we also desugar an equivalent `ConstArgHasType` clause into its list of where cluases. This ensures that whenever we check wellformedness of anything by proving all of its clauses, we also check happen to check that all of the Const Arguments have the correct type. + +```rust +fn foo() {} + +// desugars to in psuedo-rust + +fn foo() +where +// ConstArgHasType(N, usize) + N: usize, {} +``` + +Proving `ConstArgHasType` goals is implemented by first computing the type of the const argument, then equating it with the provided type. A rough outline of how the type of a Const Argument may be computed: +- [`ConstKind::Param(N)`][`ConstKind::Param`] can be looked up in the [`ParamEnv`] to find a `ConstArgHasType(N, ty)` clause +- [`ConstKind::Value`] stores the type of the value inside itself so can trivially be accessed +- [`ConstKind::Unevaluated`] can have its type computed by calling the `type_of` query +- See the implementation of proving `ConstArgHasType` goals for more detailed information + +`ConstArgHasType` is *the* soundness critical way that we check Const Arguments have the correct type. However, we do *indirectly* check the types of Const Arguments a different way in some cases. + +```rust +type Alias = [u8; true]; + +// desugars to + +const ANON: usize = true; +type Alias = [u8; ANON]; +``` + +By feeding the type of an anon const with the type of the Const Parameter we guarantee that the `ConstArgHasType` goal involving the anon const will succeed. In cases where the type of the anon const doesn't match the type of the Const Parameter what actually happens is a *type checking* error when type checking the anon const's body. + +Looking at the above example, this corresponds to `[u8; ANON]` being a well formed type because `ANON` has type `usize`, but the *body* of `ANON` being illformed and resulting in a type checking error because `true` can't be returned from a const item of type `usize`. + +[ambig-unambig-ty-and-consts]: ./hir/ambig-unambig-ty-and-consts.md +[`ConstKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html +[`ConstKind::Infer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html#variant.Infer +[`ConstKind::Param`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html#variant.Param +[`ConstKind::Unevaluated`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html#variant.Unevaluated +[`ConstKind::Value`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html#variant.Value +[const_arg_has_type]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ClauseKind.html#variant.ConstArgHasType +[`ParamEnv`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html +[`generics_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#impl-TyCtxt%3C'tcx%3E/method.generics_of +[`type_of`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.type_of +[`DefKind::AnonConst`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def/enum.DefKind.html#variant.AnonConst +[`hir::Node::AnonConst`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.Node.html#variant.AnonConst# +[cec_fcw]: https://github.com/rust-lang/rust/issues/76200 +[`const_eval_resolve_for_typeck`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.const_eval_resolve_for_typeck diff --git a/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md b/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md index d4f504ad2a98d..64a15b7f9aa82 100644 --- a/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md +++ b/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md @@ -1,6 +1,6 @@ # Ambig/Unambig Types and Consts -Types and Consts args in the HIR can be in two kinds of positions ambiguous (ambig) or unambiguous (unambig). Ambig positions are where +Types and Consts args in the AST/HIR can be in two kinds of positions ambiguous (ambig) or unambiguous (unambig). Ambig positions are where it would be valid to parse either a type or a const, unambig positions are where only one kind would be valid to parse. @@ -21,29 +21,69 @@ fn func(arg: T) { ``` -Most types/consts in ambig positions are able to be disambiguated as either a type or const during parsing. Single segment paths are always represented as types in the AST but may get resolved to a const parameter during name resolution, then lowered to a const argument during ast-lowering. The only generic arguments which remain ambiguous after lowering are inferred generic arguments (`_`) in path segments. For example, in `Foo<_>` it is not clear whether the `_` argument is an inferred type argument, or an inferred const argument. +Most types/consts in ambig positions are able to be disambiguated as either a type or const during parsing. The only exceptions to this are paths and inferred generic arguments. -In unambig positions, inferred arguments are represented with [`hir::TyKind::Infer`][ty_infer] or [`hir::ConstArgKind::Infer`][const_infer] depending on whether it is a type or const position respectively. -In ambig positions, inferred arguments are represented with `hir::GenericArg::Infer`. +## Paths + +```rust +struct Foo; + +fn foo(_: Foo) {} +``` + +At parse time we parse all unbraced generic arguments as *types* (ie they wind up as [`ast::GenericArg::Ty`]). In the above example this means we would parse the generic argument to `Foo` as an `ast::GenericArg::Ty` wrapping a [`ast::Ty::Path(N)`]. + +Then during name resolution: +- When encountering a single segment path with no generic arguments in generic argument position, we will first try to resolve it in the type namespace and if that fails we then attempt to resolve in the value namespace. +- All other kinds of paths we only try to resolve in the type namespace + +See [`LateResolutionVisitor::visit_generic_arg`] for where this is implemented. + +Finally during AST lowering when we attempt to lower a type argument, we first check if it is a `Ty::Path` and if it resolved to something in the value namespace. If it did then we create an *anon const* and lower to a const argument instead of a type argument. + +See [`LoweringContext::lower_generic_arg`] for where this is implemented. + +Note that the ambiguity for paths is not propgated into the HIR; there's no `hir::GenericArg::Path` which is turned into either a `Ty` or `Const` during HIR ty lowering (though we could do such a thing). + +## Inferred arguments (`_`) + +```rust +struct Foo; + +fn foo() { + let _unused: Foo<_>; +} +``` + +The only generic arguments which remain ambiguous after lowering are inferred generic arguments (`_`) in path segments. In the above example it is not clear at parse time whether the `_` argument to `Foo` is an inferred type argument, or an inferred const argument. + +In ambig AST positions, inferred argumentsd are parsed as an [`ast::GenericArg::Ty`] wrapping a [`ast::Ty::Infer`]. Then during AST lowering when lowering an `ast::GenericArg::Ty` we check if it is an inferred type and if so lower to a [`hir::GenericArg::Infer`]. + +In unambig AST positions, inferred arguments are parsed as either `ast::Ty::Infer` or [`ast::AnonConst`]. The `AnonConst` case is quite strange, we use [`ast::ExprKind::Underscore`] to represent the "body" of the "anon const" although in reality we do not actually lower this to an anon const in the HIR. + +It may be worth seeing if we can refactor the AST to have `ast::GenericArg::Infer` and then get rid of this overloaded meaning of `AnonConst`, as well as the reuse of `ast::Ty::Infer` in ambig positions. + +In unambig AST positions, during AST lowering we lower inferred arguments to [`hir::TyKind::Infer`][ty_infer] or [`hir::ConstArgKind::Infer`][const_infer] depending on whether it is a type or const position respectively. +In ambig AST positions, during AST lowering we lower inferred arguments to [`hir::GenericArg::Infer`][generic_arg_infer]. See [`LoweringContext::lower_generic_arg`] for where this is implemented. A naive implementation of this would result in there being potentially 5 places where you might think an inferred type/const could be found in the HIR from looking at the structure of the HIR: -1. In unambig type position as a `hir::TyKind::Infer` -2. In unambig const arg position as a `hir::ConstArgKind::Infer` +1. In unambig type position as a `TyKind::Infer` +2. In unambig const arg position as a `ConstArgKind::Infer` 3. In an ambig position as a [`GenericArg::Type(TyKind::Infer)`][generic_arg_ty] 4. In an ambig position as a [`GenericArg::Const(ConstArgKind::Infer)`][generic_arg_const] -5. In an ambig position as a [`GenericArg::Infer`][generic_arg_infer] +5. In an ambig position as a `GenericArg::Infer` Note that places 3 and 4 would never actually be possible to encounter as we always lower to `GenericArg::Infer` in generic arg position. This has a few failure modes: - People may write visitors which check for `GenericArg::Infer` but forget to check for `hir::TyKind/ConstArgKind::Infer`, only handling infers in ambig positions by accident. -- People may write visitors which check for `hir::TyKind/ConstArgKind::Infer` but forget to check for `GenericArg::Infer`, only handling infers in unambig positions by accident. +- People may write visitors which check for `TyKind/ConstArgKind::Infer` but forget to check for `GenericArg::Infer`, only handling infers in unambig positions by accident. - People may write visitors which check for `GenericArg::Type/Const(TyKind/ConstArgKind::Infer)` and `GenericArg::Infer`, not realising that we never represent inferred types/consts in ambig positions as a `GenericArg::Type/Const`. - People may write visitors which check for *only* `TyKind::Infer` and not `ConstArgKind::Infer` forgetting that there are also inferred const arguments (and vice versa). To make writing HIR visitors less error prone when caring about inferred types/consts we have a relatively complex system: -1. We have different types in the compiler for when a type or const is in an unambig or ambig position, `hir::Ty` and `hir::Ty<()>`. [`AmbigArg`][ambig_arg] is an uninhabited type which we use in the `Infer` variant of `TyKind` and `ConstArgKind` to selectively "disable" it if we are in an ambig position. +1. We have different types in the compiler for when a type or const is in an unambig or ambig position, `Ty` and `Ty<()>`. [`AmbigArg`][ambig_arg] is an uninhabited type which we use in the `Infer` variant of `TyKind` and `ConstArgKind` to selectively "disable" it if we are in an ambig position. 2. The [`visit_ty`][visit_ty] and [`visit_const_arg`][visit_const_arg] methods on HIR visitors only accept the ambig position versions of types/consts. Unambig types/consts are implicitly converted to ambig types/consts during the visiting process, with the `Infer` variant handled by a dedicated [`visit_infer`][visit_infer] method. @@ -61,3 +101,11 @@ This has a number of benefits: [visit_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_ty [visit_const_arg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_const_arg [visit_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_infer +[`LateResolutionVisitor::visit_generic_arg`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/struct.LateResolutionVisitor.html#method.visit_generic_arg +[`LoweringContext::lower_generic_arg`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/struct.LoweringContext.html#method.lower_generic_arg +[`ast::GenericArg::Ty`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.GenericArg.html#variant.Type +[`ast::Ty::Infer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.TyKind.html#variant.Infer +[`ast::AnonConst`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/struct.AnonConst.html +[`hir::GenericArg::Infer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.GenericArg.html#variant.Infer +[`ast::ExprKind::Underscore`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.ExprKind.html#variant.Underscore +[`ast::Ty::Path(N)`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/enum.TyKind.html#variant.Path \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/solve/invariants.md b/src/doc/rustc-dev-guide/src/solve/invariants.md index 8ec15f339e51b..efdd97fd1418b 100644 --- a/src/doc/rustc-dev-guide/src/solve/invariants.md +++ b/src/doc/rustc-dev-guide/src/solve/invariants.md @@ -168,5 +168,10 @@ We lookup types using structural equality during codegen, but this shouldn't nec Semantically different `'static` types need different `TypeId`s to avoid transmutes, for example `for<'a> fn(&'a str)` vs `fn(&'static str)` must have a different `TypeId`. +## Evaluation of const items is deterministic ✅ + +As the values of const items can feed into the type system, it is important that the value of a const item is always the same in every crate. If this isn't the case then we can wind up with associated types with "equal" const arguments and so are "equal" associated types, and yet when normalized during codegen in different crates actually wind up as different types. + +Notably this does *not* extend to const *functions*, as the type system only works with the results of const *items* it's actually fine for const functions to be non deterministic so long as that doesn't affect the final value of a const item. [coherence chapter]: ../coherence.md From c17a0f425685a9b386e408b9ef50789b251d36a4 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Wed, 10 Dec 2025 16:08:39 +0000 Subject: [PATCH 17/64] move docs about ambig ty and consts --- src/doc/rustc-dev-guide/src/SUMMARY.md | 2 +- .../src/{hir => }/ambig-unambig-ty-and-consts.md | 0 src/doc/rustc-dev-guide/src/const-generics.md | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/doc/rustc-dev-guide/src/{hir => }/ambig-unambig-ty-and-consts.md (100%) diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index cdf61390baf04..1678d4f62dc41 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -126,8 +126,8 @@ - [Lang Items](./lang-items.md) - [The HIR (High-level IR)](./hir.md) - [Lowering AST to HIR](./hir/lowering.md) - - [Ambig/Unambig Types and Consts](./hir/ambig-unambig-ty-and-consts.md) - [Debugging](./hir/debugging.md) +- [Ambig/Unambig Types and Consts](./ambig-unambig-ty-and-consts.md) - [The THIR (Typed High-level IR)](./thir.md) - [The MIR (Mid-level IR)](./mir/index.md) - [MIR construction](./mir/construction.md) diff --git a/src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md b/src/doc/rustc-dev-guide/src/ambig-unambig-ty-and-consts.md similarity index 100% rename from src/doc/rustc-dev-guide/src/hir/ambig-unambig-ty-and-consts.md rename to src/doc/rustc-dev-guide/src/ambig-unambig-ty-and-consts.md diff --git a/src/doc/rustc-dev-guide/src/const-generics.md b/src/doc/rustc-dev-guide/src/const-generics.md index ffde2051e07dd..cb8c7adc07f46 100644 --- a/src/doc/rustc-dev-guide/src/const-generics.md +++ b/src/doc/rustc-dev-guide/src/const-generics.md @@ -206,7 +206,7 @@ By feeding the type of an anon const with the type of the Const Parameter we gua Looking at the above example, this corresponds to `[u8; ANON]` being a well formed type because `ANON` has type `usize`, but the *body* of `ANON` being illformed and resulting in a type checking error because `true` can't be returned from a const item of type `usize`. -[ambig-unambig-ty-and-consts]: ./hir/ambig-unambig-ty-and-consts.md +[ambig-unambig-ty-and-consts]: ./ambig-unambig-ty-and-consts.md [`ConstKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html [`ConstKind::Infer`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html#variant.Infer [`ConstKind::Param`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/type.ConstKind.html#variant.Param From 6672a89f98c3018967af44be7dafba14953ddafd Mon Sep 17 00:00:00 2001 From: Redddy Date: Thu, 11 Dec 2025 23:47:25 +0900 Subject: [PATCH 18/64] Fix broken link for 'Uniqueness and Reference Immutability' --- src/doc/rustc-dev-guide/src/appendix/bibliography.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/appendix/bibliography.md b/src/doc/rustc-dev-guide/src/appendix/bibliography.md index 3729194f5fa1a..e862ac368475c 100644 --- a/src/doc/rustc-dev-guide/src/appendix/bibliography.md +++ b/src/doc/rustc-dev-guide/src/appendix/bibliography.md @@ -15,7 +15,7 @@ Rust, as well as publications about Rust. * [Safe manual memory management in Cyclone](https://www.cs.umd.edu/projects/PL/cyclone/scp.pdf) * [Skolem Normal Form](https://en.wikipedia.org/wiki/Skolem_normal_form) * [Traits: composable units of behavior](http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf) -* [Uniqueness and Reference Immutability for Safe Parallelism](https://research.microsoft.com/pubs/170528/msr-tr-2012-79.pdf) +* [Uniqueness and Reference Immutability for Safe Parallelism](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/msr-tr-2012-79.pdf) ## Concurrency From 30eb6adf41e2105fd92213d8a129347cde200ded Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 11 Dec 2025 20:18:57 +0000 Subject: [PATCH 19/64] say "certain" --- src/doc/rustc-dev-guide/src/tests/compiletest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index cda5c1bcec715..c885bce75dd61 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -90,7 +90,7 @@ The following test suites are available, with links for more information: | `rustdoc-ui` | Check terminal output of `rustdoc` ([see also](ui.md)) | Some rustdoc-specific tests can also be found in `ui/rustdoc/`. -These tests ensure that lints that are emitted as part of executing rustdoc +These tests ensure that certain lints that are emitted as part of executing rustdoc are also run when executing rustc. Run-make tests pertaining to rustdoc are typically named `run-make/rustdoc-*/`. From 0e81edcc67dc6148cc2b3da4f4bedcfed19b0fbf Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Thu, 11 Dec 2025 21:14:14 +0000 Subject: [PATCH 20/64] fix help wanted search --- src/doc/rustc-dev-guide/src/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md index 34bc5b59dd03c..061f6966f4b78 100644 --- a/src/doc/rustc-dev-guide/src/getting-started.md +++ b/src/doc/rustc-dev-guide/src/getting-started.md @@ -96,7 +96,7 @@ For example: Not all important or beginner work has issue labels. See below for how to find work that isn't labelled. -[help-wanted-search]: https://github.com/issues?q=is%3Aopen+is%3Aissue+org%3Arust-lang+no%3Aassignee+label%3AE-easy%2C%22good+first+issue%22%2Cgood-first-issue%2CE-medium%2CEasy%2CE-help-wanted%2CE-mentor+-label%3AS-blocked+-linked%3Apr+ +[help-wanted-search]: https://github.com/issues?q=is%3Aopen%20is%3Aissue%20org%3Arust-lang%20no%3Aassignee%20label%3AE-easy%2CE-medium%2CE-help-wanted%2CE-mentor%20-label%3AS-blocked%20-linked%3Apr [Triage]: ./contributing.md#issue-triage ### Recurring work From e58de3a54c0d019f0725d2e33d23833894cfd52c Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 11 Dec 2025 21:18:21 +0000 Subject: [PATCH 21/64] clarify why define_opaque isnt needed --- .../rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md index 0f0e8e87c3213..9f20bfc708dce 100644 --- a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md +++ b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md @@ -85,7 +85,7 @@ impl Baz for Quux { ``` For this you would also need to use `nightly` and the (different) `#![feature(impl_trait_in_assoc_type)]` annotation. -Note that you don't need a `#[define_opaque(Foo)]` on the method anymore. +Note that you don't need a `#[define_opaque(Foo)]` on the method anymore as the opaque type is mentioned in the function signature (behind the associated type). Complete example: ``` From 8e77f362c7da14a0e25edaa93c7bb1864455ab4e Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Thu, 11 Dec 2025 23:37:10 +0000 Subject: [PATCH 22/64] make more clear code snippet is supposed to error --- .../rustc-dev-guide/src/ty_module/instantiating_binders.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md b/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md index 0d1108c72e0ef..7e29b95437140 100644 --- a/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md +++ b/src/doc/rustc-dev-guide/src/ty_module/instantiating_binders.md @@ -1,6 +1,6 @@ # Instantiating `Binder`s -Much like [`EarlyBinder`], when accessing the inside of a [`Binder`] we must first discharge it by replacing the bound vars with some other value. This is for much the same reason as with `EarlyBinder`, types referencing parameters introduced by the `Binder` do not make any sense outside of that binder, for example: +Much like [`EarlyBinder`], when accessing the inside of a [`Binder`] we must first discharge it by replacing the bound vars with some other value. This is for much the same reason as with `EarlyBinder`, types referencing parameters introduced by the `Binder` do not make any sense outside of that binder. See the following erroring example: ```rust,ignore fn foo<'a>(a: &'a u32) -> &'a u32 { a @@ -11,10 +11,11 @@ fn bar(a: fn(&u32) -> T) -> T { fn main() { let higher_ranked_fn_ptr = foo as for<'a> fn(&'a u32) -> &'a u32; + // Attempt to infer `T=for<'a> &'a u32` which is not satsifiable let references_bound_vars = bar(higher_ranked_fn_ptr); } ``` -In this example we are providing an argument of type `for<'a> fn(&'^0 u32) -> &'^0 u32` to `bar`, we do not want to allow `T` to be inferred to the type `&'^0 u32` as it would be rather nonsensical (and likely unsound if we did not happen to ICE, `main` has no idea what `'a` is so how would the borrow checker handle a borrow with lifetime `'a`). +In this example we are providing an argument of type `for<'a> fn(&'^0 u32) -> &'^0 u32` to `bar`, we do not want to allow `T` to be inferred to the type `&'^0 u32` as it would be rather nonsensical (and likely unsound if we did not happen to ICE). `main` doesn't know about `'a` so the borrow checker would not be able to handle a borrow with lifetime `'a`. Unlike `EarlyBinder` we typically do not instantiate `Binder` with some concrete set of arguments from the user, i.e. `['b, 'static]` as arguments to a `for<'a1, 'a2> fn(&'a1 u32, &'a2 u32)`. Instead we usually instantiate the binder with inference variables or placeholders. From 31f801ef4038bf5024a199835ec15dbb17f01c8a Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Thu, 11 Dec 2025 23:43:59 +0000 Subject: [PATCH 23/64] clarify test suite is not formatted --- src/doc/rustc-dev-guide/src/conventions.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md index cce1d18506946..31028f1b94141 100644 --- a/src/doc/rustc-dev-guide/src/conventions.md +++ b/src/doc/rustc-dev-guide/src/conventions.md @@ -21,6 +21,9 @@ Instead, formatting should be done using `./x fmt`. It's a good habit to run Formatting is checked by the `tidy` script. It runs automatically when you do `./x test` and can be run in isolation with `./x fmt --check`. +We do not check that tests under the `tests/` directory are formatted, and +similarly the `./x fmt` command will not format any files under that directory. + If you want to use format-on-save in your editor, the pinned version of `rustfmt` is built under `build//stage0/bin/rustfmt`. From 3662b4ca36a63a37bf36ebc8ed56889912551111 Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Thu, 11 Dec 2025 08:07:02 +0800 Subject: [PATCH 24/64] Add LoongArch notification group instructions --- src/doc/rustc-dev-guide/src/SUMMARY.md | 1 + .../src/notification-groups/about.md | 2 ++ .../src/notification-groups/loongarch.md | 22 +++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 src/doc/rustc-dev-guide/src/notification-groups/loongarch.md diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index 826a2955e60a6..e80ee6a5137d8 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -66,6 +66,7 @@ - [ARM](notification-groups/arm.md) - [Emscripten](notification-groups/emscripten.md) - [Fuchsia](notification-groups/fuchsia.md) + - [LoongArch](notification-groups/loongarch.md) - [RISC-V](notification-groups/risc-v.md) - [Rust for Linux](notification-groups/rust-for-linux.md) - [WASI](notification-groups/wasi.md) diff --git a/src/doc/rustc-dev-guide/src/notification-groups/about.md b/src/doc/rustc-dev-guide/src/notification-groups/about.md index c649b930fe9ff..917a0f8a1020e 100644 --- a/src/doc/rustc-dev-guide/src/notification-groups/about.md +++ b/src/doc/rustc-dev-guide/src/notification-groups/about.md @@ -22,6 +22,7 @@ Here's the list of the notification groups: - [Apple](./apple.md) - [ARM](./arm.md) - [Emscripten](./emscripten.md) +- [LoongArch](./loongarch.md) - [RISC-V](./risc-v.md) - [WASI](./wasi.md) - [WebAssembly](./wasm.md) @@ -63,6 +64,7 @@ Example PRs: * [Example of adding yourself to the Apple group.](https://github.com/rust-lang/team/pull/1434) * [Example of adding yourself to the ARM group.](https://github.com/rust-lang/team/pull/358) * [Example of adding yourself to the Emscripten group.](https://github.com/rust-lang/team/pull/1579) +* [Example of adding yourself to the LoongArch group.](https://github.com/rust-lang/team/pull/2176) * [Example of adding yourself to the RISC-V group.](https://github.com/rust-lang/team/pull/394) * [Example of adding yourself to the WASI group.](https://github.com/rust-lang/team/pull/1580) * [Example of adding yourself to the WebAssembly group.](https://github.com/rust-lang/team/pull/1581) diff --git a/src/doc/rustc-dev-guide/src/notification-groups/loongarch.md b/src/doc/rustc-dev-guide/src/notification-groups/loongarch.md new file mode 100644 index 0000000000000..0a3707a9ad999 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/notification-groups/loongarch.md @@ -0,0 +1,22 @@ +# LoongArch notification group + +**Github Label:** [O-loongarch]
+**Ping command:** `@rustbot ping loongarch` + +[O-loongarch]: https://github.com/rust-lang/rust/labels/O-loongarch + +This list will be used to ask for help both in diagnosing and testing +LoongArch-related issues as well as suggestions on how to resolve +interesting questions regarding our LoongArch support. + +The group also has an associated Zulip channel ([`#t-compiler/loong-arch`]) +where people can go to pose questions and discuss LoongArch-specific topics. + +So, if you are interested in participating, please sign up for the +LoongArch group! To do so, open a PR against the [rust-lang/team] +repository. Just [follow this example][eg], but change the username to +your own! + +[`#t-compiler/loong-arch`]: https://rust-lang.zulipchat.com/#narrow/channel/551512-t-compiler.2Floong-arch +[rust-lang/team]: https://github.com/rust-lang/team +[eg]: https://github.com/rust-lang/team/pull/2176 From ce822cd6f2b6012d2e44d696c915ea7634eb8f04 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Thu, 11 Dec 2025 23:53:21 +0000 Subject: [PATCH 25/64] remove dashboard :( --- src/doc/rustc-dev-guide/src/tests/ci.md | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index a30af309a54eb..e132946ae83ee 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -447,23 +447,6 @@ More information is available in the [toolstate documentation]. [rust-toolstate]: https://rust-lang-nursery.github.io/rust-toolstate [toolstate documentation]: https://forge.rust-lang.org/infra/toolstate.html -## Public CI dashboard - -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 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. -- Top failed jobs: check which jobs are failing the most. - -To learn more about the dashboard, see the [Datadog CI docs]. - -[Datadog CI docs]: https://docs.datadoghq.com/continuous_integration/ -[public dashboard]: https://p.datadoghq.com/sb/3a172e20-e9e1-11ed-80e3-da7ad0900002-b5f7bb7e08b664a06b08527da85f7e30 - ## Determining the CI configuration If you want to determine which `bootstrap.toml` settings are used in CI for a From bceccc2eb361685ca6e073979a9080a49599fff9 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Fri, 12 Dec 2025 00:02:33 +0000 Subject: [PATCH 26/64] link to forge policy --- src/doc/rustc-dev-guide/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index fee7cf042e1f8..8f0fa462a8c5d 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -38,6 +38,11 @@ In general, when writing about a particular part of the compiler's code, we recommend that you link to the relevant parts of the [rustc rustdocs][rustdocs]. +The guide has a much lower bar for what it takes for a PR to be merged. Check out +the forge documentation for [our policy][forge_policy]. + +[forge_policy]: https://forge.rust-lang.org/rustc-dev-guide/index.html#review-policy + ### Build Instructions To build a local static HTML site, install [`mdbook`](https://github.com/rust-lang/mdBook) with: From 7897102fde1c930c4c059b38dea0c4d1b611d7d8 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 12 Dec 2025 09:17:18 +0800 Subject: [PATCH 27/64] Make test suite formatting remark more precise --- src/doc/rustc-dev-guide/src/conventions.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/conventions.md b/src/doc/rustc-dev-guide/src/conventions.md index 31028f1b94141..92ed0825c8c3e 100644 --- a/src/doc/rustc-dev-guide/src/conventions.md +++ b/src/doc/rustc-dev-guide/src/conventions.md @@ -21,8 +21,15 @@ Instead, formatting should be done using `./x fmt`. It's a good habit to run Formatting is checked by the `tidy` script. It runs automatically when you do `./x test` and can be run in isolation with `./x fmt --check`. -We do not check that tests under the `tests/` directory are formatted, and -similarly the `./x fmt` command will not format any files under that directory. +> **Note: Formatting and test suites** +> +> Most Rust source files under `tests/` directory are not formatted for reasons +> such as whitespace sensitivity, nature of snapshot tests, location-sensitive +> comments and more. +> +> Consult the `ignore` entries in +> for which test +> files are not formatted. If you want to use format-on-save in your editor, the pinned version of `rustfmt` is built under `build//stage0/bin/rustfmt`. From 73c682a1fd8e94417fdc7ab5683c7d22b563ceee Mon Sep 17 00:00:00 2001 From: Redddy Date: Fri, 12 Dec 2025 16:00:26 +0900 Subject: [PATCH 28/64] Add link to needs test issues in getting-started.md --- src/doc/rustc-dev-guide/src/getting-started.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md index 061f6966f4b78..36d19e6c570e2 100644 --- a/src/doc/rustc-dev-guide/src/getting-started.md +++ b/src/doc/rustc-dev-guide/src/getting-started.md @@ -151,6 +151,9 @@ Issues that have been resolved but do not have a regression test are marked with Writing unit tests is a low-risk, lower-priority task that offers new contributors a great opportunity to familiarize themselves with the testing infrastructure and contribution workflow. +You can see a list of needs test issues [here][needs-test-issues]. + +[needs-test-issues]: https://github.com/rust-lang/rust/issues?q=is%3Aissue%20is%3Aopen%20label%3AE-needs-test%20no%3Aassignee ### Contributing to std (standard library) From 49db9ec01b894b09d2f592e2ce09884c5a1093f9 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Sun, 15 Jun 2025 20:40:13 +0800 Subject: [PATCH 29/64] Update and add more details for Providers Signed-off-by: xizheyin Co-authored-by: Boxy --- src/doc/rustc-dev-guide/src/query.md | 142 +++++++++++++++++++++------ 1 file changed, 110 insertions(+), 32 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md index 8377a7b2f31a7..5df9de7620381 100644 --- a/src/doc/rustc-dev-guide/src/query.md +++ b/src/doc/rustc-dev-guide/src/query.md @@ -69,22 +69,24 @@ are cheaply cloneable; insert an `Rc` if necessary). If, however, the query is *not* in the cache, then the compiler will call the corresponding **provider** function. A provider is a function -implemented in a specific module and **manually registered** into the -[`Providers`][providers_struct] struct during compiler initialization. -The macro system generates the [`Providers`][providers_struct] struct, -which acts as a function table for all query implementations, where each +implemented in a specific module and **manually registered** into either +the [`Providers`][providers_struct] struct (for local crate queries) or +the [`ExternProviders`][extern_providers_struct] struct (for external crate queries) +during compiler initialization. The macro system generates both structs, +which act as function tables for all query implementations, where each field is a function pointer to the actual provider. -**Note:** The `Providers` struct is generated by macros and acts as a function table for all query implementations. -It is **not** a Rust trait, but a plain struct with function pointer fields. +**Note:** Both the `Providers` and `ExternProviders` structs are generated by macros and act as function tables for all query implementations. +They are **not** Rust traits, but plain structs with function pointer fields. **Providers are defined per-crate.** The compiler maintains, internally, a table of providers for every crate, at least -conceptually. Right now, there are really two sets: the providers for -queries about the **local crate** (that is, the one being compiled) -and providers for queries about **external crates** (that is, -dependencies of the local crate). Note that what determines the crate -that a query is targeting is not the *kind* of query, but the *key*. +conceptually. There are two sets of providers: +- The `Providers` struct for queries about the **local crate** (that is, the one being compiled) +- The `ExternProviders` struct for queries about **external crates** (that is, +dependencies of the local crate) + +Note that what determines the crate that a query is targeting is not the *kind* of query, but the *key*. For example, when you invoke `tcx.type_of(def_id)`, that could be a local query or an external query, depending on what crate the `def_id` is referring to (see the [`self::keys::Key`][Key] trait for more @@ -117,31 +119,31 @@ they define both a `provide` and a `provide_extern` function, through ### How providers are set up -When the tcx is created, it is given the providers by its creator using -the [`Providers`][providers_struct] struct. This struct is generated by -the macros here, but it is basically a big list of function pointers: - -[providers_struct]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/struct.Providers.html +When the tcx is created, it is given both the local and external providers by its creator using +the `Providers` struct from `rustc_middle::util`. This struct contains both the local and external providers: ```rust,ignore -struct Providers { - type_of: for<'tcx> fn(TyCtxt<'tcx>, DefId) -> Ty<'tcx>, - // ... one field for each query +pub struct Providers { + pub queries: crate::query::Providers, // Local crate providers + pub extern_queries: crate::query::ExternProviders, // External crate providers + pub hooks: crate::hooks::Providers, } ``` +Each of these provider structs is generated by the macros and contains function pointers for their respective queries. + #### How are providers registered? -The `Providers` struct is filled in during compiler initialization, mainly by the `rustc_driver` crate. -But the actual provider functions are implemented in various `rustc_*` crates (like `rustc_middle`, `rustc_hir_analysis`, etc). +The `util::Providers` struct is filled in during compiler initialization, by the `rustc_interface` crate from the `DEFAULT_QUERY_PROVIDERS` static. +The actual provider functions are defined across various `rustc_*` crates (like `rustc_middle`, `rustc_hir_analysis`, etc). To register providers, each crate exposes a [`provide`][provide_fn] function that looks like this: [provide_fn]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/fn.provide.html ```rust,ignore -pub fn provide(providers: &mut Providers) { - *providers = Providers { +pub fn provide(providers: &mut query::Providers) { + *providers = query::Providers { type_of, // ... add more providers here ..*providers @@ -149,27 +151,104 @@ pub fn provide(providers: &mut Providers) { } ``` -- This function takes a mutable reference to the `Providers` struct and sets the fields to point to the correct provider functions. -- You can also assign fields individually, e.g. `providers.type_of = type_of;`. +Note that this function accepts `query::Providers` not `util::Providers`. It is exceedingly rare to need a `provide` function that doesn't just accept `query::Providers`. If more than the `queries` field of `util::Providers` is being updated then `util::Providers` can be accepted instead: +```rust,ignore +pub fn provide(providers: &mut rustc_middle::util::Providers) { + providers.queries.type_of = type_of; + // ... add more local providers here + + providers.extern_queries.type_of = extern_type_of; + // ... add more external providers here + + providers.hooks.some_hook = some_hook; + // ... add more hooks here +} +``` + +Note that `util::Providers` implements `DerefMut` to `query::Providers` so callers of the `provide` functions can pass in a `util::Providers` and it will just work for provider functions that accept `query::Providers` too + +- This function takes a mutable reference to the `query::Providers` struct and sets the fields to point to the correct provider functions. +- You can also assign queries individually, e.g. `providers.type_of = type_of;`. +- You can assign fields individually for each provider type (local, external, and hooks). #### Adding a new provider -Suppose you want to add a new query called `fubar`. You would: +Suppose you want to add a new query called `fubar`. This section focuses on wiring up the providers; for how to declare the query itself in the big `rustc_queries!` macro, see [Adding a new query](#adding-a-new-query) below. + +In practice you usually: -1. Implement the provider function: +1. Decide which crate "owns" the query (for example `rustc_hir_analysis`, `rustc_mir_build`, or another `rustc_*` crate). +2. In that crate, look for an existing `provide` function: + ```rust,ignore + pub fn provide(providers: &mut query::Providers) { + // existing assignments + } + ``` + If it exists, you will extend it to set the field for your new query. If the crate does not yet have a `provide` function, add one and make sure it is included in `DEFAULT_QUERY_PROVIDERS` in the `rustc_interface` crate so that it actually gets called during initialization (see the discussion above). +3. Implement the provider function itself: ```rust,ignore - fn fubar<'tcx>(tcx: TyCtxt<'tcx>, key: DefId) -> Fubar<'tcx> { ... } + fn fubar<'tcx>(tcx: TyCtxt<'tcx>, key: LocalDefId) -> Fubar<'tcx> { ... } ``` -2. Register it in the `provide` function: +4. Register it in the crate's `provide` function: ```rust,ignore - pub fn provide(providers: &mut Providers) { - *providers = Providers { + pub fn provide(providers: &mut query::Providers) { + *providers = query::Providers { fubar, ..*providers }; } ``` +### How queries interact with external crate metadata + +When a query is made for an external crate (i.e., a dependency), the query system needs to load the information from that crate's metadata. +This is handled by the [`rustc_metadata` crate][rustc_metadata], which is responsible for decoding and providing the information stored in the `.rmeta` files. + +The process works like this: + +1. When a query is made, the query system first checks if the `DefId` refers to a local or external crate by checking if `def_id.krate == LOCAL_CRATE`. + This determines whether to use the local provider from [`Providers`][providers_struct] or the external provider from [`ExternProviders`][extern_providers_struct]. + +2. For external crates, the query system will look for a provider in the [`ExternProviders`][extern_providers_struct] struct. + The `rustc_metadata` crate registers these external providers through the `provide_extern` function in `rustc_metadata/src/rmeta/decoder/cstore_impl.rs`. Just like: + ```rust + pub fn provide_extern(providers: &mut ExternProviders) { + providers.foo = |tcx, def_id| { + // Load and decode metadata for external crate + let cdata = CStore::from_tcx(tcx).get_crate_data(def_id.krate); + cdata.foo(def_id.index) + }; + // Register other external providers... + } + ``` + +3. The metadata is stored in a binary format in `.rmeta` files that contains pre-computed information about the external crate, such as types, function signatures, trait implementations, and other information needed by the compiler. When an external query is made, the `rustc_metadata` crate: + - Loads the `.rmeta` file for the external crate + - Decodes the metadata using the `Decodable` trait + - Returns the decoded information to the query system + +This approach avoids recompiling external crates, allows for faster compilation of dependent crates, and enables incremental compilation to work across crate boundaries. +Here is a simplified example, when you call `tcx.type_of(def_id)` for a type defined in an external crate, the query system will: +1. Detect that the `def_id` refers to an external crate by checking `def_id.krate != LOCAL_CRATE` +2. Call the appropriate provider from `ExternProviders` which was registered by `rustc_metadata` +3. The provider will load and decode the type information from the external crate's metadata +4. Return the decoded type to the caller + +This is why most `rustc_*` crates only need to provide local providers - the external providers are handled by the metadata system. +The only exception is when a crate needs to provide special handling for external queries, in which case it would implement both local and external providers. + +When we define a new query that should work across crates, it does not automatically become cross-crate just because it is listed in `rustc_queries!`. You will typically need to: + +- Add the query to `rustc_queries!` with appropriate modifiers (for example whether it is cached on disk). +- Implement a local provider in the owning crate and register it via that crate's `provide` function. +- Add an external provider in `rustc_metadata` via `provide_extern`, and ensure the query's result is encoded and decoded in the crate metadata. + +An example of introducing such a cross-crate query can be found in commit [`996a185`](https://github.com/rust-lang/rust/commit/996a185) in the `rust-lang/rust` repository. + +[rustc_metadata]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/index.html +[providers_struct]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/struct.Providers.html +[extern_providers_struct]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/query/struct.ExternProviders.html + --- ## Adding a new query @@ -263,4 +342,3 @@ More discussion and issues: [GitHub issue #42633]: https://github.com/rust-lang/rust/issues/42633 [Incremental Compilation Beta]: https://internals.rust-lang.org/t/incremental-compilation-beta/4721 [Incremental Compilation Announcement]: https://blog.rust-lang.org/2016/09/08/incremental.html - From 900c79ac89cf72b6d40e7de6beff2e01d8e97e9a Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 12 Dec 2025 21:24:59 +0000 Subject: [PATCH 30/64] update some outdated infos on error codes --- .../src/diagnostics/error-codes.md | 42 ++++++------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md b/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md index 1693432b90de7..c7bb6669dce46 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md @@ -33,40 +33,22 @@ written, as always: ask your reviewer or ask around on the Rust Zulip. Error codes are stored in `compiler/rustc_error_codes`. -To create a new error, you first need to find the next available -code. You can find it with `tidy`: +To create a new error, you first need to find the next available code. +You can find it by opening `rustc_error_codes/src/lib.rs` and scrolling down +to the end of the `error_codes!` macro declaration. -``` -./x test tidy -``` - -This will invoke the tidy script, which generally checks that your code obeys -our coding conventions. Some of these jobs check error codes and ensure that -there aren't duplicates, etc (the tidy check is defined in -`src/tools/tidy/src/error_codes.rs`). Once it is finished with that, tidy will -print out the highest used error code: - -``` -... -tidy check -Found 505 error codes -Highest error code: `E0591` -... -``` - -Here we see the highest error code in use is `E0591`, so we _probably_ want -`E0592`. To be sure, run `rg E0592` and check, you should see no references. +Here we might see the highest error code in use is `E0805`, so we _probably_ want +`E0806`. To be sure, run `rg E0806` and check, you should see no references. You will have to write an extended description for your error, -which will go in `rustc_error_codes/src/error_codes/E0592.md`. -To register the error, open `rustc_error_codes/src/error_codes.rs` and add the -code (in its proper numerical order) into` register_diagnostics!` macro, like -this: +which will go in `rustc_error_codes/src/error_codes/E0806.md`. +To register the error, add the code (in its proper numerical order) to +the `error_codes!` macro, like this: ```rust -register_diagnostics! { - ... - E0592: include_str!("./error_codes/E0592.md"), +macro_rules! error_codes { +... +0806, } ``` @@ -75,7 +57,7 @@ To actually issue the error, you can use the `struct_span_code_err!` macro: ```rust struct_span_code_err!(self.dcx(), // some path to the `DiagCtxt` here span, // whatever span in the source you want - E0592, // your new error code + E0806, // your new error code fluent::example::an_error_message) .emit() // actually issue the error ``` From 42334f76a7fc2c00e518908f38e5ece4ff672ab8 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 15:22:27 +0200 Subject: [PATCH 31/64] sembr README.md --- src/doc/rustc-dev-guide/README.md | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index 8f0fa462a8c5d..9c439b83739c7 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -1,8 +1,8 @@ [![CI](https://github.com/rust-lang/rustc-dev-guide/actions/workflows/ci.yml/badge.svg)](https://github.com/rust-lang/rustc-dev-guide/actions/workflows/ci.yml) -This is a collaborative effort to build a guide that explains how rustc -works. The aim of the guide is to help new contributors get oriented +This is a collaborative effort to build a guide that explains how rustc works. +The aim of the guide is to help new contributors get oriented to rustc, as well as to help more experienced folks in figuring out some new part of the compiler that they haven't worked on before. @@ -21,25 +21,24 @@ For documentation on developing the standard library, see The guide is useful today, but it has a lot of work still to go. -If you'd like to help improve the guide, we'd love to have you! You can find -plenty of issues on the [issue -tracker](https://github.com/rust-lang/rustc-dev-guide/issues). Just post a -comment on the issue you would like to work on to make sure that we don't -accidentally duplicate work. If you think something is missing, please open an -issue about it! +If you'd like to help improve the guide, we'd love to have you! +You can find plenty of issues on the [issue +tracker](https://github.com/rust-lang/rustc-dev-guide/issues). +Just post a comment on the issue you would like to work on to make sure that we don't +accidentally duplicate work. +If you think something is missing, please open an issue about it! **In general, if you don't know how the compiler works, that is not a problem!** In that case, what we will do is to schedule a bit of time for you to talk with someone who **does** know the code, or who wants -to pair with you and figure it out. Then you can work on writing up -what you learned. +to pair with you and figure it out. + Then you can work on writing up what you learned. In general, when writing about a particular part of the compiler's code, we -recommend that you link to the relevant parts of the [rustc -rustdocs][rustdocs]. +recommend that you link to the relevant parts of the [rustc rustdocs][rustdocs]. -The guide has a much lower bar for what it takes for a PR to be merged. Check out -the forge documentation for [our policy][forge_policy]. +The guide has a much lower bar for what it takes for a PR to be merged. +Check out the forge documentation for [our policy][forge_policy]. [forge_policy]: https://forge.rust-lang.org/rustc-dev-guide/index.html#review-policy @@ -61,9 +60,9 @@ The build files are found in the `book/html` directory. ### Link Validations -We use `mdbook-linkcheck2` to validate URLs included in our documentation. Link -checking is **not** run by default locally, though it is in CI. To enable it -locally, set the environment variable `ENABLE_LINKCHECK=1` like in the +We use `mdbook-linkcheck2` to validate URLs included in our documentation. +Link checking is **not** run by default locally, though it is in CI. +To enable it locally, set the environment variable `ENABLE_LINKCHECK=1` like in the following example. ``` @@ -72,6 +71,7 @@ ENABLE_LINKCHECK=1 mdbook serve ## Synchronizing josh subtree with rustc -This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization. +This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. +You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization. You can find a guide on how to perform the synchronization [here](./src/external-repos.md#synchronizing-a-josh-subtree). From 12c2c05a26a584d2dfb72922649c02378c67eaef Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Sat, 13 Dec 2025 13:27:26 +0000 Subject: [PATCH 32/64] Prepare for merging from rust-lang/rust This updates the rust-version file to ce63e5d9ea20f15a70c6fdc4d4de7aee352fd965. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 7a84872f266d1..4bcbec1a9f480 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -dfe1b8c97bcde283102f706d5dcdc3649e5e12e3 +ce63e5d9ea20f15a70c6fdc4d4de7aee352fd965 From ef04de5f20ff7033160b5a57e96b23e6b79c574a Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 15:54:54 +0200 Subject: [PATCH 33/64] sembr nit (missed by tool) --- src/doc/rustc-dev-guide/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index 9c439b83739c7..dba4f9ea759e6 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -2,8 +2,8 @@ This is a collaborative effort to build a guide that explains how rustc works. -The aim of the guide is to help new contributors get oriented -to rustc, as well as to help more experienced folks in figuring out +The aim of the guide is to help new contributors get oriented to rustc, +as well as to help more experienced folks in figuring out some new part of the compiler that they haven't worked on before. [You can read the latest version of the guide here.](https://rustc-dev-guide.rust-lang.org/) From 48782ebaea174e1e706c2ccf4e95408d45811a71 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 15:56:22 +0200 Subject: [PATCH 34/64] small README improvements --- src/doc/rustc-dev-guide/README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index dba4f9ea759e6..ed14e000f49a6 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -1,19 +1,15 @@ [![CI](https://github.com/rust-lang/rustc-dev-guide/actions/workflows/ci.yml/badge.svg)](https://github.com/rust-lang/rustc-dev-guide/actions/workflows/ci.yml) - This is a collaborative effort to build a guide that explains how rustc works. The aim of the guide is to help new contributors get oriented to rustc, as well as to help more experienced folks in figuring out some new part of the compiler that they haven't worked on before. -[You can read the latest version of the guide here.](https://rustc-dev-guide.rust-lang.org/) +You may also find the [rustc API docs] useful. -You may also find the rustdocs [for the compiler itself][rustdocs] useful. Note that these are not intended as a guide; it's recommended that you search for the docs you're looking for instead of reading them top to bottom. -[rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc - For documentation on developing the standard library, see [`std-dev-guide`](https://std-dev-guide.rust-lang.org/). @@ -32,10 +28,10 @@ If you think something is missing, please open an issue about it! problem!** In that case, what we will do is to schedule a bit of time for you to talk with someone who **does** know the code, or who wants to pair with you and figure it out. - Then you can work on writing up what you learned. +Then you can work on writing up what you learned. In general, when writing about a particular part of the compiler's code, we -recommend that you link to the relevant parts of the [rustc rustdocs][rustdocs]. +recommend that you link to the relevant parts of the [rustc API docs]. The guide has a much lower bar for what it takes for a PR to be merged. Check out the forge documentation for [our policy][forge_policy]. @@ -75,3 +71,5 @@ This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.g You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization. You can find a guide on how to perform the synchronization [here](./src/external-repos.md#synchronizing-a-josh-subtree). + +[rustc API docs]: https://doc.rust-lang.org/nightly/nightly-rustc From bf1f3ebf3713e5a7df7b745a3918afeb8f70a5a7 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 16:08:32 +0200 Subject: [PATCH 35/64] point to the "main crate", instead of a list of crates --- src/doc/rustc-dev-guide/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/README.md b/src/doc/rustc-dev-guide/README.md index ed14e000f49a6..59d6719c71cbd 100644 --- a/src/doc/rustc-dev-guide/README.md +++ b/src/doc/rustc-dev-guide/README.md @@ -72,4 +72,4 @@ You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool t You can find a guide on how to perform the synchronization [here](./src/external-repos.md#synchronizing-a-josh-subtree). -[rustc API docs]: https://doc.rust-lang.org/nightly/nightly-rustc +[rustc API docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle From dd91e003814086e0d92316b1569ac8629869d965 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 16:19:08 +0200 Subject: [PATCH 36/64] whitespace --- src/doc/rustc-dev-guide/.github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/.github/workflows/ci.yml b/src/doc/rustc-dev-guide/.github/workflows/ci.yml index fe92bc876cf71..3ec22145ccd2a 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/ci.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: pull_request: schedule: # Run multiple times a day as the successfull cached links are not checked every time. - - cron: '0 */8 * * *' + - cron: "0 */8 * * *" jobs: ci: From 745a0fb8d3354ecd2bcd57358d3067163c38ed06 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 16:24:32 +0200 Subject: [PATCH 37/64] does not work for some reason --- src/doc/rustc-dev-guide/.github/workflows/ci.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/doc/rustc-dev-guide/.github/workflows/ci.yml b/src/doc/rustc-dev-guide/.github/workflows/ci.yml index 3ec22145ccd2a..f2f2f7ed14858 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/ci.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/ci.yml @@ -83,16 +83,6 @@ jobs: git commit -m "Deploy ${GITHUB_SHA} to gh-pages" git push --quiet -f "https://x-token:${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}" HEAD:gh-pages - - name: Cache sembr build - uses: actions/cache@v4 - with: - path: | - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - ci/sembr/target/ - key: sembr-${{ hashFiles('ci/sembr/Cargo.lock') }} - - name: Check if files comply with semantic line breaks continue-on-error: true run: | From ce0f8c9b4dfc4355008615ccc4ed82b7a7f1122f Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 16:43:00 +0200 Subject: [PATCH 38/64] test is hard to follow --- src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 34 -------------------- 1 file changed, 34 deletions(-) diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index 7ace34aed984a..04bf7e2bd79bc 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -294,40 +294,6 @@ fn test_prettify_ignore_link_targets() { assert_eq!(original, lengthen_lines(original, 100)); } -#[test] -fn test_sembr_then_prettify() { - let original = " -hi there. do -not split -short sentences. -hi again. -"; - let expected = " -hi there. -do -not split -short sentences. -hi again. -"; - let processed = comply(original); - assert_eq!(expected, processed); - let expected = " -hi there. -do not split -short sentences. -hi again. -"; - let processed = lengthen_lines(&processed, 50); - assert_eq!(expected, processed); - let expected = " -hi there. -do not split short sentences. -hi again. -"; - let processed = lengthen_lines(&processed, 50); - assert_eq!(expected, processed); -} - #[test] fn test_sembr_question_mark() { let original = " From 9d62f73e874bd37f23b24e79faa9d5679c9953b4 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 17:23:06 +0200 Subject: [PATCH 39/64] fix corner case --- src/doc/rustc-dev-guide/ci/sembr/src/main.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs index 04bf7e2bd79bc..2539a9eadda34 100644 --- a/src/doc/rustc-dev-guide/ci/sembr/src/main.rs +++ b/src/doc/rustc-dev-guide/ci/sembr/src/main.rs @@ -177,6 +177,9 @@ fn lengthen_lines(content: &str, limit: usize) -> String { let Some(next_line) = content.get(n + 1) else { continue; }; + if next_line.trim_start().starts_with("```") { + continue; + } if ignore(next_line, in_code_block) || REGEX_LIST_ENTRY.is_match(next_line) || REGEX_IGNORE_END.is_match(line) @@ -255,6 +258,12 @@ preserve next line preserve next line * three + +do not mess with code block chars +``` +leave the +text alone +``` "; let expected = "\ do not split short sentences @@ -269,6 +278,12 @@ preserve next line preserve next line * three + +do not mess with code block chars +``` +leave the +text alone +``` "; assert_eq!(expected, lengthen_lines(original, 50)); } From 3d73b326340b71048bb92b02acc805f5b10a0d47 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 16:31:53 +0200 Subject: [PATCH 40/64] sembr fuzzing.md --- src/doc/rustc-dev-guide/src/fuzzing.md | 68 +++++++++++++------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index cc98b49a97c68..295f2ef872656 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -3,12 +3,13 @@ For the purposes of this guide, *fuzzing* is any testing methodology that -involves compiling a wide variety of programs in an attempt to uncover bugs in -rustc. Fuzzing is often used to find internal compiler errors (ICEs). Fuzzing -can be beneficial, because it can find bugs before users run into them and +involves compiling a wide variety of programs in an attempt to uncover bugs in rustc. +Fuzzing is often used to find internal compiler errors (ICEs). +Fuzzing can be beneficial, because it can find bugs before users run into them and provide small, self-contained programs that make the bug easier to track down. However, some common mistakes can reduce the helpfulness of fuzzing and end up -making contributors' lives harder. To maximize your positive impact on the Rust +making contributors' lives harder. +To maximize your positive impact on the Rust project, please read this guide before reporting fuzzer-generated bugs! ## Guidelines @@ -28,16 +29,14 @@ project, please read this guide before reporting fuzzer-generated bugs! - Don't report lots of bugs that use internal features, including but not limited to `custom_mir`, `lang_items`, `no_core`, and `rustc_attrs`. -- Don't seed your fuzzer with inputs that are known to crash rustc (details - below). +- Don't seed your fuzzer with inputs that are known to crash rustc (details below). ### Discussion If you're not sure whether or not an ICE is a duplicate of one that's already -been reported, please go ahead and report it and link to issues you think might -be related. In general, ICEs on the same line but with different *query stacks* -are usually distinct bugs. For example, [#109020][#109020] and [#109129][#109129] -had similar error messages: +been reported, please go ahead and report it and link to issues you think might be related. +In general, ICEs on the same line but with different *query stacks* are usually distinct bugs. +For example, [#109020][#109020] and [#109129][#109129] had similar error messages: ``` error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead @@ -63,10 +62,10 @@ end of query stack ## Building a corpus -When building a corpus, be sure to avoid collecting tests that are already -known to crash rustc. A fuzzer that is seeded with such tests is more likely to -generate bugs with the same root cause, wasting everyone's time. The simplest -way to avoid this is to loop over each file in the corpus, see if it causes an +When building a corpus, be sure to avoid collecting tests that are already known to crash rustc. +A fuzzer that is seeded with such tests is more likely to +generate bugs with the same root cause, wasting everyone's time. +The simplest way to avoid this is to loop over each file in the corpus, see if it causes an ICE, and remove it if so. To build a corpus, you may want to use: @@ -84,16 +83,16 @@ To build a corpus, you may want to use: Here are a few things you can do to help the Rust project after filing an ICE. - [Bisect][bisect] the bug to figure out when it was introduced. - If you find the regressing PR / commit, you can mark the issue with the label - `S-has-bisection`. If not, consider applying `E-needs-bisection` instead. + If you find the regressing PR / commit, you can mark the issue with the label `S-has-bisection`. + If not, consider applying `E-needs-bisection` instead. - Fix "distractions": problems with the test case that don't contribute to 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`. +- 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 [crash test]. While you're at it, consider including other "untracked" crashes in your PR. - Please don't forget to mark all relevant issues with `S-bug-has-test` once - your PR is merged. + 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]. @@ -103,13 +102,14 @@ See also [applying and removing labels][labeling]. ## Minimization -It is helpful to carefully *minimize* the fuzzer-generated input. When -minimizing, be careful to preserve the original error, and avoid introducing +It is helpful to carefully *minimize* the fuzzer-generated input. +When minimizing, be careful to preserve the original error, and avoid introducing distracting problems such as syntax, type-checking, or borrow-checking errors. -There are some tools that can help with minimization. If you're not sure how -to avoid introducing syntax, type-, and borrow-checking errors while using -these tools, post both the complete and minimized test cases. Generally, +There are some tools that can help with minimization. +If you're not sure how to avoid introducing syntax, type-, and borrow-checking errors while using +these tools, post both the complete and minimized test cases. +Generally, *syntax-aware* tools give the best results in the least amount of time. [`treereduce-rust`][treereduce] and [picireny][picireny] are syntax-aware. [`halfempty`][halfempty] is not, but is generally a high-quality tool. @@ -121,21 +121,23 @@ these tools, post both the complete and minimized test cases. Generally, ## Effective fuzzing When fuzzing rustc, you may want to avoid generating machine code, since this -is mostly done by LLVM. Try `--emit=mir` instead. +is mostly done by LLVM. +Try `--emit=mir` instead. -A variety of compiler flags can uncover different issues. `-Zmir-opt-level=4` -will turn on MIR optimization passes that are not run by default, potentially -uncovering interesting bugs. `-Zvalidate-mir` can help uncover such bugs. +A variety of compiler flags can uncover different issues. +`-Zmir-opt-level=4` will turn on MIR optimization passes that are not run by default, potentially +uncovering interesting bugs. +`-Zvalidate-mir` can help uncover such bugs. If you're fuzzing a compiler you built, you may want to build it with `-C -target-cpu=native` or even PGO/BOLT to squeeze out a few more executions per -second. Of course, it's best to try multiple build configurations and see +target-cpu=native` or even PGO/BOLT to squeeze out a few more executions per second. +Of course, it's best to try multiple build configurations and see what actually results in superior throughput. You may want to build rustc from source with debug assertions to find additional bugs, though this is a trade-off: it can slow down fuzzing by -requiring extra work for every execution. To enable debug assertions, add this -to `bootstrap.toml` when compiling rustc: +requiring extra work for every execution. +To enable debug assertions, add this to `bootstrap.toml` when compiling rustc: ```toml [rust] From cfe2be49b53a192bbe20946743503032ebaf071b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 17:36:27 +0200 Subject: [PATCH 41/64] make more readable --- src/doc/rustc-dev-guide/src/fuzzing.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 295f2ef872656..009ca07706683 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -5,8 +5,8 @@ For the purposes of this guide, *fuzzing* is any testing methodology that involves compiling a wide variety of programs in an attempt to uncover bugs in rustc. Fuzzing is often used to find internal compiler errors (ICEs). -Fuzzing can be beneficial, because it can find bugs before users run into them and -provide small, self-contained programs that make the bug easier to track down. +Fuzzing can be beneficial, because it can find bugs before users run into them. +It also provides small, self-contained programs that make the bug easier to track down. However, some common mistakes can reduce the helpfulness of fuzzing and end up making contributors' lives harder. To maximize your positive impact on the Rust @@ -144,7 +144,7 @@ To enable debug assertions, add this to `bootstrap.toml` when compiling rustc: debug-assertions = true ``` -ICEs that require debug assertions to reproduce should be tagged +ICEs that require debug assertions to reproduce should be tagged [`requires-debug-assertions`][requires-debug-assertions]. [requires-debug-assertions]: https://github.com/rust-lang/rust/labels/requires-debug-assertions From a1b57f4383e1c6c8df6ce5d4e684c39ce11420e2 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 17:39:16 +0200 Subject: [PATCH 42/64] remove unclear text --- src/doc/rustc-dev-guide/src/fuzzing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 009ca07706683..b4792f8ef9f1c 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -22,7 +22,7 @@ project, please read this guide before reporting fuzzer-generated bugs! - Include a reasonably minimal, standalone example along with any bug report - Include all of the information requested in the bug report template - Search for existing reports with the same message and query stack -- Format the test case with `rustfmt`, if it maintains the bug +- Format the test case with `rustfmt` - Indicate that the bug was found by fuzzing *Please don't:* From d79d0aef3c702e1bfe735bff2615f4160852765b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 17:46:47 +0200 Subject: [PATCH 43/64] horizontal scroll is excessive for these examples --- src/doc/rustc-dev-guide/src/fuzzing.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index b4792f8ef9f1c..070092879e4d5 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -38,13 +38,11 @@ been reported, please go ahead and report it and link to issues you think might In general, ICEs on the same line but with different *query stacks* are usually distinct bugs. For example, [#109020][#109020] and [#109129][#109129] had similar error messages: -``` -error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead -``` -``` -error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <() as Project>::Assoc, maybe try to call `try_normalize_erasing_regions` instead -``` -but different query stacks: +> error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead + +> error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <() as Project>::Assoc, maybe try to call `try_normalize_erasing_regions` instead + +However, they have different query stacks: ``` query stack during panic: #0 [fn_abi_of_instance] computing call ABI of `<[closure@src/main.rs:36:25: 36:28] as core::ops::function::FnOnce<(Emplacable<()>,)>>::call_once - shim(vtable)` From 6f5454a580913795e58ad480f8e3c243139026f2 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 17:47:48 +0200 Subject: [PATCH 44/64] guidance is clear enough --- src/doc/rustc-dev-guide/src/fuzzing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 070092879e4d5..dc601e8b00926 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -62,7 +62,7 @@ end of query stack When building a corpus, be sure to avoid collecting tests that are already known to crash rustc. A fuzzer that is seeded with such tests is more likely to -generate bugs with the same root cause, wasting everyone's time. +generate bugs with the same root cause. The simplest way to avoid this is to loop over each file in the corpus, see if it causes an ICE, and remove it if so. From d8d8dbd9732c264090c7dcc97a5ff992352a980a Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 18:02:02 +0200 Subject: [PATCH 45/64] feels appropriate --- src/doc/rustc-dev-guide/src/fuzzing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index dc601e8b00926..6cbe3cdb43596 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -78,7 +78,7 @@ To build a corpus, you may want to use: ## Extra credit -Here are a few things you can do to help the Rust project after filing an ICE. +Here are a few things you can do to help the Rust project after filing an ICE: - [Bisect][bisect] the bug to figure out when it was introduced. If you find the regressing PR / commit, you can mark the issue with the label `S-has-bisection`. From cc28befef11c3142e6e0f82a1a9d3c3dc57a07d2 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 18:14:14 +0200 Subject: [PATCH 46/64] fluff --- src/doc/rustc-dev-guide/src/fuzzing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 6cbe3cdb43596..9f5360e1ecf34 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -133,7 +133,7 @@ Of course, it's best to try multiple build configurations and see what actually results in superior throughput. You may want to build rustc from source with debug assertions to find -additional bugs, though this is a trade-off: it can slow down fuzzing by +additional bugs, though this can slow down fuzzing by requiring extra work for every execution. To enable debug assertions, add this to `bootstrap.toml` when compiling rustc: From 86f18b3f8487d13fff27d70da46376f3fb98cbf8 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 18:15:07 +0200 Subject: [PATCH 47/64] use compact format, as this is what is in bootstrap.example.toml --- src/doc/rustc-dev-guide/src/fuzzing.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 9f5360e1ecf34..648fa351c8f53 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -138,8 +138,7 @@ requiring extra work for every execution. To enable debug assertions, add this to `bootstrap.toml` when compiling rustc: ```toml -[rust] -debug-assertions = true +rust.debug-assertions = true ``` ICEs that require debug assertions to reproduce should be tagged From da01b354cfa14ef69c43dd449341a3bcc8aa6521 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 18:18:39 +0200 Subject: [PATCH 48/64] redundant --- src/doc/rustc-dev-guide/src/fuzzing.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 648fa351c8f53..6ef8c31796394 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -36,7 +36,7 @@ project, please read this guide before reporting fuzzer-generated bugs! If you're not sure whether or not an ICE is a duplicate of one that's already been reported, please go ahead and report it and link to issues you think might be related. In general, ICEs on the same line but with different *query stacks* are usually distinct bugs. -For example, [#109020][#109020] and [#109129][#109129] had similar error messages: +For example, [#109020] and [#109129] had similar error messages: > error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead @@ -71,7 +71,7 @@ To build a corpus, you may want to use: - The rustc/rust-analyzer/clippy test suites (or even source code) --- though avoid tests that are already known to cause failures, which often begin with comments like `//@ failure-status: 101` or `//@ known-bug: #NNN`. -- The already-fixed ICEs in the archived [Glacier][glacier] repository --- though +- The already-fixed ICEs in the archived [Glacier] repository --- though avoid the unfixed ones in `ices/`! [glacier]: https://github.com/rust-lang/glacier @@ -142,9 +142,9 @@ rust.debug-assertions = true ``` ICEs that require debug assertions to reproduce should be tagged -[`requires-debug-assertions`][requires-debug-assertions]. +[`requires-debug-assertions`]. -[requires-debug-assertions]: https://github.com/rust-lang/rust/labels/requires-debug-assertions +[`requires-debug-assertions`]: https://github.com/rust-lang/rust/labels/requires-debug-assertions ## Existing projects From cc8cfcc187ef8a3e4bd26566b873c8866574085a Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 13 Dec 2025 18:26:45 +0200 Subject: [PATCH 49/64] fails link checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit error: Potential incomplete link ┌─ fuzzing.md:41:122 │ 41 │ > error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Did you forget to define a URL for `closure@src/main.rs:36:25: 36:28`? --- src/doc/rustc-dev-guide/src/fuzzing.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 6ef8c31796394..635c01d21aeec 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -38,9 +38,13 @@ been reported, please go ahead and report it and link to issues you think might In general, ICEs on the same line but with different *query stacks* are usually distinct bugs. For example, [#109020] and [#109129] had similar error messages: -> error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead +``` +error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <[closure@src/main.rs:36:25: 36:28] as std::ops::FnOnce<(Emplacable<()>,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead +``` -> error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <() as Project>::Assoc, maybe try to call `try_normalize_erasing_regions` instead +``` +error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:195:90: Failed to normalize <() as Project>::Assoc, maybe try to call `try_normalize_erasing_regions` instead +``` However, they have different query stacks: ``` From 0def1822a0a3f32d457644a4a8e2282d19eab071 Mon Sep 17 00:00:00 2001 From: Redddy Date: Sun, 14 Dec 2025 06:26:45 +0900 Subject: [PATCH 50/64] Updated titles and links for two references in the bibliography --- src/doc/rustc-dev-guide/src/appendix/bibliography.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/appendix/bibliography.md b/src/doc/rustc-dev-guide/src/appendix/bibliography.md index e862ac368475c..13a9c3a0b40bf 100644 --- a/src/doc/rustc-dev-guide/src/appendix/bibliography.md +++ b/src/doc/rustc-dev-guide/src/appendix/bibliography.md @@ -25,12 +25,12 @@ Rust, as well as publications about Rust. * [Contention aware scheduling](https://www.blagodurov.net/files/a8-blagodurov.pdf) * [Dynamic circular work stealing deque](https://patents.google.com/patent/US7346753B2/en) - The Chase/Lev deque * [Epoch-based reclamation](https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-579.pdf). -* [Language support for fast and reliable message passing in singularity OS](https://research.microsoft.com/pubs/67482/singsharp.pdf) +* [Language support for fast and reliable message-based communication in singularity OS](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/04/singsharp.pdf) * [Non-blocking steal-half work queues](https://www.cs.bgu.ac.il/%7Ehendlerd/papers/p280-hendler.pdf) * [Reagents: expressing and composing fine-grained concurrency](https://aturon.github.io/academic/reagents.pdf) * [Scheduling multithreaded computations by work stealing](https://www.lri.fr/~cecile/ENSEIGNEMENT/IPAR/Exposes/cilk1.pdf) * [Scheduling techniques for concurrent systems](https://www.stanford.edu/~ouster/cgi-bin/papers/coscheduling.pdf) -* [Singularity: rethinking the software stack](https://research.microsoft.com/pubs/69431/osr2007_rethinkingsoftwarestack.pdf) +* [Singularity: rethinking the software stack](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/osr2007_rethinkingsoftwarestack.pdf) * [The data locality of work stealing](http://www.aladdin.cs.cmu.edu/papers/pdfs/y2000/locality_spaa00.pdf) * [Thread scheduling for multiprogramming multiprocessors](https://dl.acm.org/doi/10.1145/277651.277678) * [Three layer cake for shared-memory programming](https://dl.acm.org/doi/10.1145/1953611.1953616) From 69ba7c5bd3208a1d1b026d8773bbfee8256a8e51 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sun, 14 Dec 2025 14:32:27 +0200 Subject: [PATCH 51/64] about-this-guide.md: make more clear My first thought seeing the sentence part of the list was that there was a missing hyperlink --- src/doc/rustc-dev-guide/src/about-this-guide.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 4f5733ae0821a..bf5cfe67fbc00 100644 --- a/src/doc/rustc-dev-guide/src/about-this-guide.md +++ b/src/doc/rustc-dev-guide/src/about-this-guide.md @@ -64,10 +64,12 @@ please see the corresponding [subsection on writing documentation in this guide] ## Other places to find information +This guide, the one you are currently reading, +contains information about how various parts of the compiler work, +and how to contribute to the compiler. + You might also find the following sites useful: -- This guide contains information about how various parts of the - compiler work and how to contribute to the compiler. - [rustc API docs] -- rustdoc documentation for the compiler, devtools, and internal tools - [Forge] -- contains documentation about Rust infrastructure, team procedures, and more - [compiler-team] -- the home-base for the Rust compiler team, with description From 164eec7f93ca4eecfbfdfb582862ce8602b0000c Mon Sep 17 00:00:00 2001 From: Redddy Date: Sun, 14 Dec 2025 23:13:58 +0900 Subject: [PATCH 52/64] Add rust-analyzer book link to the guide --- src/doc/rustc-dev-guide/src/about-this-guide.md | 2 ++ 1 file changed, 2 insertions(+) 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 4f5733ae0821a..782bd313b29e2 100644 --- a/src/doc/rustc-dev-guide/src/about-this-guide.md +++ b/src/doc/rustc-dev-guide/src/about-this-guide.md @@ -73,6 +73,7 @@ You might also find the following sites useful: - [compiler-team] -- the home-base for the Rust compiler team, with description of the team procedures, active working groups, and the team calendar. - [std-dev-guide] -- a similar guide for developing the standard library. +- [rust-analyzer book][r-a book] -- documentation for the rust-analyzer. - [The t-compiler Zulip][z] - The [Rust Internals forum][rif], a place to ask questions and discuss Rust's internals @@ -110,4 +111,5 @@ You might also find the following sites useful: [Forge]: https://forge.rust-lang.org/ [compiler-team]: https://github.com/rust-lang/compiler-team/ [std-dev-guide]: https://std-dev-guide.rust-lang.org/ +[r-a book]: https://rust-analyzer.github.io/book/ [z]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler From a56a4fff27babc71bc9649641a2aa2281a74ec7e Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sun, 14 Dec 2025 22:25:39 +0200 Subject: [PATCH 53/64] less text for same effect --- src/doc/rustc-dev-guide/src/about-this-guide.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 782bd313b29e2..69951a7fd8478 100644 --- a/src/doc/rustc-dev-guide/src/about-this-guide.md +++ b/src/doc/rustc-dev-guide/src/about-this-guide.md @@ -58,7 +58,7 @@ please see the corresponding [subsection on writing documentation in this guide] [subsection on writing documentation in this guide]: contributing.md#contributing-to-rustc-dev-guide -> “‘All conditioned things are impermanent’ — +> “‘All conditioned things are impermanent’ — > when one sees this with wisdom, one turns away from suffering.” > _The Dhammapada, verse 277_ @@ -73,7 +73,7 @@ You might also find the following sites useful: - [compiler-team] -- the home-base for the Rust compiler team, with description of the team procedures, active working groups, and the team calendar. - [std-dev-guide] -- a similar guide for developing the standard library. -- [rust-analyzer book][r-a book] -- documentation for the rust-analyzer. +- [rust-analyzer book] -- documentation for the rust-analyzer. - [The t-compiler Zulip][z] - The [Rust Internals forum][rif], a place to ask questions and discuss Rust's internals @@ -111,5 +111,5 @@ You might also find the following sites useful: [Forge]: https://forge.rust-lang.org/ [compiler-team]: https://github.com/rust-lang/compiler-team/ [std-dev-guide]: https://std-dev-guide.rust-lang.org/ -[r-a book]: https://rust-analyzer.github.io/book/ +[rust-analyzer book]: https://rust-analyzer.github.io/book/ [z]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler From 1bd997a4520e5712ab17a4cbc12624a0620b3836 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Wed, 10 Dec 2025 10:52:37 +0900 Subject: [PATCH 54/64] Cleaned up some tests Split invalid-compile-flags into run-pass & invalid Update tests/ui/README.md --- tests/ui/README.md | 22 ++++++++++++------- tests/ui/borrowck/return-ref-to-temporary.rs | 3 ++- .../borrowck/return-ref-to-temporary.stderr | 2 +- .../closures/closure-upvar-trait-caching.rs | 5 +++-- tests/ui/closures/nested-closure-call.rs | 3 ++- ...protection-missing-pac-ret.BADFLAGS.stderr | 0 ...otection-missing-pac-ret.BADFLAGSPC.stderr | 0 ...rotection-missing-pac-ret.BADTARGET.stderr | 0 .../branch-protection-missing-pac-ret.rs | 0 .../invalid}/codegen-option-without-group.rs | 0 .../codegen-option-without-group.stderr | 0 .../crate-type-flag.empty_crate_type.stderr | 0 ...ate-type-flag.proc_underscore_macro.stderr | 0 .../invalid}/crate-type-flag.rs | 0 .../invalid}/crate-type-flag.unknown.stderr | 0 .../invalid}/debug-option-without-group.rs | 0 .../debug-option-without-group.stderr | 0 .../emit-output-types-without-args.rs | 0 .../emit-output-types-without-args.stderr | 0 .../requires-x86-or-x86_64.aarch64.stderr | 0 .../function-return/requires-x86-or-x86_64.rs | 0 ...requires-non-large-code-model.large.stderr | 0 ...nk-extern-requires-non-large-code-model.rs | 0 .../requires-x86-or-x86_64.aarch64.stderr | 0 .../requires-x86-or-x86_64.rs | 0 .../invalid}/invalid-llvm-passes.rs | 0 .../invalid}/invalid-llvm-passes.stderr | 0 .../invalid}/need-crate-arg-ignore-tidy$x.rs | 0 .../need-crate-arg-ignore-tidy$x.stderr | 0 ...crate-name-request-malformed-crate-name.rs | 0 ...e-name-request-malformed-crate-name.stderr | 0 ...le-names-request-malformed-crate-name-1.rs | 0 ...ames-request-malformed-crate-name-1.stderr | 0 ...le-names-request-malformed-crate-name-2.rs | 0 ...ames-request-malformed-crate-name-2.stderr | 0 ...file-names-request-malformed-crate-name.rs | 0 ...-names-request-malformed-crate-name.stderr | 0 .../invalid}/print-without-arg.rs | 0 .../invalid}/print-without-arg.stderr | 0 .../invalid}/print.rs | 0 .../invalid}/print.stderr | 0 .../requires-x86.aarch64.stderr | 0 .../reg-struct-return/requires-x86.rs | 0 .../requires-x86.x86_64.stderr | 0 .../regparm-valid-values.regparm4.stderr | 0 .../invalid}/regparm/regparm-valid-values.rs | 0 .../regparm/requires-x86.aarch64.stderr | 0 .../invalid}/regparm/requires-x86.rs | 0 .../regparm/requires-x86.x86_64.stderr | 0 .../run-pass}/repeated-debug-opt-flags.rs | 1 + tests/ui/enum/enum-variant-no-field.rs | 5 ++++- tests/ui/enum/enum-variant-no-field.stderr | 2 +- .../ui/enum/enum-with-uninhabited-variant.rs | 3 ++- tests/ui/expr/return-in-block-tuple.rs | 3 ++- tests/ui/extern/extern-rust-trait-method.rs | 1 + tests/ui/fmt/println-float.rs | 1 + tests/ui/indexing/ref-array-indexing.rs | 5 +++-- tests/ui/issues/issue-21449.rs | 6 ----- tests/ui/issues/issue-21449.stderr | 9 -------- tests/ui/issues/issue-23189.rs | 5 ----- tests/ui/issues/issue-23189.stderr | 9 -------- .../trait-method-lifetime-suggestion.rs | 5 +++-- .../trait-method-lifetime-suggestion.stderr | 2 +- tests/ui/lint/lint-missing-doc-crate-attr.rs | 4 ++++ ...err => lint-missing-doc-crate-attr.stderr} | 9 ++++---- .../lint/lint-missing-doc-crate-flags.stderr | 2 +- tests/ui/lint/lint-missing-docs-crate-attr.rs | 3 --- tests/ui/macros/undefined-macro-in-impl.rs | 1 + .../ui/macros/undefined-macro-in-impl.stderr | 2 +- .../match/match-const-tuple-type-mismatch.rs | 17 +++++++------- .../match-const-tuple-type-mismatch.stderr | 21 +++++++++--------- tests/ui/match/match-range-char-const.rs | 3 ++- tests/ui/match/match-static-pattern.rs | 5 +++-- tests/ui/match/match-static-pattern.stderr | 4 ++-- tests/ui/moves/array-copy-move.rs | 1 + tests/ui/never_type/never-deref.rs | 1 + tests/ui/never_type/never-deref.stderr | 2 +- .../parser/cast-angle-bracket-precedence.rs | 2 ++ .../cast-angle-bracket-precedence.stderr | 12 +++++----- .../pattern/match-at-pattern-shadows-name.rs | 4 +++- .../match-at-pattern-shadows-name.stderr | 4 ++-- .../module-used-as-struct-constructor.rs | 1 + .../module-used-as-struct-constructor.stderr | 2 +- .../shadowed/match-binding-shadows-const.rs | 1 + .../match-binding-shadows-const.stderr | 2 +- tests/ui/statics/static-mut-unsafe-init.rs | 7 +++--- .../ui/threads-sendsync/thread-join-unwrap.rs | 3 +-- .../ui/trait-bounds/sort-missing-ord-bound.rs | 5 ++++- .../sort-missing-ord-bound.stderr | 4 ++-- .../solver-cycles/assoc-equality-cycle.rs | 5 +++-- .../solver-cycles/assoc-equality-cycle.stderr | 8 +++---- .../traits/solver-cycles/self-item-cycle.rs | 7 +++--- .../solver-cycles/self-item-cycle.stderr | 12 +++++----- tests/ui/typeck/missing-type-annotation.rs | 1 + .../ui/typeck/missing-type-annotation.stderr | 2 +- tests/ui/typeck/osstring-str-equality.rs | 1 + .../return-expression-invalid-callee.rs | 9 ++++---- .../return-expression-invalid-callee.stderr | 6 ++--- 98 files changed, 139 insertions(+), 126 deletions(-) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/branch-protection-missing-pac-ret.BADFLAGS.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/branch-protection-missing-pac-ret.BADFLAGSPC.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/branch-protection-missing-pac-ret.BADTARGET.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/branch-protection-missing-pac-ret.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/codegen-option-without-group.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/codegen-option-without-group.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/crate-type-flag.empty_crate_type.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/crate-type-flag.proc_underscore_macro.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/crate-type-flag.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/crate-type-flag.unknown.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/debug-option-without-group.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/debug-option-without-group.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/emit-output-types-without-args.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/emit-output-types-without-args.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/function-return/requires-x86-or-x86_64.aarch64.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/function-return/requires-x86-or-x86_64.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/function-return/thunk-extern-requires-non-large-code-model.large.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/function-return/thunk-extern-requires-non-large-code-model.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/invalid-llvm-passes.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/invalid-llvm-passes.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/need-crate-arg-ignore-tidy$x.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/need-crate-arg-ignore-tidy$x.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-crate-name-request-malformed-crate-name.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-crate-name-request-malformed-crate-name.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-file-names-request-malformed-crate-name-1.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-file-names-request-malformed-crate-name-1.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-file-names-request-malformed-crate-name-2.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-file-names-request-malformed-crate-name-2.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-file-names-request-malformed-crate-name.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-file-names-request-malformed-crate-name.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-without-arg.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print-without-arg.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/print.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/reg-struct-return/requires-x86.aarch64.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/reg-struct-return/requires-x86.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/reg-struct-return/requires-x86.x86_64.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/regparm/regparm-valid-values.regparm4.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/regparm/regparm-valid-values.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/regparm/requires-x86.aarch64.stderr (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/regparm/requires-x86.rs (100%) rename tests/ui/{invalid-compile-flags => compile-flags/invalid}/regparm/requires-x86.x86_64.stderr (100%) rename tests/ui/{codegen => compile-flags/run-pass}/repeated-debug-opt-flags.rs (72%) delete mode 100644 tests/ui/issues/issue-21449.rs delete mode 100644 tests/ui/issues/issue-21449.stderr delete mode 100644 tests/ui/issues/issue-23189.rs delete mode 100644 tests/ui/issues/issue-23189.stderr create mode 100644 tests/ui/lint/lint-missing-doc-crate-attr.rs rename tests/ui/lint/{lint-missing-docs-crate-attr.stderr => lint-missing-doc-crate-attr.stderr} (58%) delete mode 100644 tests/ui/lint/lint-missing-docs-crate-attr.rs diff --git a/tests/ui/README.md b/tests/ui/README.md index 25e870fd8f188..ca9f89f002ee4 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -256,6 +256,10 @@ Some traits' implementation must be compared with their definition, checking for This subdirectory is *not* intended comparison traits (`PartialEq`, `Eq`, `PartialOrd`, `Ord`). +## `tests/ui/compile-flags/` + +Tests for compile flags. + ## `tests/ui/compiletest-self-test/`: compiletest "meta" tests Meta test suite of the test harness `compiletest` itself. @@ -548,6 +552,8 @@ A broad directory for tests on expressions. Tests on the `extern` keyword and `extern` blocks and functions. +**FIXME**: Merge with `tests/ui/abi/extern`. + ## `tests/ui/extern-flag/`: `--extern` command line flag Tests for the `--extern` CLI flag. @@ -556,6 +562,12 @@ Tests for the `--extern` CLI flag. Tests on feature-gating, and the `#![feature(..)]` mechanism itself. +## `tests/ui/ffi/`: Foreign Function Interface + +Tests for the `std::ffi` module. + +See [`std::ffi`](https://doc.rust-lang.org/std/ffi/index.html) + ## `tests/ui/ffi-attrs/`: `#![feature(ffi_const, ffi_pure)]` The `#[ffi_const]` and `#[ffi_pure]` attributes applies clang's `const` and `pure` attributes to foreign functions declarations, respectively. These attributes are the core element of the tests in this category. @@ -733,15 +745,9 @@ Various tests related to rejecting invalid inputs. **FIXME**: This is rather uninformative, possibly rehome into more meaningful directories. -## `tests/ui/invalid-compile-flags/` - -Tests for checking that invalid usage of compiler flags are rejected. - -## `tests/ui/io-checks/` - -Contains a single test. The test tries to output a file into an invalid directory with `-o`, then checks that the result is an error, not an internal compiler error. +## `tests/ui/io-checks/`: Input Output -**FIXME**: Rehome to invalid compiler flags maybe. +Tests for I/O related behaviour, covering stdout/stderr handling and error propagation. ## `tests/ui/issues/`: Tests directly related to GitHub issues diff --git a/tests/ui/borrowck/return-ref-to-temporary.rs b/tests/ui/borrowck/return-ref-to-temporary.rs index b9e20e8dbcb5f..90609b8d6da6d 100644 --- a/tests/ui/borrowck/return-ref-to-temporary.rs +++ b/tests/ui/borrowck/return-ref-to-temporary.rs @@ -1,6 +1,7 @@ +//! regression test for issue https://github.com/rust-lang/rust/issues/46472 fn bar<'a>() -> &'a mut u32 { &mut 4 //~^ ERROR cannot return reference to temporary value [E0515] } -fn main() { } +fn main() {} diff --git a/tests/ui/borrowck/return-ref-to-temporary.stderr b/tests/ui/borrowck/return-ref-to-temporary.stderr index 6115da28cc91c..85faf0a9e3758 100644 --- a/tests/ui/borrowck/return-ref-to-temporary.stderr +++ b/tests/ui/borrowck/return-ref-to-temporary.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return reference to temporary value - --> $DIR/issue-46472.rs:2:5 + --> $DIR/return-ref-to-temporary.rs:3:5 | LL | &mut 4 | ^^^^^- diff --git a/tests/ui/closures/closure-upvar-trait-caching.rs b/tests/ui/closures/closure-upvar-trait-caching.rs index d2a6862e05c4f..82588631c99c3 100644 --- a/tests/ui/closures/closure-upvar-trait-caching.rs +++ b/tests/ui/closures/closure-upvar-trait-caching.rs @@ -7,8 +7,9 @@ // reasonable examples) let to ambiguity errors about not being able // to infer sufficient type information. - fn main() { let n = 0; - let it = Some(1_usize).into_iter().inspect(|_| {n;}); + let it = Some(1_usize).into_iter().inspect(|_| { + n; + }); } diff --git a/tests/ui/closures/nested-closure-call.rs b/tests/ui/closures/nested-closure-call.rs index f371828606c4b..9d0860167a1ac 100644 --- a/tests/ui/closures/nested-closure-call.rs +++ b/tests/ui/closures/nested-closure-call.rs @@ -1,4 +1,5 @@ +//! regression test for https://github.com/rust-lang/rust/issues/24779 //@ run-pass fn main() { - assert_eq!((||||42)()(), 42); + assert_eq!((|| || 42)()(), 42); } diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGS.stderr b/tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADFLAGS.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGS.stderr rename to tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADFLAGS.stderr diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGSPC.stderr b/tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADFLAGSPC.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGSPC.stderr rename to tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADFLAGSPC.stderr diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADTARGET.stderr b/tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADTARGET.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADTARGET.stderr rename to tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADTARGET.stderr diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs b/tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.rs similarity index 100% rename from tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs rename to tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.rs diff --git a/tests/ui/invalid-compile-flags/codegen-option-without-group.rs b/tests/ui/compile-flags/invalid/codegen-option-without-group.rs similarity index 100% rename from tests/ui/invalid-compile-flags/codegen-option-without-group.rs rename to tests/ui/compile-flags/invalid/codegen-option-without-group.rs diff --git a/tests/ui/invalid-compile-flags/codegen-option-without-group.stderr b/tests/ui/compile-flags/invalid/codegen-option-without-group.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/codegen-option-without-group.stderr rename to tests/ui/compile-flags/invalid/codegen-option-without-group.stderr diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr b/tests/ui/compile-flags/invalid/crate-type-flag.empty_crate_type.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr rename to tests/ui/compile-flags/invalid/crate-type-flag.empty_crate_type.stderr diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr b/tests/ui/compile-flags/invalid/crate-type-flag.proc_underscore_macro.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr rename to tests/ui/compile-flags/invalid/crate-type-flag.proc_underscore_macro.stderr diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.rs b/tests/ui/compile-flags/invalid/crate-type-flag.rs similarity index 100% rename from tests/ui/invalid-compile-flags/crate-type-flag.rs rename to tests/ui/compile-flags/invalid/crate-type-flag.rs diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr b/tests/ui/compile-flags/invalid/crate-type-flag.unknown.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr rename to tests/ui/compile-flags/invalid/crate-type-flag.unknown.stderr diff --git a/tests/ui/invalid-compile-flags/debug-option-without-group.rs b/tests/ui/compile-flags/invalid/debug-option-without-group.rs similarity index 100% rename from tests/ui/invalid-compile-flags/debug-option-without-group.rs rename to tests/ui/compile-flags/invalid/debug-option-without-group.rs diff --git a/tests/ui/invalid-compile-flags/debug-option-without-group.stderr b/tests/ui/compile-flags/invalid/debug-option-without-group.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/debug-option-without-group.stderr rename to tests/ui/compile-flags/invalid/debug-option-without-group.stderr diff --git a/tests/ui/invalid-compile-flags/emit-output-types-without-args.rs b/tests/ui/compile-flags/invalid/emit-output-types-without-args.rs similarity index 100% rename from tests/ui/invalid-compile-flags/emit-output-types-without-args.rs rename to tests/ui/compile-flags/invalid/emit-output-types-without-args.rs diff --git a/tests/ui/invalid-compile-flags/emit-output-types-without-args.stderr b/tests/ui/compile-flags/invalid/emit-output-types-without-args.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/emit-output-types-without-args.stderr rename to tests/ui/compile-flags/invalid/emit-output-types-without-args.stderr diff --git a/tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.aarch64.stderr b/tests/ui/compile-flags/invalid/function-return/requires-x86-or-x86_64.aarch64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.aarch64.stderr rename to tests/ui/compile-flags/invalid/function-return/requires-x86-or-x86_64.aarch64.stderr diff --git a/tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs b/tests/ui/compile-flags/invalid/function-return/requires-x86-or-x86_64.rs similarity index 100% rename from tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs rename to tests/ui/compile-flags/invalid/function-return/requires-x86-or-x86_64.rs diff --git a/tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.large.stderr b/tests/ui/compile-flags/invalid/function-return/thunk-extern-requires-non-large-code-model.large.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.large.stderr rename to tests/ui/compile-flags/invalid/function-return/thunk-extern-requires-non-large-code-model.large.stderr diff --git a/tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.rs b/tests/ui/compile-flags/invalid/function-return/thunk-extern-requires-non-large-code-model.rs similarity index 100% rename from tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.rs rename to tests/ui/compile-flags/invalid/function-return/thunk-extern-requires-non-large-code-model.rs diff --git a/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr b/tests/ui/compile-flags/invalid/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr rename to tests/ui/compile-flags/invalid/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr diff --git a/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs b/tests/ui/compile-flags/invalid/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs similarity index 100% rename from tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs rename to tests/ui/compile-flags/invalid/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs diff --git a/tests/ui/invalid-compile-flags/invalid-llvm-passes.rs b/tests/ui/compile-flags/invalid/invalid-llvm-passes.rs similarity index 100% rename from tests/ui/invalid-compile-flags/invalid-llvm-passes.rs rename to tests/ui/compile-flags/invalid/invalid-llvm-passes.rs diff --git a/tests/ui/invalid-compile-flags/invalid-llvm-passes.stderr b/tests/ui/compile-flags/invalid/invalid-llvm-passes.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/invalid-llvm-passes.stderr rename to tests/ui/compile-flags/invalid/invalid-llvm-passes.stderr diff --git a/tests/ui/invalid-compile-flags/need-crate-arg-ignore-tidy$x.rs b/tests/ui/compile-flags/invalid/need-crate-arg-ignore-tidy$x.rs similarity index 100% rename from tests/ui/invalid-compile-flags/need-crate-arg-ignore-tidy$x.rs rename to tests/ui/compile-flags/invalid/need-crate-arg-ignore-tidy$x.rs diff --git a/tests/ui/invalid-compile-flags/need-crate-arg-ignore-tidy$x.stderr b/tests/ui/compile-flags/invalid/need-crate-arg-ignore-tidy$x.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/need-crate-arg-ignore-tidy$x.stderr rename to tests/ui/compile-flags/invalid/need-crate-arg-ignore-tidy$x.stderr diff --git a/tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.rs b/tests/ui/compile-flags/invalid/print-crate-name-request-malformed-crate-name.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.rs rename to tests/ui/compile-flags/invalid/print-crate-name-request-malformed-crate-name.rs diff --git a/tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.stderr b/tests/ui/compile-flags/invalid/print-crate-name-request-malformed-crate-name.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.stderr rename to tests/ui/compile-flags/invalid/print-crate-name-request-malformed-crate-name.stderr diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.rs b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-1.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.rs rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-1.rs diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.stderr b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-1.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.stderr rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-1.stderr diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.rs b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-2.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.rs rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-2.rs diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.stderr b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-2.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.stderr rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-2.stderr diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.rs b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.rs rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name.rs diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.stderr b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.stderr rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name.stderr diff --git a/tests/ui/invalid-compile-flags/print-without-arg.rs b/tests/ui/compile-flags/invalid/print-without-arg.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-without-arg.rs rename to tests/ui/compile-flags/invalid/print-without-arg.rs diff --git a/tests/ui/invalid-compile-flags/print-without-arg.stderr b/tests/ui/compile-flags/invalid/print-without-arg.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-without-arg.stderr rename to tests/ui/compile-flags/invalid/print-without-arg.stderr diff --git a/tests/ui/invalid-compile-flags/print.rs b/tests/ui/compile-flags/invalid/print.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print.rs rename to tests/ui/compile-flags/invalid/print.rs diff --git a/tests/ui/invalid-compile-flags/print.stderr b/tests/ui/compile-flags/invalid/print.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print.stderr rename to tests/ui/compile-flags/invalid/print.stderr diff --git a/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.aarch64.stderr b/tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.aarch64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.aarch64.stderr rename to tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.aarch64.stderr diff --git a/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs b/tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.rs similarity index 100% rename from tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs rename to tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.rs diff --git a/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.x86_64.stderr b/tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.x86_64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.x86_64.stderr rename to tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.x86_64.stderr diff --git a/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.regparm4.stderr b/tests/ui/compile-flags/invalid/regparm/regparm-valid-values.regparm4.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/regparm-valid-values.regparm4.stderr rename to tests/ui/compile-flags/invalid/regparm/regparm-valid-values.regparm4.stderr diff --git a/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs b/tests/ui/compile-flags/invalid/regparm/regparm-valid-values.rs similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs rename to tests/ui/compile-flags/invalid/regparm/regparm-valid-values.rs diff --git a/tests/ui/invalid-compile-flags/regparm/requires-x86.aarch64.stderr b/tests/ui/compile-flags/invalid/regparm/requires-x86.aarch64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/requires-x86.aarch64.stderr rename to tests/ui/compile-flags/invalid/regparm/requires-x86.aarch64.stderr diff --git a/tests/ui/invalid-compile-flags/regparm/requires-x86.rs b/tests/ui/compile-flags/invalid/regparm/requires-x86.rs similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/requires-x86.rs rename to tests/ui/compile-flags/invalid/regparm/requires-x86.rs diff --git a/tests/ui/invalid-compile-flags/regparm/requires-x86.x86_64.stderr b/tests/ui/compile-flags/invalid/regparm/requires-x86.x86_64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/requires-x86.x86_64.stderr rename to tests/ui/compile-flags/invalid/regparm/requires-x86.x86_64.stderr diff --git a/tests/ui/codegen/repeated-debug-opt-flags.rs b/tests/ui/compile-flags/run-pass/repeated-debug-opt-flags.rs similarity index 72% rename from tests/ui/codegen/repeated-debug-opt-flags.rs rename to tests/ui/compile-flags/run-pass/repeated-debug-opt-flags.rs index 5d8044b0a1a06..d584ec9fd280d 100644 --- a/tests/ui/codegen/repeated-debug-opt-flags.rs +++ b/tests/ui/compile-flags/run-pass/repeated-debug-opt-flags.rs @@ -1,3 +1,4 @@ +//! regression test for https://github.com/rust-lang/rust/issues/24945 //@ run-pass // This test is just checking that we continue to accept `-g -g -O -O` // as options to the compiler. diff --git a/tests/ui/enum/enum-variant-no-field.rs b/tests/ui/enum/enum-variant-no-field.rs index b285cb81ee230..a69766b7c48d0 100644 --- a/tests/ui/enum/enum-variant-no-field.rs +++ b/tests/ui/enum/enum-variant-no-field.rs @@ -1,4 +1,7 @@ -enum Foo { Bar } +//! regression test for https://github.com/rust-lang/rust/issues/23253 +enum Foo { + Bar, +} fn main() { Foo::Bar.a; diff --git a/tests/ui/enum/enum-variant-no-field.stderr b/tests/ui/enum/enum-variant-no-field.stderr index ec7696909e725..4d02bf8761891 100644 --- a/tests/ui/enum/enum-variant-no-field.stderr +++ b/tests/ui/enum/enum-variant-no-field.stderr @@ -1,5 +1,5 @@ error[E0609]: no field `a` on type `Foo` - --> $DIR/issue-23253.rs:4:14 + --> $DIR/enum-variant-no-field.rs:7:14 | LL | Foo::Bar.a; | ^ unknown field diff --git a/tests/ui/enum/enum-with-uninhabited-variant.rs b/tests/ui/enum/enum-with-uninhabited-variant.rs index 70c764f33ddf9..8dfa492e6ea5c 100644 --- a/tests/ui/enum/enum-with-uninhabited-variant.rs +++ b/tests/ui/enum/enum-with-uninhabited-variant.rs @@ -1,3 +1,4 @@ +//! regression test for issue https://github.com/rust-lang/rust/issues/50442 //@ run-pass #![allow(dead_code)] enum Void {} @@ -5,7 +6,7 @@ enum Void {} enum Foo { A(i32), B(Void), - C(i32) + C(i32), } fn main() { diff --git a/tests/ui/expr/return-in-block-tuple.rs b/tests/ui/expr/return-in-block-tuple.rs index 6d563a5bae1c9..2b3a59f21412f 100644 --- a/tests/ui/expr/return-in-block-tuple.rs +++ b/tests/ui/expr/return-in-block-tuple.rs @@ -1,6 +1,7 @@ +//! regression test for https://github.com/rust-lang/rust/issues/18110 //@ run-pass #![allow(unreachable_code)] fn main() { - ({return},); + ({ return },); } diff --git a/tests/ui/extern/extern-rust-trait-method.rs b/tests/ui/extern/extern-rust-trait-method.rs index 473e43650c2c5..d71e5a8b6d532 100644 --- a/tests/ui/extern/extern-rust-trait-method.rs +++ b/tests/ui/extern/extern-rust-trait-method.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/19398 //@ check-pass trait T { diff --git a/tests/ui/fmt/println-float.rs b/tests/ui/fmt/println-float.rs index 18c8c756f32e3..3adb0b4343496 100644 --- a/tests/ui/fmt/println-float.rs +++ b/tests/ui/fmt/println-float.rs @@ -1,3 +1,4 @@ +//! regression test for https://github.com/rust-lang/rust/issues/11382 //@ run-pass fn main() { println!("{}", 1.2); diff --git a/tests/ui/indexing/ref-array-indexing.rs b/tests/ui/indexing/ref-array-indexing.rs index 9f54d4258bf1d..302255798df2d 100644 --- a/tests/ui/indexing/ref-array-indexing.rs +++ b/tests/ui/indexing/ref-array-indexing.rs @@ -1,5 +1,6 @@ +//! regression test for https://github.com/rust-lang/rust/issues/43205 //@ run-pass fn main() { - let _ = &&[()][0]; - println!("{:?}", &[(),()][1]); + let _ = &&[()][0]; + println!("{:?}", &[(), ()][1]); } diff --git a/tests/ui/issues/issue-21449.rs b/tests/ui/issues/issue-21449.rs deleted file mode 100644 index 00ce2b7fffa88..0000000000000 --- a/tests/ui/issues/issue-21449.rs +++ /dev/null @@ -1,6 +0,0 @@ -mod MyMod {} - -fn main() { - let myVar = MyMod { T: 0 }; - //~^ ERROR expected struct, variant or union type, found module `MyMod` -} diff --git a/tests/ui/issues/issue-21449.stderr b/tests/ui/issues/issue-21449.stderr deleted file mode 100644 index cd1059d48993a..0000000000000 --- a/tests/ui/issues/issue-21449.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0574]: expected struct, variant or union type, found module `MyMod` - --> $DIR/issue-21449.rs:4:17 - | -LL | let myVar = MyMod { T: 0 }; - | ^^^^^ not a struct, variant or union type - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0574`. diff --git a/tests/ui/issues/issue-23189.rs b/tests/ui/issues/issue-23189.rs deleted file mode 100644 index e5526357cb0ef..0000000000000 --- a/tests/ui/issues/issue-23189.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod module {} - -fn main() { - let _ = module { x: 0 }; //~ERROR expected struct -} diff --git a/tests/ui/issues/issue-23189.stderr b/tests/ui/issues/issue-23189.stderr deleted file mode 100644 index 37d778dc992eb..0000000000000 --- a/tests/ui/issues/issue-23189.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0574]: expected struct, variant or union type, found module `module` - --> $DIR/issue-23189.rs:4:13 - | -LL | let _ = module { x: 0 }; - | ^^^^^^ not a struct, variant or union type - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0574`. diff --git a/tests/ui/lifetimes/trait-method-lifetime-suggestion.rs b/tests/ui/lifetimes/trait-method-lifetime-suggestion.rs index e2ee84694e390..39cf4ae641857 100644 --- a/tests/ui/lifetimes/trait-method-lifetime-suggestion.rs +++ b/tests/ui/lifetimes/trait-method-lifetime-suggestion.rs @@ -1,5 +1,6 @@ -// Test that regionck suggestions in a provided method of a trait -// don't ICE +//! regression test for https://github.com/rust-lang/rust/issues/17758 +//! Test that regionck suggestions in a provided method of a trait +//! don't ICE trait Foo<'a> { fn foo(&'a self); diff --git a/tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr b/tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr index 7a7d2374ef879..64347577d0704 100644 --- a/tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr +++ b/tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/issue-17758.rs:7:9 + --> $DIR/trait-method-lifetime-suggestion.rs:8:9 | LL | trait Foo<'a> { | -- lifetime `'a` defined here diff --git a/tests/ui/lint/lint-missing-doc-crate-attr.rs b/tests/ui/lint/lint-missing-doc-crate-attr.rs new file mode 100644 index 0000000000000..51959785c53bd --- /dev/null +++ b/tests/ui/lint/lint-missing-doc-crate-attr.rs @@ -0,0 +1,4 @@ +// regression test for https://github.com/rust-lang/rust/issues/10656 +#![deny(missing_docs)] +//~^ ERROR missing documentation for the crate +#![crate_type = "lib"] diff --git a/tests/ui/lint/lint-missing-docs-crate-attr.stderr b/tests/ui/lint/lint-missing-doc-crate-attr.stderr similarity index 58% rename from tests/ui/lint/lint-missing-docs-crate-attr.stderr rename to tests/ui/lint/lint-missing-doc-crate-attr.stderr index 61828f9c02a6c..caff87df664b3 100644 --- a/tests/ui/lint/lint-missing-docs-crate-attr.stderr +++ b/tests/ui/lint/lint-missing-doc-crate-attr.stderr @@ -1,12 +1,13 @@ error: missing documentation for the crate - --> $DIR/issue-10656.rs:1:1 + --> $DIR/lint-missing-doc-crate-attr.rs:2:1 | LL | / #![deny(missing_docs)] -LL | | #![crate_type="lib"] - | |____________________^ +LL | | +LL | | #![crate_type = "lib"] + | |______________________^ | note: the lint level is defined here - --> $DIR/issue-10656.rs:1:9 + --> $DIR/lint-missing-doc-crate-attr.rs:2:9 | LL | #![deny(missing_docs)] | ^^^^^^^^^^^^ diff --git a/tests/ui/lint/lint-missing-doc-crate-flags.stderr b/tests/ui/lint/lint-missing-doc-crate-flags.stderr index 8efd3a17263fe..040d60a56ebf0 100644 --- a/tests/ui/lint/lint-missing-doc-crate-flags.stderr +++ b/tests/ui/lint/lint-missing-doc-crate-flags.stderr @@ -1,5 +1,5 @@ error: missing documentation for the crate - --> $DIR/lint-missing-doc-crate.rs:4:47 + --> $DIR/lint-missing-doc-crate-flags.rs:4:47 | LL | | ^ diff --git a/tests/ui/lint/lint-missing-docs-crate-attr.rs b/tests/ui/lint/lint-missing-docs-crate-attr.rs deleted file mode 100644 index 250c4bc442f98..0000000000000 --- a/tests/ui/lint/lint-missing-docs-crate-attr.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![deny(missing_docs)] -#![crate_type="lib"] -//~^^ ERROR missing documentation for the crate diff --git a/tests/ui/macros/undefined-macro-in-impl.rs b/tests/ui/macros/undefined-macro-in-impl.rs index fe4a327aef49c..64b394f984be0 100644 --- a/tests/ui/macros/undefined-macro-in-impl.rs +++ b/tests/ui/macros/undefined-macro-in-impl.rs @@ -1,3 +1,4 @@ +//! regression test for https://github.com/rust-lang/rust/issues/19734 fn main() {} struct Type; diff --git a/tests/ui/macros/undefined-macro-in-impl.stderr b/tests/ui/macros/undefined-macro-in-impl.stderr index ed48714fe5078..8d1bd958d7f6a 100644 --- a/tests/ui/macros/undefined-macro-in-impl.stderr +++ b/tests/ui/macros/undefined-macro-in-impl.stderr @@ -1,5 +1,5 @@ error: cannot find macro `undef` in this scope - --> $DIR/issue-19734.rs:6:5 + --> $DIR/undefined-macro-in-impl.rs:7:5 | LL | undef!(); | ^^^^^ diff --git a/tests/ui/match/match-const-tuple-type-mismatch.rs b/tests/ui/match/match-const-tuple-type-mismatch.rs index 08539d6debd82..c9358e3d5faac 100644 --- a/tests/ui/match/match-const-tuple-type-mismatch.rs +++ b/tests/ui/match/match-const-tuple-type-mismatch.rs @@ -1,12 +1,13 @@ -// Regression test for issue #4968 - +//! Regression test for issue https://github.com/rust-lang/rust/issues/4968 //@ dont-require-annotations: NOTE -const A: (isize,isize) = (4,2); +const A: (isize, isize) = (4, 2); fn main() { - match 42 { A => () } - //~^ ERROR mismatched types - //~| NOTE expected type `{integer}` - //~| NOTE found tuple `(isize, isize)` - //~| NOTE expected integer, found `(isize, isize)` + match 42 { + A => (), + //~^ ERROR mismatched types + //~| NOTE expected type `{integer}` + //~| NOTE found tuple `(isize, isize)` + //~| NOTE expected integer, found `(isize, isize)` + } } diff --git a/tests/ui/match/match-const-tuple-type-mismatch.stderr b/tests/ui/match/match-const-tuple-type-mismatch.stderr index 2c1e1d7bfe5a1..e7dd97c4e9a60 100644 --- a/tests/ui/match/match-const-tuple-type-mismatch.stderr +++ b/tests/ui/match/match-const-tuple-type-mismatch.stderr @@ -1,16 +1,17 @@ error[E0308]: mismatched types - --> $DIR/issue-4968.rs:7:16 + --> $DIR/match-const-tuple-type-mismatch.rs:7:9 | -LL | const A: (isize,isize) = (4,2); - | ---------------------- constant defined here +LL | const A: (isize, isize) = (4, 2); + | ----------------------- constant defined here LL | fn main() { -LL | match 42 { A => () } - | -- ^ - | | | - | | expected integer, found `(isize, isize)` - | | `A` is interpreted as a constant, not a new binding - | | help: introduce a new binding instead: `other_a` - | this expression has type `{integer}` +LL | match 42 { + | -- this expression has type `{integer}` +LL | A => (), + | ^ + | | + | expected integer, found `(isize, isize)` + | `A` is interpreted as a constant, not a new binding + | help: introduce a new binding instead: `other_a` | = note: expected type `{integer}` found tuple `(isize, isize)` diff --git a/tests/ui/match/match-range-char-const.rs b/tests/ui/match/match-range-char-const.rs index 9950647198395..84881fd56cc0f 100644 --- a/tests/ui/match/match-range-char-const.rs +++ b/tests/ui/match/match-range-char-const.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/18464 //@ run-pass #![deny(dead_code)] @@ -7,6 +8,6 @@ const HIGH_RANGE: char = '9'; fn main() { match '5' { LOW_RANGE..=HIGH_RANGE => (), - _ => () + _ => (), }; } diff --git a/tests/ui/match/match-static-pattern.rs b/tests/ui/match/match-static-pattern.rs index 6da4e6e15284b..5d367f9ec17c7 100644 --- a/tests/ui/match/match-static-pattern.rs +++ b/tests/ui/match/match-static-pattern.rs @@ -1,9 +1,10 @@ +//! regression test for issue https://github.com/rust-lang/rust/issues/17933 pub static X: usize = 1; fn main() { match 1 { - self::X => { }, + self::X => {} //~^ ERROR expected unit struct, unit variant or constant, found static `self::X` - _ => { }, + _ => {} } } diff --git a/tests/ui/match/match-static-pattern.stderr b/tests/ui/match/match-static-pattern.stderr index 42a7e04420735..1b111fbcc2dec 100644 --- a/tests/ui/match/match-static-pattern.stderr +++ b/tests/ui/match/match-static-pattern.stderr @@ -1,7 +1,7 @@ error[E0532]: expected unit struct, unit variant or constant, found static `self::X` - --> $DIR/issue-17933.rs:5:9 + --> $DIR/match-static-pattern.rs:6:9 | -LL | self::X => { }, +LL | self::X => {} | ^^^^^^^ not a unit struct, unit variant or constant error: aborting due to 1 previous error diff --git a/tests/ui/moves/array-copy-move.rs b/tests/ui/moves/array-copy-move.rs index 2ecc42b579d50..ea95bc06a3693 100644 --- a/tests/ui/moves/array-copy-move.rs +++ b/tests/ui/moves/array-copy-move.rs @@ -1,3 +1,4 @@ +//! regression test for issue https://github.com/rust-lang/rust/issues/16783 //@ run-pass #![allow(unused_variables)] diff --git a/tests/ui/never_type/never-deref.rs b/tests/ui/never_type/never-deref.rs index dc3be48a7ead7..6e4b89db04a54 100644 --- a/tests/ui/never_type/never-deref.rs +++ b/tests/ui/never_type/never-deref.rs @@ -1,3 +1,4 @@ +//! regression test for https://github.com/rust-lang/rust/issues/17373 fn main() { *return //~ ERROR type `!` cannot be dereferenced ; diff --git a/tests/ui/never_type/never-deref.stderr b/tests/ui/never_type/never-deref.stderr index 0e16d08c87d34..76f31f3779878 100644 --- a/tests/ui/never_type/never-deref.stderr +++ b/tests/ui/never_type/never-deref.stderr @@ -1,5 +1,5 @@ error[E0614]: type `!` cannot be dereferenced - --> $DIR/issue-17373.rs:2:5 + --> $DIR/never-deref.rs:3:5 | LL | *return | ^^^^^^^ can't be dereferenced diff --git a/tests/ui/parser/cast-angle-bracket-precedence.rs b/tests/ui/parser/cast-angle-bracket-precedence.rs index e3ada65049d56..65b598d03bdef 100644 --- a/tests/ui/parser/cast-angle-bracket-precedence.rs +++ b/tests/ui/parser/cast-angle-bracket-precedence.rs @@ -1,3 +1,5 @@ +//! regression test for https://github.com/rust-lang/rust/issues/22644 + fn main() { let a: usize = 0; let long_name: usize = 0; diff --git a/tests/ui/parser/cast-angle-bracket-precedence.stderr b/tests/ui/parser/cast-angle-bracket-precedence.stderr index c6d41cc856dd4..975bfea9425aa 100644 --- a/tests/ui/parser/cast-angle-bracket-precedence.stderr +++ b/tests/ui/parser/cast-angle-bracket-precedence.stderr @@ -1,5 +1,5 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:6:31 + --> $DIR/cast-angle-bracket-precedence.rs:8:31 | LL | println!("{}", a as usize < long_name); | ^ --------- interpreted as generic arguments @@ -12,7 +12,7 @@ LL | println!("{}", (a as usize) < long_name); | + + error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:7:33 + --> $DIR/cast-angle-bracket-precedence.rs:9:33 | LL | println!("{}{}", a as usize < long_name, long_name); | ^ -------------------- interpreted as generic arguments @@ -25,7 +25,7 @@ LL | println!("{}{}", (a as usize) < long_name, long_name); | + + error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:9:31 + --> $DIR/cast-angle-bracket-precedence.rs:11:31 | LL | println!("{}", a as usize < 4); | ^ - interpreted as generic arguments @@ -38,7 +38,7 @@ LL | println!("{}", (a as usize) < 4); | + + error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:14:20 + --> $DIR/cast-angle-bracket-precedence.rs:16:20 | LL | < | ^ not interpreted as comparison @@ -53,7 +53,7 @@ LL ~ usize) | error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:23:20 + --> $DIR/cast-angle-bracket-precedence.rs:25:20 | LL | < | ^ not interpreted as comparison @@ -70,7 +70,7 @@ LL ~ usize) | error: `<<` is interpreted as a start of generic arguments for `usize`, not a shift - --> $DIR/issue-22644.rs:26:31 + --> $DIR/cast-angle-bracket-precedence.rs:28:31 | LL | println!("{}", a as usize << long_name); | ^^ --------- interpreted as generic arguments diff --git a/tests/ui/pattern/match-at-pattern-shadows-name.rs b/tests/ui/pattern/match-at-pattern-shadows-name.rs index a23819a20f9aa..3cd2040c9fafa 100644 --- a/tests/ui/pattern/match-at-pattern-shadows-name.rs +++ b/tests/ui/pattern/match-at-pattern-shadows-name.rs @@ -1,10 +1,12 @@ +//! regression test for https://github.com/rust-lang/rust/issues/27033 fn main() { match Some(1) { None @ _ => {} //~ ERROR match bindings cannot shadow unit variants }; const C: u8 = 1; match 1 { - C @ 2 => { //~ ERROR match bindings cannot shadow constant + C @ 2 => { + //~^ ERROR match bindings cannot shadow constant println!("{}", C); } _ => {} diff --git a/tests/ui/pattern/match-at-pattern-shadows-name.stderr b/tests/ui/pattern/match-at-pattern-shadows-name.stderr index 129870f8c4098..6e2fbf546e82d 100644 --- a/tests/ui/pattern/match-at-pattern-shadows-name.stderr +++ b/tests/ui/pattern/match-at-pattern-shadows-name.stderr @@ -1,5 +1,5 @@ error[E0530]: match bindings cannot shadow unit variants - --> $DIR/issue-27033.rs:3:9 + --> $DIR/match-at-pattern-shadows-name.rs:4:9 | LL | None @ _ => {} | ^^^^ cannot be named the same as a unit variant @@ -9,7 +9,7 @@ LL | None @ _ => {} = note: the unit variant `None` is defined here error[E0530]: match bindings cannot shadow constants - --> $DIR/issue-27033.rs:7:9 + --> $DIR/match-at-pattern-shadows-name.rs:8:9 | LL | const C: u8 = 1; | ---------------- the constant `C` is defined here diff --git a/tests/ui/resolve/module-used-as-struct-constructor.rs b/tests/ui/resolve/module-used-as-struct-constructor.rs index 68cb2865fdc82..bdc7b2bf5841f 100644 --- a/tests/ui/resolve/module-used-as-struct-constructor.rs +++ b/tests/ui/resolve/module-used-as-struct-constructor.rs @@ -1,3 +1,4 @@ +//! regression test for https://github.com/rust-lang/rust/issues/17001, https://github.com/rust-lang/rust/issues/21449, https://github.com/rust-lang/rust/issues/23189 mod foo {} fn main() { diff --git a/tests/ui/resolve/module-used-as-struct-constructor.stderr b/tests/ui/resolve/module-used-as-struct-constructor.stderr index 6ea32e0a45c39..b94a28762a7f8 100644 --- a/tests/ui/resolve/module-used-as-struct-constructor.stderr +++ b/tests/ui/resolve/module-used-as-struct-constructor.stderr @@ -1,5 +1,5 @@ error[E0574]: expected struct, variant or union type, found module `foo` - --> $DIR/issue-17001.rs:4:13 + --> $DIR/module-used-as-struct-constructor.rs:5:13 | LL | let p = foo { x: () }; | ^^^ not a struct, variant or union type diff --git a/tests/ui/shadowed/match-binding-shadows-const.rs b/tests/ui/shadowed/match-binding-shadows-const.rs index 55196177f6934..95f2e087b5e7f 100644 --- a/tests/ui/shadowed/match-binding-shadows-const.rs +++ b/tests/ui/shadowed/match-binding-shadows-const.rs @@ -1,3 +1,4 @@ +//! regression test for https://github.com/rust-lang/rust/issues/34047 const C: u8 = 0; fn main() { diff --git a/tests/ui/shadowed/match-binding-shadows-const.stderr b/tests/ui/shadowed/match-binding-shadows-const.stderr index 97b1230ce3509..345c67700e626 100644 --- a/tests/ui/shadowed/match-binding-shadows-const.stderr +++ b/tests/ui/shadowed/match-binding-shadows-const.stderr @@ -1,5 +1,5 @@ error[E0530]: match bindings cannot shadow constants - --> $DIR/issue-34047.rs:5:13 + --> $DIR/match-binding-shadows-const.rs:6:13 | LL | const C: u8 = 0; | ---------------- the constant `C` is defined here diff --git a/tests/ui/statics/static-mut-unsafe-init.rs b/tests/ui/statics/static-mut-unsafe-init.rs index d8b20169ee0c4..ee8472100a08e 100644 --- a/tests/ui/statics/static-mut-unsafe-init.rs +++ b/tests/ui/statics/static-mut-unsafe-init.rs @@ -1,7 +1,8 @@ +//! regression test for https://github.com/rust-lang/rust/issues/17450 //@ build-pass -#![allow(dead_code, warnings)] +#![allow(dead_code)] -static mut x: isize = 3; -static mut y: isize = unsafe { x }; +static mut X: isize = 3; +static mut Y: isize = unsafe { X }; fn main() {} diff --git a/tests/ui/threads-sendsync/thread-join-unwrap.rs b/tests/ui/threads-sendsync/thread-join-unwrap.rs index 06f50ac6996df..6288e15b18741 100644 --- a/tests/ui/threads-sendsync/thread-join-unwrap.rs +++ b/tests/ui/threads-sendsync/thread-join-unwrap.rs @@ -1,8 +1,7 @@ +//! Regression test for unwrapping the result of `join`, issue https://github.com/rust-lang/rust/issues/21291 //@ run-pass //@ needs-threads -// Regression test for unwrapping the result of `join`, issue #21291 - use std::thread; fn main() { diff --git a/tests/ui/trait-bounds/sort-missing-ord-bound.rs b/tests/ui/trait-bounds/sort-missing-ord-bound.rs index b491bc37f5153..8d4ea88150175 100644 --- a/tests/ui/trait-bounds/sort-missing-ord-bound.rs +++ b/tests/ui/trait-bounds/sort-missing-ord-bound.rs @@ -1,4 +1,7 @@ -struct X { x: i32 } +//! regression test for issue https://github.com/rust-lang/rust/issues/20162 +struct X { + x: i32, +} fn main() { let mut b: Vec = vec![]; diff --git a/tests/ui/trait-bounds/sort-missing-ord-bound.stderr b/tests/ui/trait-bounds/sort-missing-ord-bound.stderr index 8f45f0d36c71e..c11781e5fff3f 100644 --- a/tests/ui/trait-bounds/sort-missing-ord-bound.stderr +++ b/tests/ui/trait-bounds/sort-missing-ord-bound.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `X: Ord` is not satisfied - --> $DIR/issue-20162.rs:5:7 + --> $DIR/sort-missing-ord-bound.rs:8:7 | LL | b.sort(); | ^^^^ the trait `Ord` is not implemented for `X` @@ -9,7 +9,7 @@ note: required by a bound in `slice::::sort` help: consider annotating `X` with `#[derive(Ord)]` | LL + #[derive(Ord)] -LL | struct X { x: i32 } +LL | struct X { | error: aborting due to 1 previous error diff --git a/tests/ui/traits/solver-cycles/assoc-equality-cycle.rs b/tests/ui/traits/solver-cycles/assoc-equality-cycle.rs index 258e362d1317c..f82bffc598b8b 100644 --- a/tests/ui/traits/solver-cycles/assoc-equality-cycle.rs +++ b/tests/ui/traits/solver-cycles/assoc-equality-cycle.rs @@ -1,9 +1,10 @@ +//! regression test for https://github.com/rust-lang/rust/issues/21177 trait Trait { type A; type B; } -fn foo>() { } +fn foo>() {} //~^ ERROR cycle detected -fn main() { } +fn main() {} diff --git a/tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr b/tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr index 9f66f43a195a1..a8c0228601a26 100644 --- a/tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr +++ b/tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr @@ -1,14 +1,14 @@ error[E0391]: cycle detected when computing the bounds for type parameter `T` - --> $DIR/issue-21177.rs:6:21 + --> $DIR/assoc-equality-cycle.rs:7:21 | -LL | fn foo>() { } +LL | fn foo>() {} | ^^^^ | = note: ...which immediately requires computing the bounds for type parameter `T` again note: cycle used when computing explicit predicates of `foo` - --> $DIR/issue-21177.rs:6:21 + --> $DIR/assoc-equality-cycle.rs:7:21 | -LL | fn foo>() { } +LL | fn foo>() {} | ^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information diff --git a/tests/ui/traits/solver-cycles/self-item-cycle.rs b/tests/ui/traits/solver-cycles/self-item-cycle.rs index 1500bc831528a..b0b5ab4235beb 100644 --- a/tests/ui/traits/solver-cycles/self-item-cycle.rs +++ b/tests/ui/traits/solver-cycles/self-item-cycle.rs @@ -1,5 +1,6 @@ -trait T : Iterator -//~^ ERROR cycle detected -{} +//! regression test for https://github.com/rust-lang/rust/issues/20772 +trait T: Iterator //~ ERROR cycle detected +{ +} fn main() {} diff --git a/tests/ui/traits/solver-cycles/self-item-cycle.stderr b/tests/ui/traits/solver-cycles/self-item-cycle.stderr index 81f80aef59446..9ffb9955af8a5 100644 --- a/tests/ui/traits/solver-cycles/self-item-cycle.stderr +++ b/tests/ui/traits/solver-cycles/self-item-cycle.stderr @@ -1,15 +1,15 @@ error[E0391]: cycle detected when computing the super traits of `T` with associated type name `Item` - --> $DIR/issue-20772.rs:1:1 + --> $DIR/self-item-cycle.rs:2:1 | -LL | trait T : Iterator - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | trait T: Iterator + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: ...which immediately requires computing the super traits of `T` with associated type name `Item` again note: cycle used when computing the super predicates of `T` - --> $DIR/issue-20772.rs:1:1 + --> $DIR/self-item-cycle.rs:2:1 | -LL | trait T : Iterator - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | trait T: Iterator + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 1 previous error diff --git a/tests/ui/typeck/missing-type-annotation.rs b/tests/ui/typeck/missing-type-annotation.rs index bd347d6329846..d13a7a8559e30 100644 --- a/tests/ui/typeck/missing-type-annotation.rs +++ b/tests/ui/typeck/missing-type-annotation.rs @@ -1,3 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/18159 fn main() { let x; //~ ERROR type annotations needed } diff --git a/tests/ui/typeck/missing-type-annotation.stderr b/tests/ui/typeck/missing-type-annotation.stderr index 5de13a5c314c5..88716e757a939 100644 --- a/tests/ui/typeck/missing-type-annotation.stderr +++ b/tests/ui/typeck/missing-type-annotation.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/issue-18159.rs:2:9 + --> $DIR/missing-type-annotation.rs:3:9 | LL | let x; | ^ diff --git a/tests/ui/typeck/osstring-str-equality.rs b/tests/ui/typeck/osstring-str-equality.rs index b5a3f07dd4b85..47d3dd632bdc1 100644 --- a/tests/ui/typeck/osstring-str-equality.rs +++ b/tests/ui/typeck/osstring-str-equality.rs @@ -1,3 +1,4 @@ +//! regression test for https://github.com/rust-lang/rust/issues/49854 //@ run-pass use std::ffi::OsString; diff --git a/tests/ui/typeck/return-expression-invalid-callee.rs b/tests/ui/typeck/return-expression-invalid-callee.rs index 31fd87961dc9f..1416f3e9ddfe7 100644 --- a/tests/ui/typeck/return-expression-invalid-callee.rs +++ b/tests/ui/typeck/return-expression-invalid-callee.rs @@ -1,7 +1,8 @@ -// Test that overloaded call parameter checking does not ICE -// when a type error or unconstrained type variable propagates -// into it. +//! regression test for issue https://github.com/rust-lang/rust/issues/18532 +//! Test that overloaded call parameter checking does not ICE +//! when a type error or unconstrained type variable propagates +//! into it. fn main() { - (return)((),()); //~ ERROR expected function, found `!` + (return)((), ()); //~ ERROR expected function, found `!` } diff --git a/tests/ui/typeck/return-expression-invalid-callee.stderr b/tests/ui/typeck/return-expression-invalid-callee.stderr index 059c7f137819e..5a36602af8bb6 100644 --- a/tests/ui/typeck/return-expression-invalid-callee.stderr +++ b/tests/ui/typeck/return-expression-invalid-callee.stderr @@ -1,8 +1,8 @@ error[E0618]: expected function, found `!` - --> $DIR/issue-18532.rs:6:5 + --> $DIR/return-expression-invalid-callee.rs:7:5 | -LL | (return)((),()); - | ^^^^^^^^------- +LL | (return)((), ()); + | ^^^^^^^^-------- | | | call expression requires function From 023f38fe73f5e392ea94cc15e53611bd2074302e Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 13 Dec 2025 22:59:34 +0100 Subject: [PATCH 55/64] custom `VaList` layout for Hexagon --- library/core/src/ffi/va_list.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs index 4c59ea0cc5328..d5166baf0c7ca 100644 --- a/library/core/src/ffi/va_list.rs +++ b/library/core/src/ffi/va_list.rs @@ -31,6 +31,9 @@ use crate::marker::PhantomCovariantLifetime; // the pointer decay behavior in Rust, while otherwise matching Rust semantics. // This attribute ensures that the compiler uses the correct ABI for functions // like `extern "C" fn takes_va_list(va: VaList<'_>)` by passing `va` indirectly. +// +// The Clang `BuiltinVaListKind` enumerates the `va_list` variations that Clang supports, +// and we mirror these here. crate::cfg_select! { all( target_arch = "aarch64", @@ -124,6 +127,23 @@ crate::cfg_select! { } } + all(target_arch = "hexagon", target_env = "musl") => { + /// Hexagon Musl implementation of a `va_list`. + /// + /// See the [LLVM source] for more details. On bare metal Hexagon uses an opaque pointer. + /// + /// [LLVM source]: + /// https://github.com/llvm/llvm-project/blob/0cdc1b6dd4a870fc41d4b15ad97e0001882aba58/clang/lib/CodeGen/Targets/Hexagon.cpp#L407-L417 + #[repr(C)] + #[derive(Debug)] + #[rustc_pass_indirectly_in_non_rustic_abis] + struct VaListInner { + __current_saved_reg_area_pointer: *const c_void, + __saved_reg_area_end_pointer: *const c_void, + __overflow_area_pointer: *const c_void, + } + } + // The fallback implementation, used for: // // - apple aarch64 (see https://github.com/rust-lang/rust/pull/56599) From dbfc8c218e1f48290b261146f8463878362ba100 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Mon, 15 Dec 2025 15:21:18 +0000 Subject: [PATCH 56/64] dont create unnecessary `DefId`s under mgca --- compiler/rustc_metadata/src/rmeta/encoder.rs | 5 +++- compiler/rustc_resolve/src/def_collector.rs | 10 ++++++++ .../mgca/explicit_anon_consts.rs | 5 ++-- .../mgca/explicit_anon_consts.stderr | 24 +++++++++---------- .../mgca/unused_speculative_def_id.rs | 24 +++++++++++++++++++ .../mgca/unused_speculative_def_id.stderr | 18 ++++++++++++++ 6 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 tests/ui/const-generics/mgca/unused_speculative_def_id.rs create mode 100644 tests/ui/const-generics/mgca/unused_speculative_def_id.stderr diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b15ed34fc3569..7da82835befb8 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1451,7 +1451,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { _ => false, } { - continue; + // MGCA doesn't have unnecessary DefIds + if !tcx.features().min_generic_const_args() { + continue; + } } if def_kind == DefKind::Field diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index ea64a1e6c64dd..71bbd64ddc6ce 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -357,6 +357,16 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } fn visit_anon_const(&mut self, constant: &'a AnonConst) { + // `MgcaDisambiguation::Direct` is set even when MGCA is disabled, so + // to avoid affecting stable we have to feature gate the not creating + // anon consts + if let MgcaDisambiguation::Direct = constant.mgca_disambiguation + && self.resolver.tcx.features().min_generic_const_args() + { + visit::walk_anon_const(self, constant); + return; + } + let parent = self.create_def(constant.id, None, DefKind::AnonConst, constant.value.span); self.with_parent(parent, |this| visit::walk_anon_const(this, constant)); } diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.rs b/tests/ui/const-generics/mgca/explicit_anon_consts.rs index 4592827762660..31391b023bfe3 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.rs +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.rs @@ -1,5 +1,8 @@ #![feature(associated_const_equality, generic_const_items, min_generic_const_args)] #![expect(incomplete_features)] +// library crates exercise weirder code paths around +// DefIds which were created for const args. +#![crate_type = "lib"] struct Foo; @@ -66,5 +69,3 @@ struct Default3; struct Default4; //~^ ERROR: complex const arguments must be placed inside of a `const` block struct Default5; - -fn main() {} diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr index e4bf49c71efed..b3d960e315eac 100644 --- a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr @@ -1,5 +1,5 @@ error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:8:41 + --> $DIR/explicit_anon_consts.rs:11:41 | LL | type Adt3 = Foo; | ^ cannot perform const operation using `N` @@ -8,7 +8,7 @@ LL | type Adt3 = Foo; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:16:42 + --> $DIR/explicit_anon_consts.rs:19:42 | LL | type Arr3 = [(); const { N }]; | ^ cannot perform const operation using `N` @@ -17,7 +17,7 @@ LL | type Arr3 = [(); const { N }]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:25:27 + --> $DIR/explicit_anon_consts.rs:28:27 | LL | let _3 = [(); const { N }]; | ^ cannot perform const operation using `N` @@ -26,7 +26,7 @@ LL | let _3 = [(); const { N }]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:37:46 + --> $DIR/explicit_anon_consts.rs:40:46 | LL | const ITEM3: usize = const { N }; | ^ cannot perform const operation using `N` @@ -35,7 +35,7 @@ LL | const ITEM3: usize = const { N }; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:55:31 + --> $DIR/explicit_anon_consts.rs:58:31 | LL | T3: Trait, | ^ cannot perform const operation using `N` @@ -44,7 +44,7 @@ LL | T3: Trait, = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/explicit_anon_consts.rs:64:58 + --> $DIR/explicit_anon_consts.rs:67:58 | LL | struct Default3; | ^ cannot perform const operation using `N` @@ -53,37 +53,37 @@ LL | struct Default3; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:10:33 + --> $DIR/explicit_anon_consts.rs:13:33 | LL | type Adt4 = Foo<{ 1 + 1 }>; | ^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:18:34 + --> $DIR/explicit_anon_consts.rs:21:34 | LL | type Arr4 = [(); 1 + 1]; | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:27:19 + --> $DIR/explicit_anon_consts.rs:30:19 | LL | let _4 = [(); 1 + 1]; | ^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:40:38 + --> $DIR/explicit_anon_consts.rs:43:38 | LL | const ITEM4: usize = { 1 + 1 }; | ^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:57:23 + --> $DIR/explicit_anon_consts.rs:60:23 | LL | T4: Trait, | ^^^^^^^^^ error: complex const arguments must be placed inside of a `const` block - --> $DIR/explicit_anon_consts.rs:66:50 + --> $DIR/explicit_anon_consts.rs:69:50 | LL | struct Default4; | ^^^^^^^^^ diff --git a/tests/ui/const-generics/mgca/unused_speculative_def_id.rs b/tests/ui/const-generics/mgca/unused_speculative_def_id.rs new file mode 100644 index 0000000000000..e617daba24b68 --- /dev/null +++ b/tests/ui/const-generics/mgca/unused_speculative_def_id.rs @@ -0,0 +1,24 @@ +#![feature(min_generic_const_args, generic_const_exprs, generic_const_items)] +#![expect(incomplete_features)] + +// Previously we would create a `DefId` to represent the const argument to `A` +// except it would go unused as it's a MGCA path const arg. We would also make +// a `DefId` for the `const { 1 }` anon const arg to `ERR` which would wind up +// with a `DefId` parent of the speculatively created `DefId` for the argument to +// `A`. +// +// This then caused Problems:tm: in the rest of the compiler that did not expect +// to encounter such nonsensical `DefId`s. +// +// The `ERR` path must fail to resolve as if it can be resolved then broken GCE +// logic will attempt to evaluate the constant directly which is wrong for +// `type_const`s which do not have bodies. + +struct A; + +struct Foo { + field: A<{ ERR:: }>, + //~^ ERROR: cannot find value `ERR` in this scope +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/unused_speculative_def_id.stderr b/tests/ui/const-generics/mgca/unused_speculative_def_id.stderr new file mode 100644 index 0000000000000..e087e046ec35d --- /dev/null +++ b/tests/ui/const-generics/mgca/unused_speculative_def_id.stderr @@ -0,0 +1,18 @@ +error[E0425]: cannot find value `ERR` in this scope + --> $DIR/unused_speculative_def_id.rs:20:16 + | +LL | field: A<{ ERR:: }>, + | ^^^ + | + --> $SRC_DIR/core/src/result.rs:LL:COL + | + = note: similarly named tuple variant `Err` defined here +help: a tuple variant with a similar name exists + | +LL - field: A<{ ERR:: }>, +LL + field: A<{ Err:: }>, + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. From 63cdf9310e41d3ee38f546a75b2c8cd7d5f2b565 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Tue, 16 Dec 2025 03:59:09 +0000 Subject: [PATCH 57/64] Prepare for merging from rust-lang/rust This updates the rust-version file to cec70080fd441d16e9fb08a0d1d1a04c72d1ed25. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 4bcbec1a9f480..71a84e2bda12c 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -ce63e5d9ea20f15a70c6fdc4d4de7aee352fd965 +cec70080fd441d16e9fb08a0d1d1a04c72d1ed25 From fca8611a3e79a22a7339a75eba0cb66d627afc6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 16 Dec 2025 09:42:42 +0100 Subject: [PATCH 58/64] Mirror GCC --- src/ci/docker/scripts/build-gcc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/scripts/build-gcc.sh b/src/ci/docker/scripts/build-gcc.sh index 11db5aa811ce8..ab4cae21e0254 100755 --- a/src/ci/docker/scripts/build-gcc.sh +++ b/src/ci/docker/scripts/build-gcc.sh @@ -7,7 +7,7 @@ source shared.sh # This version is specified in the Dockerfile GCC=$GCC_VERSION -curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.xz | xzcat | tar xf - +curl https://ci-mirrors.rust-lang.org/rustc/gcc/gcc-$GCC.tar.xz | xzcat | tar xf - cd gcc-$GCC # FIXME(#49246): Remove the `sed` below. From d5bf1a4c9a9205d820faedff789f4e55ebf18857 Mon Sep 17 00:00:00 2001 From: Ivar Flakstad <69173633+ivarflakstad@users.noreply.github.com> Date: Sun, 13 Jul 2025 15:32:28 +0200 Subject: [PATCH 59/64] Introduce `vtable_for` intrinsic and use it to implement `try_as_dyn` and `try_as_dyn_mut` for fallible coercion from `&T` / `&mut T` to `&dyn Trait`. --- .../src/interpret/intrinsics.rs | 50 +++++++- .../rustc_hir_analysis/src/check/intrinsic.rs | 15 +++ compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_type_ir/src/predicate.rs | 7 ++ library/core/src/any.rs | 108 +++++++++++++++++- library/core/src/intrinsics/mod.rs | 16 +++ library/coretests/tests/intrinsics.rs | 19 ++- tests/ui/any/try_as_dyn.rs | 29 +++++ tests/ui/any/try_as_dyn_mut.rs | 20 ++++ tests/ui/any/try_as_dyn_soundness_test1.rs | 22 ++++ tests/ui/any/try_as_dyn_soundness_test2.rs | 16 +++ 11 files changed, 299 insertions(+), 4 deletions(-) create mode 100644 tests/ui/any/try_as_dyn.rs create mode 100644 tests/ui/any/try_as_dyn_mut.rs create mode 100644 tests/ui/any/try_as_dyn_soundness_test1.rs create mode 100644 tests/ui/any/try_as_dyn_soundness_test2.rs diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index a7a3bbebed5f1..44c817b33184e 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -6,14 +6,17 @@ mod simd; use std::assert_matches::assert_matches; -use rustc_abi::{FieldIdx, HasDataLayout, Size, VariantIdx}; +use rustc_abi::{FIRST_VARIANT, FieldIdx, HasDataLayout, Size, VariantIdx}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; +use rustc_hir::def_id::CRATE_DEF_ID; +use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, read_target_uint, write_target_uint}; use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic}; use rustc_middle::ty::layout::TyAndLayout; -use rustc_middle::ty::{FloatTy, Ty, TyCtxt}; +use rustc_middle::ty::{FloatTy, PolyExistentialPredicate, Ty, TyCtxt, TypeFoldable}; use rustc_middle::{bug, span_bug, ty}; use rustc_span::{Symbol, sym}; +use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt}; use tracing::trace; use super::memory::MemoryKind; @@ -219,6 +222,49 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(Scalar::from_target_usize(offset, self), dest)?; } + sym::vtable_for => { + let tp_ty = instance.args.type_at(0); + let result_ty = instance.args.type_at(1); + + ensure_monomorphic_enough(tcx, tp_ty)?; + ensure_monomorphic_enough(tcx, result_ty)?; + let ty::Dynamic(preds, _) = result_ty.kind() else { + span_bug!( + self.find_closest_untracked_caller_location(), + "Invalid type provided to vtable_for::. U must be dyn Trait, got {result_ty}." + ); + }; + + let (infcx, param_env) = + self.tcx.infer_ctxt().build_with_typing_env(self.typing_env); + + let ocx = ObligationCtxt::new(&infcx); + ocx.register_obligations(preds.iter().map(|pred: PolyExistentialPredicate<'_>| { + let pred = pred.with_self_ty(tcx, tp_ty); + // Lifetimes can only be 'static because of the bound on T + let pred = pred.fold_with(&mut ty::BottomUpFolder { + tcx, + ty_op: |ty| ty, + lt_op: |lt| { + if lt == tcx.lifetimes.re_erased { tcx.lifetimes.re_static } else { lt } + }, + ct_op: |ct| ct, + }); + Obligation::new(tcx, ObligationCause::dummy(), param_env, pred) + })); + let type_impls_trait = ocx.evaluate_obligations_error_on_ambiguity().is_empty(); + // Since `assumed_wf_tys=[]` the choice of LocalDefId is irrelevant, so using the "default" + let regions_are_valid = ocx.resolve_regions(CRATE_DEF_ID, param_env, []).is_empty(); + + if regions_are_valid && type_impls_trait { + let vtable_ptr = self.get_vtable_ptr(tp_ty, preds)?; + // Writing a non-null pointer into an `Option` will automatically make it `Some`. + self.write_pointer(vtable_ptr, dest)?; + } else { + // Write `None` + self.write_discriminant(FIRST_VARIANT, dest)?; + } + } sym::variant_count => { let tp_ty = instance.args.type_at(0); let ty = match tp_ty.kind() { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 676c9a980afff..4e8333f678b66 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -215,6 +215,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::type_name | sym::ub_checks | sym::variant_count + | sym::vtable_for | sym::wrapping_add | sym::wrapping_mul | sym::wrapping_sub @@ -643,6 +644,20 @@ pub(crate) fn check_intrinsic_type( (0, 0, vec![Ty::new_imm_ptr(tcx, tcx.types.unit)], tcx.types.usize) } + sym::vtable_for => { + let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, span); + let dyn_metadata_adt_ref = tcx.adt_def(dyn_metadata); + let dyn_metadata_args = tcx.mk_args(&[param(1).into()]); + let dyn_ty = Ty::new_adt(tcx, dyn_metadata_adt_ref, dyn_metadata_args); + + let option_did = tcx.require_lang_item(LangItem::Option, span); + let option_adt_ref = tcx.adt_def(option_did); + let option_args = tcx.mk_args(&[dyn_ty.into()]); + let ret_ty = Ty::new_adt(tcx, option_adt_ref, option_args); + + (2, 0, vec![], ret_ty) + } + // This type check is not particularly useful, but the `where` bounds // on the definition in `core` do the heavy lifting for checking it. sym::aggregate_raw_ptr => (3, 0, vec![param(1), param(2)], param(0)), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8e464b55d6c23..4700d945795ab 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2473,6 +2473,7 @@ symbols! { vsreg, vsx, vtable_align, + vtable_for, vtable_size, warn, wasip2, diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 3e32a77885468..bfe9065157792 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -291,6 +291,13 @@ pub enum ExistentialPredicate { impl Eq for ExistentialPredicate {} impl ty::Binder> { + pub fn def_id(&self) -> I::DefId { + match self.skip_binder() { + ExistentialPredicate::Trait(tr) => tr.def_id.into(), + ExistentialPredicate::Projection(p) => p.def_id.into(), + ExistentialPredicate::AutoTrait(did) => did.into(), + } + } /// Given an existential predicate like `?Self: PartialEq` (e.g., derived from `dyn PartialEq`), /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self` /// has been replaced with `self_ty` (e.g., `self_ty: PartialEq`, in our example). diff --git a/library/core/src/any.rs b/library/core/src/any.rs index ff55793340bd0..42f332f7d8ba8 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -86,7 +86,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use crate::{fmt, hash, intrinsics}; +use crate::{fmt, hash, intrinsics, ptr}; /////////////////////////////////////////////////////////////////////////////// // Any trait @@ -906,3 +906,109 @@ pub const fn type_name() -> &'static str { pub const fn type_name_of_val(_val: &T) -> &'static str { type_name::() } + +/// Returns `Some(&U)` if `T` can be coerced to the trait object type `U`. Otherwise, it returns `None`. +/// +/// # Compile-time failures +/// Determining whether `T` can be coerced to the trait object type `U` requires compiler trait resolution. +/// In some cases, that resolution can exceed the recursion limit, +/// and compilation will fail instead of this function returning `None`. +/// # Examples +/// +/// ```rust +/// #![feature(try_as_dyn)] +/// +/// use core::any::try_as_dyn; +/// +/// trait Animal { +/// fn speak(&self) -> &'static str; +/// } +/// +/// struct Dog; +/// impl Animal for Dog { +/// fn speak(&self) -> &'static str { "woof" } +/// } +/// +/// struct Rock; // does not implement Animal +/// +/// let dog = Dog; +/// let rock = Rock; +/// +/// let as_animal: Option<&dyn Animal> = try_as_dyn::(&dog); +/// assert_eq!(as_animal.unwrap().speak(), "woof"); +/// +/// let not_an_animal: Option<&dyn Animal> = try_as_dyn::(&rock); +/// assert!(not_an_animal.is_none()); +/// ``` +#[must_use] +#[unstable(feature = "try_as_dyn", issue = "144361")] +pub const fn try_as_dyn< + T: Any + 'static, + U: ptr::Pointee> + ?Sized + 'static, +>( + t: &T, +) -> Option<&U> { + let vtable: Option> = const { intrinsics::vtable_for::() }; + match vtable { + Some(dyn_metadata) => { + let pointer = ptr::from_raw_parts(t, dyn_metadata); + // SAFETY: `t` is a reference to a type, so we know it is valid. + // `dyn_metadata` is a vtable for T, implementing the trait of `U`. + Some(unsafe { &*pointer }) + } + None => None, + } +} + +/// Returns `Some(&mut U)` if `T` can be coerced to the trait object type `U`. Otherwise, it returns `None`. +/// +/// # Compile-time failures +/// Determining whether `T` can be coerced to the trait object type `U` requires compiler trait resolution. +/// In some cases, that resolution can exceed the recursion limit, +/// and compilation will fail instead of this function returning `None`. +/// # Examples +/// +/// ```rust +/// #![feature(try_as_dyn)] +/// +/// use core::any::try_as_dyn_mut; +/// +/// trait Animal { +/// fn speak(&self) -> &'static str; +/// } +/// +/// struct Dog; +/// impl Animal for Dog { +/// fn speak(&self) -> &'static str { "woof" } +/// } +/// +/// struct Rock; // does not implement Animal +/// +/// let mut dog = Dog; +/// let mut rock = Rock; +/// +/// let as_animal: Option<&mut dyn Animal> = try_as_dyn_mut::(&mut dog); +/// assert_eq!(as_animal.unwrap().speak(), "woof"); +/// +/// let not_an_animal: Option<&mut dyn Animal> = try_as_dyn_mut::(&mut rock); +/// assert!(not_an_animal.is_none()); +/// ``` +#[must_use] +#[unstable(feature = "try_as_dyn", issue = "144361")] +pub const fn try_as_dyn_mut< + T: Any + 'static, + U: ptr::Pointee> + ?Sized + 'static, +>( + t: &mut T, +) -> Option<&mut U> { + let vtable: Option> = const { intrinsics::vtable_for::() }; + match vtable { + Some(dyn_metadata) => { + let pointer = ptr::from_raw_parts_mut(t, dyn_metadata); + // SAFETY: `t` is a reference to a type, so we know it is valid. + // `dyn_metadata` is a vtable for T, implementing the trait of `U`. + Some(unsafe { &mut *pointer }) + } + None => None, + } +} diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 722e16ab0fa49..2179b451c375e 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2754,6 +2754,22 @@ pub unsafe fn vtable_size(ptr: *const ()) -> usize; #[rustc_intrinsic] pub unsafe fn vtable_align(ptr: *const ()) -> usize; +/// The intrinsic returns the `U` vtable for `T` if `T` can be coerced to the trait object type `U`. +/// +/// # Compile-time failures +/// Determining whether `T` can be coerced to the trait object type `U` requires trait resolution by the compiler. +/// In some cases, that resolution can exceed the recursion limit, +/// and compilation will fail instead of this function returning `None`. +/// +/// # Safety +/// +/// `ptr` must point to a vtable. +#[rustc_nounwind] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_intrinsic] +pub const fn vtable_for> + ?Sized>() +-> Option>; + /// The size of a type in bytes. /// /// Note that, unlike most intrinsics, this is safe to call; diff --git a/library/coretests/tests/intrinsics.rs b/library/coretests/tests/intrinsics.rs index 744a6a0d2dd8f..c6d841b8383a8 100644 --- a/library/coretests/tests/intrinsics.rs +++ b/library/coretests/tests/intrinsics.rs @@ -1,5 +1,8 @@ use core::any::TypeId; -use core::intrinsics::assume; +use core::intrinsics::{assume, vtable_for}; +use std::fmt::Debug; +use std::option::Option; +use std::ptr::DynMetadata; #[test] fn test_typeid_sized_types() { @@ -193,3 +196,17 @@ fn carrying_mul_add_fallback_i128() { (u128::MAX - 1, -(i128::MIN / 2)), ); } + +#[test] +fn test_vtable_for() { + #[derive(Debug)] + struct A {} + + struct B {} + + const A_VTABLE: Option> = vtable_for::(); + assert!(A_VTABLE.is_some()); + + const B_VTABLE: Option> = vtable_for::(); + assert!(B_VTABLE.is_none()); +} diff --git a/tests/ui/any/try_as_dyn.rs b/tests/ui/any/try_as_dyn.rs new file mode 100644 index 0000000000000..ee220f797ced9 --- /dev/null +++ b/tests/ui/any/try_as_dyn.rs @@ -0,0 +1,29 @@ +//@ run-pass +#![feature(try_as_dyn)] + +use std::fmt::Debug; + +// Look ma, no `T: Debug` +fn debug_format_with_try_as_dyn(t: &T) -> String { + match std::any::try_as_dyn::<_, dyn Debug>(t) { + Some(d) => format!("{d:?}"), + None => "default".to_string() + } +} + +// Test that downcasting to a dyn trait works as expected +fn main() { + #[allow(dead_code)] + #[derive(Debug)] + struct A { + index: usize + } + let a = A { index: 42 }; + let result = debug_format_with_try_as_dyn(&a); + assert_eq!("A { index: 42 }", result); + + struct B {} + let b = B {}; + let result = debug_format_with_try_as_dyn(&b); + assert_eq!("default", result); +} diff --git a/tests/ui/any/try_as_dyn_mut.rs b/tests/ui/any/try_as_dyn_mut.rs new file mode 100644 index 0000000000000..ff7baa32ea874 --- /dev/null +++ b/tests/ui/any/try_as_dyn_mut.rs @@ -0,0 +1,20 @@ +//@ run-pass +#![feature(try_as_dyn)] + +use std::fmt::{Error, Write}; + +// Look ma, no `T: Write` +fn try_as_dyn_mut_write(t: &mut T, s: &str) -> Result<(), Error> { + match std::any::try_as_dyn_mut::<_, dyn Write>(t) { + Some(w) => w.write_str(s), + None => Ok(()) + } +} + +// Test that downcasting to a mut dyn trait works as expected +fn main() { + let mut buf = "Hello".to_string(); + + try_as_dyn_mut_write(&mut buf, " world!").unwrap(); + assert_eq!(buf, "Hello world!"); +} diff --git a/tests/ui/any/try_as_dyn_soundness_test1.rs b/tests/ui/any/try_as_dyn_soundness_test1.rs new file mode 100644 index 0000000000000..0772e9a2d77ee --- /dev/null +++ b/tests/ui/any/try_as_dyn_soundness_test1.rs @@ -0,0 +1,22 @@ +//@ run-pass +#![feature(try_as_dyn)] + +use std::any::try_as_dyn; + +trait Trait { + +} + +impl Trait for for<'a> fn(&'a Box) { + +} + +fn store(_: &'static Box) { + +} + +fn main() { + let fn_ptr: fn(&'static Box) = store; + let dt = try_as_dyn::<_, dyn Trait>(&fn_ptr); + assert!(dt.is_none()); +} diff --git a/tests/ui/any/try_as_dyn_soundness_test2.rs b/tests/ui/any/try_as_dyn_soundness_test2.rs new file mode 100644 index 0000000000000..c16b50d0261ed --- /dev/null +++ b/tests/ui/any/try_as_dyn_soundness_test2.rs @@ -0,0 +1,16 @@ +//@ run-pass +#![feature(try_as_dyn)] +use std::any::try_as_dyn; + +trait Trait { + +} + +impl Trait fn(&'a Box)> for () { + +} + +fn main() { + let dt = try_as_dyn::<_, dyn Trait)>>(&()); + assert!(dt.is_none()); +} From 6d6068f6c5b371b91e51289e5e875f8df75e5def Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 16 Dec 2025 10:42:14 +0000 Subject: [PATCH 60/64] stabilize annotate-snippet as default formatter --- compiler/rustc_errors/src/emitter.rs | 13 +++--- compiler/rustc_errors/src/json.rs | 47 ++++++--------------- compiler/rustc_errors/src/json/tests.rs | 2 +- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_session/src/config.rs | 55 ++++++------------------- compiler/rustc_session/src/session.rs | 27 ++---------- src/librustdoc/config.rs | 12 ++---- src/librustdoc/core.rs | 15 +------ src/librustdoc/doctest.rs | 2 +- 9 files changed, 42 insertions(+), 133 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 78feb60261bd8..2e41f74ee25d8 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -46,17 +46,14 @@ const DEFAULT_COLUMN_WIDTH: usize = 140; /// Describes the way the content of the `rendered` field of the json output is generated #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum HumanReadableErrorType { - Default { short: bool }, - AnnotateSnippet { short: bool, unicode: bool }, +pub struct HumanReadableErrorType { + pub short: bool, + pub unicode: bool, } impl HumanReadableErrorType { pub fn short(&self) -> bool { - match self { - HumanReadableErrorType::Default { short } - | HumanReadableErrorType::AnnotateSnippet { short, .. } => *short, - } + self.short } } @@ -607,7 +604,7 @@ pub enum OutputTheme { Unicode, } -/// Handles the writing of `HumanReadableErrorType::Default` and `HumanReadableErrorType::Short` +/// Handles the writing of `HumanReadableErrorType` #[derive(Setters)] pub struct HumanEmitter { #[setters(skip)] diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 3b8c8baa5eff8..85801245bea90 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -28,8 +28,8 @@ use serde::Serialize; use crate::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use crate::diagnostic::IsLint; use crate::emitter::{ - ColorConfig, Destination, Emitter, HumanEmitter, HumanReadableErrorType, OutputTheme, - TimingEvent, should_show_source_code, + ColorConfig, Destination, Emitter, HumanReadableErrorType, OutputTheme, TimingEvent, + should_show_source_code, }; use crate::registry::Registry; use crate::timings::{TimingRecord, TimingSection}; @@ -378,38 +378,17 @@ impl Diagnostic { choice => choice, }, ); - match je.json_rendered { - HumanReadableErrorType::AnnotateSnippet { short, unicode } => { - AnnotateSnippetEmitter::new(dst, je.translator.clone()) - .short_message(short) - .sm(je.sm.clone()) - .diagnostic_width(je.diagnostic_width) - .macro_backtrace(je.macro_backtrace) - .track_diagnostics(je.track_diagnostics) - .terminal_url(je.terminal_url) - .ui_testing(je.ui_testing) - .ignored_directories_in_source_blocks( - je.ignored_directories_in_source_blocks.clone(), - ) - .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) - .emit_diagnostic(diag, registry) - } - HumanReadableErrorType::Default { short } => { - HumanEmitter::new(dst, je.translator.clone()) - .short_message(short) - .sm(je.sm.clone()) - .diagnostic_width(je.diagnostic_width) - .macro_backtrace(je.macro_backtrace) - .track_diagnostics(je.track_diagnostics) - .terminal_url(je.terminal_url) - .ui_testing(je.ui_testing) - .ignored_directories_in_source_blocks( - je.ignored_directories_in_source_blocks.clone(), - ) - .theme(OutputTheme::Ascii) - .emit_diagnostic(diag, registry) - } - } + AnnotateSnippetEmitter::new(dst, je.translator.clone()) + .short_message(je.json_rendered.short) + .sm(je.sm.clone()) + .diagnostic_width(je.diagnostic_width) + .macro_backtrace(je.macro_backtrace) + .track_diagnostics(je.track_diagnostics) + .terminal_url(je.terminal_url) + .ui_testing(je.ui_testing) + .ignored_directories_in_source_blocks(je.ignored_directories_in_source_blocks.clone()) + .theme(if je.json_rendered.unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) + .emit_diagnostic(diag, registry); let buf = Arc::try_unwrap(buf.0).unwrap().into_inner().unwrap(); let buf = String::from_utf8(buf).unwrap(); diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index 30be06ae0bd3b..c1c9ecf7198f6 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -54,7 +54,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { Some(sm), translator, true, // pretty - HumanReadableErrorType::Default { short: true }, + HumanReadableErrorType { short: true, unicode: false }, ColorConfig::Never, ); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 89b8a5fddb89e..8dab3a7f37f59 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -321,7 +321,7 @@ fn test_search_paths_tracking_hash_different_order() { let early_dcx = EarlyDiagCtxt::new(JSON); const JSON: ErrorOutputType = ErrorOutputType::Json { pretty: false, - json_rendered: HumanReadableErrorType::Default { short: false }, + json_rendered: HumanReadableErrorType { short: false, unicode: false }, color_config: ColorConfig::Never, }; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index be4b36e3b926c..5b2ae59aba403 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -806,7 +806,7 @@ pub enum ErrorOutputType { /// Output meant for the consumption of humans. #[default] HumanReadable { - kind: HumanReadableErrorType = HumanReadableErrorType::Default { short: false }, + kind: HumanReadableErrorType = HumanReadableErrorType { short: false, unicode: false }, color_config: ColorConfig = ColorConfig::Auto, }, /// Output that's consumed by other tools such as `rustfix` or the `RLS`. @@ -1965,16 +1965,8 @@ impl JsonUnusedExterns { /// /// The first value returned is how to render JSON diagnostics, and the second /// is whether or not artifact notifications are enabled. -pub fn parse_json( - early_dcx: &EarlyDiagCtxt, - matches: &getopts::Matches, - is_nightly_build: bool, -) -> JsonConfig { - let mut json_rendered = if is_nightly_build { - HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false } - } else { - HumanReadableErrorType::Default { short: false } - }; +pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig { + let mut json_rendered = HumanReadableErrorType { short: false, unicode: false }; let mut json_color = ColorConfig::Never; let mut json_artifact_notifications = false; let mut json_unused_externs = JsonUnusedExterns::No; @@ -1991,15 +1983,10 @@ pub fn parse_json( for sub_option in option.split(',') { match sub_option { "diagnostic-short" => { - json_rendered = if is_nightly_build { - HumanReadableErrorType::AnnotateSnippet { short: true, unicode: false } - } else { - HumanReadableErrorType::Default { short: true } - }; + json_rendered = HumanReadableErrorType { short: true, unicode: false }; } "diagnostic-unicode" => { - json_rendered = - HumanReadableErrorType::AnnotateSnippet { short: false, unicode: true }; + json_rendered = HumanReadableErrorType { short: false, unicode: true }; } "diagnostic-rendered-ansi" => json_color = ColorConfig::Always, "artifacts" => json_artifact_notifications = true, @@ -2029,13 +2016,8 @@ pub fn parse_error_format( color_config: ColorConfig, json_color: ColorConfig, json_rendered: HumanReadableErrorType, - is_nightly_build: bool, ) -> ErrorOutputType { - let default_kind = if is_nightly_build { - HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false } - } else { - HumanReadableErrorType::Default { short: false } - }; + let default_kind = HumanReadableErrorType { short: false, unicode: false }; // We need the `opts_present` check because the driver will send us Matches // with only stable options if no unstable options are used. Since error-format // is unstable, it will not be present. We have to use `opts_present` not @@ -2046,7 +2028,7 @@ pub fn parse_error_format( ErrorOutputType::HumanReadable { color_config, kind: default_kind } } Some("human-annotate-rs") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false }, + kind: HumanReadableErrorType { short: false, unicode: false }, color_config, }, Some("json") => { @@ -2056,15 +2038,11 @@ pub fn parse_error_format( ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color } } Some("short") => ErrorOutputType::HumanReadable { - kind: if is_nightly_build { - HumanReadableErrorType::AnnotateSnippet { short: true, unicode: false } - } else { - HumanReadableErrorType::Default { short: true } - }, + kind: HumanReadableErrorType { short: true, unicode: false }, color_config, }, Some("human-unicode") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::AnnotateSnippet { short: false, unicode: true }, + kind: HumanReadableErrorType { short: false, unicode: true }, color_config, }, Some(arg) => { @@ -2136,8 +2114,8 @@ fn check_error_format_stability( let format = match format { ErrorOutputType::Json { pretty: true, .. } => "pretty-json", ErrorOutputType::HumanReadable { kind, .. } => match kind { - HumanReadableErrorType::AnnotateSnippet { unicode: false, .. } => "human-annotate-rs", - HumanReadableErrorType::AnnotateSnippet { unicode: true, .. } => "human-unicode", + HumanReadableErrorType { unicode: false, .. } => "human-annotate-rs", + HumanReadableErrorType { unicode: true, .. } => "human-unicode", _ => return, }, _ => return, @@ -2465,16 +2443,9 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M json_timings, json_unused_externs, json_future_incompat, - } = parse_json(early_dcx, matches, unstable_features.is_nightly_build()); + } = parse_json(early_dcx, matches); - let error_format = parse_error_format( - early_dcx, - matches, - color, - json_color, - json_rendered, - unstable_features.is_nightly_build(), - ); + let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered); early_dcx.set_error_format(error_format); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 14b80099bafe4..1a0ec600af47d 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -13,9 +13,7 @@ use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef}; use rustc_data_structures::sync::{DynSend, DynSync, Lock, MappedReadGuard, ReadGuard, RwLock}; use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::codes::*; -use rustc_errors::emitter::{ - DynEmitter, HumanEmitter, HumanReadableErrorType, OutputTheme, stderr_destination, -}; +use rustc_errors::emitter::{DynEmitter, HumanReadableErrorType, OutputTheme, stderr_destination}; use rustc_errors::json::JsonEmitter; use rustc_errors::timings::TimingSectionHandler; use rustc_errors::translation::Translator; @@ -920,7 +918,7 @@ fn default_emitter( match sopts.error_format { config::ErrorOutputType::HumanReadable { kind, color_config } => match kind { - HumanReadableErrorType::AnnotateSnippet { short, unicode } => { + HumanReadableErrorType { short, unicode } => { let emitter = AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) .sm(source_map) @@ -938,20 +936,6 @@ fn default_emitter( ); Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) } - HumanReadableErrorType::Default { short } => { - let emitter = HumanEmitter::new(stderr_destination(color_config), translator) - .sm(source_map) - .short_message(short) - .diagnostic_width(sopts.diagnostic_width) - .macro_backtrace(macro_backtrace) - .track_diagnostics(track_diagnostics) - .terminal_url(terminal_url) - .theme(OutputTheme::Ascii) - .ignored_directories_in_source_blocks( - sopts.unstable_opts.ignore_directory_in_diagnostics_source_blocks.clone(), - ); - Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) - } }, config::ErrorOutputType::Json { pretty, json_rendered, color_config } => Box::new( JsonEmitter::new( @@ -1460,16 +1444,11 @@ fn mk_emitter(output: ErrorOutputType) -> Box { Translator::with_fallback_bundle(vec![rustc_errors::DEFAULT_LOCALE_RESOURCE], false); let emitter: Box = match output { config::ErrorOutputType::HumanReadable { kind, color_config } => match kind { - HumanReadableErrorType::AnnotateSnippet { short, unicode } => Box::new( + HumanReadableErrorType { short, unicode } => Box::new( AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) .short_message(short), ), - HumanReadableErrorType::Default { short } => Box::new( - HumanEmitter::new(stderr_destination(color_config), translator) - .theme(OutputTheme::Ascii) - .short_message(short), - ), }, config::ErrorOutputType::Json { pretty, json_rendered, color_config } => { Box::new(JsonEmitter::new( diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index e5a4593260a42..3d4b4e969157c 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -404,15 +404,9 @@ impl Options { let unstable_features = rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref()); let config::JsonConfig { json_rendered, json_unused_externs, json_color, .. } = - config::parse_json(early_dcx, matches, unstable_features.is_nightly_build()); - let error_format = config::parse_error_format( - early_dcx, - matches, - color, - json_color, - json_rendered, - unstable_features.is_nightly_build(), - ); + config::parse_json(early_dcx, matches); + let error_format = + config::parse_error_format(early_dcx, matches, color, json_color, json_rendered); let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_default(); let mut target_modifiers = BTreeMap::::new(); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 6e70f5b41c426..fb20889632840 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -7,9 +7,7 @@ use rustc_driver::USING_INTERNAL_FEATURES; use rustc_errors::TerminalUrl; use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::codes::*; -use rustc_errors::emitter::{ - DynEmitter, HumanEmitter, HumanReadableErrorType, OutputTheme, stderr_destination, -}; +use rustc_errors::emitter::{DynEmitter, HumanReadableErrorType, OutputTheme, stderr_destination}; use rustc_errors::json::JsonEmitter; use rustc_feature::UnstableFeatures; use rustc_hir::def::Res; @@ -162,7 +160,7 @@ pub(crate) fn new_dcx( let translator = rustc_driver::default_translator(); let emitter: Box = match error_format { ErrorOutputType::HumanReadable { kind, color_config } => match kind { - HumanReadableErrorType::AnnotateSnippet { short, unicode } => Box::new( + HumanReadableErrorType { short, unicode } => Box::new( AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) .sm(source_map.map(|sm| sm as _)) .short_message(short) @@ -171,15 +169,6 @@ pub(crate) fn new_dcx( .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) .ui_testing(unstable_opts.ui_testing), ), - HumanReadableErrorType::Default { short } => Box::new( - HumanEmitter::new(stderr_destination(color_config), translator) - .sm(source_map.map(|sm| sm as _)) - .short_message(short) - .diagnostic_width(diagnostic_width) - .track_diagnostics(unstable_opts.track_diagnostics) - .theme(OutputTheme::Ascii) - .ui_testing(unstable_opts.ui_testing), - ), }, ErrorOutputType::Json { pretty, json_rendered, color_config } => { let source_map = source_map.unwrap_or_else(|| { diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 85fecb87533db..25868e24ce164 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -625,7 +625,7 @@ fn run_test( ]); if let ErrorOutputType::HumanReadable { kind, color_config } = rustdoc_options.error_format { let short = kind.short(); - let unicode = kind == HumanReadableErrorType::AnnotateSnippet { unicode: true, short }; + let unicode = kind == HumanReadableErrorType { unicode: true, short }; if short { compiler_args.extend_from_slice(&["--error-format".to_owned(), "short".to_owned()]); From a47c8b292ed7b2a3bff627da1cd6e2826aab6db0 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 16 Dec 2025 10:47:37 +0000 Subject: [PATCH 61/64] remove human-annotate-rs --- compiler/rustc_session/src/config.rs | 9 ++------- tests/ui/annotate-snippet/missing-type.rs | 2 +- tests/ui/annotate-snippet/multiple-files.rs | 2 +- tests/ui/annotate-snippet/multispan.rs | 2 +- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 5b2ae59aba403..a3a97dfec61dc 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2027,10 +2027,6 @@ pub fn parse_error_format( None | Some("human") => { ErrorOutputType::HumanReadable { color_config, kind: default_kind } } - Some("human-annotate-rs") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType { short: false, unicode: false }, - color_config, - }, Some("json") => { ErrorOutputType::Json { pretty: false, json_rendered, color_config: json_color } } @@ -2051,8 +2047,8 @@ pub fn parse_error_format( kind: default_kind, }); early_dcx.early_fatal(format!( - "argument for `--error-format` must be `human`, `human-annotate-rs`, \ - `human-unicode`, `json`, `pretty-json` or `short` (instead was `{arg}`)" + "argument for `--error-format` must be `human`, `human-unicode`, \ + `json`, `pretty-json` or `short` (instead was `{arg}`)" )) } } @@ -2114,7 +2110,6 @@ fn check_error_format_stability( let format = match format { ErrorOutputType::Json { pretty: true, .. } => "pretty-json", ErrorOutputType::HumanReadable { kind, .. } => match kind { - HumanReadableErrorType { unicode: false, .. } => "human-annotate-rs", HumanReadableErrorType { unicode: true, .. } => "human-unicode", _ => return, }, diff --git a/tests/ui/annotate-snippet/missing-type.rs b/tests/ui/annotate-snippet/missing-type.rs index 54088def3eeaf..2d06c13b96ab8 100644 --- a/tests/ui/annotate-snippet/missing-type.rs +++ b/tests/ui/annotate-snippet/missing-type.rs @@ -1,5 +1,5 @@ //@ edition: 2015 -//@ compile-flags: --error-format human-annotate-rs -Z unstable-options +//@ compile-flags: --error-format human pub fn main() { let x: Iter; diff --git a/tests/ui/annotate-snippet/multiple-files.rs b/tests/ui/annotate-snippet/multiple-files.rs index c67a31d8f0714..060e817bea08a 100644 --- a/tests/ui/annotate-snippet/multiple-files.rs +++ b/tests/ui/annotate-snippet/multiple-files.rs @@ -1,5 +1,5 @@ //@ aux-build:other_file.rs -//@ compile-flags: --error-format human-annotate-rs -Z unstable-options +//@ compile-flags: --error-format human extern crate other_file; diff --git a/tests/ui/annotate-snippet/multispan.rs b/tests/ui/annotate-snippet/multispan.rs index c2054f62d24c5..adbbef6d42f75 100644 --- a/tests/ui/annotate-snippet/multispan.rs +++ b/tests/ui/annotate-snippet/multispan.rs @@ -1,5 +1,5 @@ //@ proc-macro: multispan.rs -//@ compile-flags: --error-format human-annotate-rs -Z unstable-options +//@ compile-flags: --error-format human #![feature(proc_macro_hygiene)] From 84f2854bc3bfea59aeb6fd23245a788196c9d4ff Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 16 Dec 2025 10:48:15 +0000 Subject: [PATCH 62/64] remove fixme & update stderr files --- .../src/annotate_snippet_emitter_writer.rs | 17 ----------------- src/tools/clippy/tests/ui/unit_arg.stderr | 3 --- tests/ui/attributes/crate-type-delimited.stderr | 1 - tests/ui/attributes/crate-type-empty.stderr | 1 - .../ui/attributes/crate-type-macro-call.stderr | 1 - .../generic_const_exprs/issue-105608.stderr | 1 - .../ice-line-bounds-issue-148732.stderr | 1 - tests/ui/macros/cfg_select.stderr | 2 -- .../issue-42234-unknown-receiver-type.stderr | 1 - .../structs/ice-line-bounds-issue-148684.stderr | 1 - 10 files changed, 29 deletions(-) diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 7f64dc3df23ed..9bb3189739582 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -303,17 +303,6 @@ impl AnnotateSnippetEmitter { } } - let suggestions_expected = suggestions - .iter() - .filter(|s| { - matches!( - s.style, - SuggestionStyle::HideCodeInline - | SuggestionStyle::ShowCode - | SuggestionStyle::ShowAlways - ) - }) - .count(); for suggestion in suggestions { match suggestion.style { SuggestionStyle::CompletelyHidden => { @@ -526,12 +515,6 @@ impl AnnotateSnippetEmitter { } } - // FIXME: This hack should be removed once annotate_snippets is the - // default emitter. - if suggestions_expected > 0 && report.is_empty() { - group = group.element(Padding); - } - if !group.is_empty() { report.push(group); } diff --git a/src/tools/clippy/tests/ui/unit_arg.stderr b/src/tools/clippy/tests/ui/unit_arg.stderr index 0dcfb02b9fa08..eb7c56c45b595 100644 --- a/src/tools/clippy/tests/ui/unit_arg.stderr +++ b/src/tools/clippy/tests/ui/unit_arg.stderr @@ -204,21 +204,18 @@ error: passing a unit value to a function | LL | fn_take_unit(mac!(def)); | ^^^^^^^^^^^^^^^^^^^^^^^ - | error: passing a unit value to a function --> tests/ui/unit_arg.rs:173:5 | LL | fn_take_unit(mac!(func Default::default)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | error: passing a unit value to a function --> tests/ui/unit_arg.rs:175:5 | LL | fn_take_unit(mac!(nonempty_block Default::default())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | error: aborting due to 13 previous errors diff --git a/tests/ui/attributes/crate-type-delimited.stderr b/tests/ui/attributes/crate-type-delimited.stderr index 23234efe169f1..e9616f27174c8 100644 --- a/tests/ui/attributes/crate-type-delimited.stderr +++ b/tests/ui/attributes/crate-type-delimited.stderr @@ -5,7 +5,6 @@ LL | #![crate_type(lib)] | ^^^^^^^^^^^^^^^^^^^ | = note: for more information, visit - | error: aborting due to 1 previous error diff --git a/tests/ui/attributes/crate-type-empty.stderr b/tests/ui/attributes/crate-type-empty.stderr index c1d474d9f17ff..b8eca61748ead 100644 --- a/tests/ui/attributes/crate-type-empty.stderr +++ b/tests/ui/attributes/crate-type-empty.stderr @@ -5,7 +5,6 @@ LL | #![crate_type] | ^^^^^^^^^^^^^^ | = note: for more information, visit - | error: aborting due to 1 previous error diff --git a/tests/ui/attributes/crate-type-macro-call.stderr b/tests/ui/attributes/crate-type-macro-call.stderr index cd17b324041bd..b3927fef47183 100644 --- a/tests/ui/attributes/crate-type-macro-call.stderr +++ b/tests/ui/attributes/crate-type-macro-call.stderr @@ -5,7 +5,6 @@ LL | #![crate_type = foo!()] | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, visit - | error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr b/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr index 1c97eaddfe1bb..cc35035edf95d 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr @@ -3,7 +3,6 @@ error[E0282]: type annotations needed | LL | Combination::<0>.and::<_>().and::<_>(); | ^^^ cannot infer type of the type parameter `M` declared on the method `and` - | error: aborting due to 1 previous error diff --git a/tests/ui/delegation/ice-line-bounds-issue-148732.stderr b/tests/ui/delegation/ice-line-bounds-issue-148732.stderr index 1f43ec335448b..f332bc6a7a210 100644 --- a/tests/ui/delegation/ice-line-bounds-issue-148732.stderr +++ b/tests/ui/delegation/ice-line-bounds-issue-148732.stderr @@ -5,7 +5,6 @@ LL | dbg!(b); | ^^^^^^^ expected named lifetime parameter | = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) - | error[E0425]: cannot find function `a` in this scope --> $DIR/ice-line-bounds-issue-148732.rs:1:7 diff --git a/tests/ui/macros/cfg_select.stderr b/tests/ui/macros/cfg_select.stderr index 5e2d705760cf6..510fc33d6d113 100644 --- a/tests/ui/macros/cfg_select.stderr +++ b/tests/ui/macros/cfg_select.stderr @@ -38,14 +38,12 @@ error[E0539]: malformed `cfg_select` macro input | LL | "str" => {} | ^^^^^ expected a valid identifier here - | error[E0539]: malformed `cfg_select` macro input --> $DIR/cfg_select.rs:80:5 | LL | a::b => {} | ^^^^ expected a valid identifier here - | error[E0537]: invalid predicate `a` --> $DIR/cfg_select.rs:85:5 diff --git a/tests/ui/span/issue-42234-unknown-receiver-type.stderr b/tests/ui/span/issue-42234-unknown-receiver-type.stderr index 10308ec07da5a..f16006a8e085b 100644 --- a/tests/ui/span/issue-42234-unknown-receiver-type.stderr +++ b/tests/ui/span/issue-42234-unknown-receiver-type.stderr @@ -16,7 +16,6 @@ error[E0282]: type annotations needed | LL | .sum::<_>() | ^^^ cannot infer type of the type parameter `S` declared on the method `sum` - | error: aborting due to 2 previous errors diff --git a/tests/ui/structs/ice-line-bounds-issue-148684.stderr b/tests/ui/structs/ice-line-bounds-issue-148684.stderr index f26d96cd1172b..71ed393bf0563 100644 --- a/tests/ui/structs/ice-line-bounds-issue-148684.stderr +++ b/tests/ui/structs/ice-line-bounds-issue-148684.stderr @@ -9,7 +9,6 @@ LL | | } ... LL | A(2, vec![]) | ^^^^^^^^^^^^ - | error: aborting due to 1 previous error From 0004d8d421f0e8bfb432cc2a4234ec0b33a4fbec Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 16 Dec 2025 08:36:33 -0800 Subject: [PATCH 63/64] Remove deny of manual-let-else --- compiler/rustc_ast/src/lib.rs | 1 - compiler/rustc_borrowck/src/lib.rs | 1 - compiler/rustc_const_eval/src/lib.rs | 1 - compiler/rustc_hir/src/lib.rs | 1 - compiler/rustc_hir_analysis/src/lib.rs | 1 - compiler/rustc_hir_typeck/src/lib.rs | 1 - compiler/rustc_lint/src/lib.rs | 1 - compiler/rustc_middle/src/lib.rs | 1 - compiler/rustc_resolve/src/lib.rs | 1 - 9 files changed, 9 deletions(-) diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 10a8e181c840e..cbdc89f9deedc 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -6,7 +6,6 @@ // tidy-alphabetical-start #![cfg_attr(bootstrap, feature(array_windows))] -#![deny(clippy::manual_let_else)] #![doc(test(attr(deny(warnings), allow(internal_features))))] #![feature(associated_type_defaults)] #![feature(box_patterns)] diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index d82357fca2d45..8d61ffde116c5 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2,7 +2,6 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![deny(clippy::manual_let_else)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(file_buffered)] diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 6c74ed2a5121d..2fce4b8c0566e 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -1,6 +1,5 @@ // tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] -#![deny(clippy::manual_let_else)] #![feature(array_try_map)] #![feature(assert_matches)] #![feature(box_patterns)] diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index c27954b6d14e4..7a5776f0d5a93 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -4,7 +4,6 @@ // tidy-alphabetical-start #![cfg_attr(bootstrap, feature(debug_closure_helpers))] -#![deny(clippy::manual_let_else)] #![feature(associated_type_defaults)] #![feature(closure_track_caller)] #![feature(const_default)] diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 79c5fbab1ffa2..538fb8c7df1ea 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -59,7 +59,6 @@ This API is completely unstable and subject to change. #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(bootstrap, feature(debug_closure_helpers))] -#![deny(clippy::manual_let_else)] #![feature(assert_matches)] #![feature(gen_blocks)] #![feature(if_let_guard)] diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 9ca5ddd494aeb..d3ef1d63e8ba9 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -1,5 +1,4 @@ // tidy-alphabetical-start -#![deny(clippy::manual_let_else)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 49929a0a9bc76..4e7a3e4051767 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -22,7 +22,6 @@ // tidy-alphabetical-start #![allow(internal_features)] #![cfg_attr(bootstrap, feature(array_windows))] -#![deny(clippy::manual_let_else)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(if_let_guard)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index ee3e89e57bd42..5f62d44df6b61 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -30,7 +30,6 @@ #![allow(rustc::direct_use_of_rustc_type_ir)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(bootstrap, feature(array_windows))] -#![deny(clippy::manual_let_else)] #![feature(allocator_api)] #![feature(assert_matches)] #![feature(associated_type_defaults)] diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b3141406e467e..775335e5008c3 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -10,7 +10,6 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![deny(clippy::manual_let_else)] #![feature(arbitrary_self_types)] #![feature(assert_matches)] #![feature(box_patterns)] From 4efe2681f75bc8fb3910f1bf183f4bfc70d7aca8 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Tue, 16 Dec 2025 22:27:42 +0530 Subject: [PATCH 64/64] std: io: error: Add comment for UEFI unpacked repr use The following commit adds the comment explaining the rational why UEFI uses unpacked representation on 64-bit platforms as opposed to bit-packed representation used in all other 64-bit platforms. Signed-off-by: Ayush Singh --- library/std/src/io/error.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 98b266663ad2f..528eb185df088 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -1,6 +1,13 @@ #[cfg(test)] mod tests; +// On 64-bit platforms, `io::Error` may use a bit-packed representation to +// reduce size. However, this representation assumes that error codes are +// always 32-bit wide. +// +// This assumption is invalid on 64-bit UEFI, where error codes are 64-bit. +// Therefore, the packed representation is explicitly disabled for UEFI +// targets, and the unpacked representation must be used instead. #[cfg(all(target_pointer_width = "64", not(target_os = "uefi")))] mod repr_bitpacked; #[cfg(all(target_pointer_width = "64", not(target_os = "uefi")))]