From 25ab022f2951318e8ffdec2d8566c3a7d164e00d Mon Sep 17 00:00:00 2001 From: xizheyin Date: Sun, 29 Jun 2025 15:37:28 +0800 Subject: [PATCH 01/20] move `tests/ui/resolve/suggest*` to `tests/ui/resolve/suggestions/` Signed-off-by: xizheyin --- .../auxiliary/suggest-constructor-cycle-error.rs | 0 tests/ui/resolve/{ => suggestions}/suggest-builder-fn.rs | 0 tests/ui/resolve/{ => suggestions}/suggest-builder-fn.stderr | 0 .../resolve/{ => suggestions}/suggest-constructor-cycle-error.rs | 0 .../{ => suggestions}/suggest-constructor-cycle-error.stderr | 0 .../suggest-import-without-clobbering-attrs.fixed | 0 .../{ => suggestions}/suggest-import-without-clobbering-attrs.rs | 0 .../suggest-import-without-clobbering-attrs.stderr | 0 .../ui/resolve/{ => suggestions}/suggest-path-for-tuple-struct.rs | 0 .../{ => suggestions}/suggest-path-for-tuple-struct.stderr | 0 .../{ => suggestions}/suggest-path-instead-of-mod-dot-item.rs | 0 .../{ => suggestions}/suggest-path-instead-of-mod-dot-item.stderr | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/resolve/{ => suggestions}/auxiliary/suggest-constructor-cycle-error.rs (100%) rename tests/ui/resolve/{ => suggestions}/suggest-builder-fn.rs (100%) rename tests/ui/resolve/{ => suggestions}/suggest-builder-fn.stderr (100%) rename tests/ui/resolve/{ => suggestions}/suggest-constructor-cycle-error.rs (100%) rename tests/ui/resolve/{ => suggestions}/suggest-constructor-cycle-error.stderr (100%) rename tests/ui/resolve/{ => suggestions}/suggest-import-without-clobbering-attrs.fixed (100%) rename tests/ui/resolve/{ => suggestions}/suggest-import-without-clobbering-attrs.rs (100%) rename tests/ui/resolve/{ => suggestions}/suggest-import-without-clobbering-attrs.stderr (100%) rename tests/ui/resolve/{ => suggestions}/suggest-path-for-tuple-struct.rs (100%) rename tests/ui/resolve/{ => suggestions}/suggest-path-for-tuple-struct.stderr (100%) rename tests/ui/resolve/{ => suggestions}/suggest-path-instead-of-mod-dot-item.rs (100%) rename tests/ui/resolve/{ => suggestions}/suggest-path-instead-of-mod-dot-item.stderr (100%) diff --git a/tests/ui/resolve/auxiliary/suggest-constructor-cycle-error.rs b/tests/ui/resolve/suggestions/auxiliary/suggest-constructor-cycle-error.rs similarity index 100% rename from tests/ui/resolve/auxiliary/suggest-constructor-cycle-error.rs rename to tests/ui/resolve/suggestions/auxiliary/suggest-constructor-cycle-error.rs diff --git a/tests/ui/resolve/suggest-builder-fn.rs b/tests/ui/resolve/suggestions/suggest-builder-fn.rs similarity index 100% rename from tests/ui/resolve/suggest-builder-fn.rs rename to tests/ui/resolve/suggestions/suggest-builder-fn.rs diff --git a/tests/ui/resolve/suggest-builder-fn.stderr b/tests/ui/resolve/suggestions/suggest-builder-fn.stderr similarity index 100% rename from tests/ui/resolve/suggest-builder-fn.stderr rename to tests/ui/resolve/suggestions/suggest-builder-fn.stderr diff --git a/tests/ui/resolve/suggest-constructor-cycle-error.rs b/tests/ui/resolve/suggestions/suggest-constructor-cycle-error.rs similarity index 100% rename from tests/ui/resolve/suggest-constructor-cycle-error.rs rename to tests/ui/resolve/suggestions/suggest-constructor-cycle-error.rs diff --git a/tests/ui/resolve/suggest-constructor-cycle-error.stderr b/tests/ui/resolve/suggestions/suggest-constructor-cycle-error.stderr similarity index 100% rename from tests/ui/resolve/suggest-constructor-cycle-error.stderr rename to tests/ui/resolve/suggestions/suggest-constructor-cycle-error.stderr diff --git a/tests/ui/resolve/suggest-import-without-clobbering-attrs.fixed b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed similarity index 100% rename from tests/ui/resolve/suggest-import-without-clobbering-attrs.fixed rename to tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed diff --git a/tests/ui/resolve/suggest-import-without-clobbering-attrs.rs b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs similarity index 100% rename from tests/ui/resolve/suggest-import-without-clobbering-attrs.rs rename to tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs diff --git a/tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.stderr similarity index 100% rename from tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr rename to tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.stderr diff --git a/tests/ui/resolve/suggest-path-for-tuple-struct.rs b/tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.rs similarity index 100% rename from tests/ui/resolve/suggest-path-for-tuple-struct.rs rename to tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.rs diff --git a/tests/ui/resolve/suggest-path-for-tuple-struct.stderr b/tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.stderr similarity index 100% rename from tests/ui/resolve/suggest-path-for-tuple-struct.stderr rename to tests/ui/resolve/suggestions/suggest-path-for-tuple-struct.stderr diff --git a/tests/ui/resolve/suggest-path-instead-of-mod-dot-item.rs b/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.rs similarity index 100% rename from tests/ui/resolve/suggest-path-instead-of-mod-dot-item.rs rename to tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.rs diff --git a/tests/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr similarity index 100% rename from tests/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr rename to tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr From 000f038e9999ebdbaf3167c42dadc3db872a5d3f Mon Sep 17 00:00:00 2001 From: xizheyin Date: Sun, 29 Jun 2025 15:38:09 +0800 Subject: [PATCH 02/20] Add ui test resolve/false-self-in-macro-issue-143134.rs Signed-off-by: xizheyin --- tests/ui/resolve/false-self-in-macro-issue-143134.rs | 10 ++++++++++ .../resolve/false-self-in-macro-issue-143134.stderr | 12 ++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 tests/ui/resolve/false-self-in-macro-issue-143134.rs create mode 100644 tests/ui/resolve/false-self-in-macro-issue-143134.stderr diff --git a/tests/ui/resolve/false-self-in-macro-issue-143134.rs b/tests/ui/resolve/false-self-in-macro-issue-143134.rs new file mode 100644 index 0000000000000..0983b8b3dc3c4 --- /dev/null +++ b/tests/ui/resolve/false-self-in-macro-issue-143134.rs @@ -0,0 +1,10 @@ +trait T { + fn f(self); + } + impl T for () { + fn f(self) { + let self = (); //~ ERROR expected unit struct, unit variant or constant, found local variable `self` + } +} + +fn main() {} diff --git a/tests/ui/resolve/false-self-in-macro-issue-143134.stderr b/tests/ui/resolve/false-self-in-macro-issue-143134.stderr new file mode 100644 index 0000000000000..43e77e183ae7a --- /dev/null +++ b/tests/ui/resolve/false-self-in-macro-issue-143134.stderr @@ -0,0 +1,12 @@ +error[E0424]: expected unit struct, unit variant or constant, found local variable `self` + --> $DIR/false-self-in-macro-issue-143134.rs:6:13 + | +LL | / fn f(self) { +LL | | let self = (); + | | ^^^^ `self` value is a keyword and may not be bound to variables or shadowed +LL | | } + | |_____- this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0424`. From 236b392904d234d9ec2968c55ae20132405a555d Mon Sep 17 00:00:00 2001 From: xizheyin Date: Sun, 29 Jun 2025 16:10:52 +0800 Subject: [PATCH 03/20] Return early when `self` resolve failure because of `let self = ...` Signed-off-by: xizheyin --- compiler/rustc_resolve/src/late/diagnostics.rs | 16 ++++++++++++---- tests/ui/error-codes/E0424.stderr | 2 -- .../false-self-in-macro-issue-143134.stderr | 7 ++----- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index e7b8c988cd4af..0b78835326fc3 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1183,15 +1183,23 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { _ => "`self` value is a keyword only available in methods with a `self` parameter", }, ); + + // using `let self` is wrong even if we're not in an associated method or if we're in a macro expansion. + // So, we should return early if we're in a pattern, see issue #143134. + if matches!(source, PathSource::Pat) { + return true; + } + let is_assoc_fn = self.self_type_is_available(); let self_from_macro = "a `self` parameter, but a macro invocation can only \ access identifiers it receives from parameters"; - if let Some((fn_kind, span)) = &self.diag_metadata.current_function { + if let Some((fn_kind, fn_span)) = &self.diag_metadata.current_function { // The current function has a `self` parameter, but we were unable to resolve // a reference to `self`. This can only happen if the `self` identifier we - // are resolving came from a different hygiene context. + // are resolving came from a different hygiene context or a variable binding. + // But variable binding error is returned early above. if fn_kind.decl().inputs.get(0).is_some_and(|p| p.is_self()) { - err.span_label(*span, format!("this function has {self_from_macro}")); + err.span_label(*fn_span, format!("this function has {self_from_macro}")); } else { let doesnt = if is_assoc_fn { let (span, sugg) = fn_kind @@ -1204,7 +1212,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // This avoids placing the suggestion into the visibility specifier. let span = fn_kind .ident() - .map_or(*span, |ident| span.with_lo(ident.span.hi())); + .map_or(*fn_span, |ident| fn_span.with_lo(ident.span.hi())); ( self.r .tcx diff --git a/tests/ui/error-codes/E0424.stderr b/tests/ui/error-codes/E0424.stderr index d02da3e4ecb8a..831a070bf6cc6 100644 --- a/tests/ui/error-codes/E0424.stderr +++ b/tests/ui/error-codes/E0424.stderr @@ -40,8 +40,6 @@ LL | fn qux(&self) { error[E0424]: expected unit struct, unit variant or constant, found module `self` --> $DIR/E0424.rs:20:9 | -LL | fn main () { - | ---- this function can't have a `self` parameter LL | let self = "self"; | ^^^^ `self` value is a keyword and may not be bound to variables or shadowed diff --git a/tests/ui/resolve/false-self-in-macro-issue-143134.stderr b/tests/ui/resolve/false-self-in-macro-issue-143134.stderr index 43e77e183ae7a..48c979575ea8c 100644 --- a/tests/ui/resolve/false-self-in-macro-issue-143134.stderr +++ b/tests/ui/resolve/false-self-in-macro-issue-143134.stderr @@ -1,11 +1,8 @@ error[E0424]: expected unit struct, unit variant or constant, found local variable `self` --> $DIR/false-self-in-macro-issue-143134.rs:6:13 | -LL | / fn f(self) { -LL | | let self = (); - | | ^^^^ `self` value is a keyword and may not be bound to variables or shadowed -LL | | } - | |_____- this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters +LL | let self = (); + | ^^^^ `self` value is a keyword and may not be bound to variables or shadowed error: aborting due to 1 previous error From 1a1b52acbf44f55f7458dd38b260479843fe3810 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 4 Jul 2025 11:33:36 +0000 Subject: [PATCH 04/20] clippy fix: indentation --- library/core/src/alloc/layout.rs | 4 ++-- library/core/src/cell.rs | 28 ++++++++++++++-------------- library/core/src/error.rs | 24 ++++++++++++------------ library/core/src/fmt/mod.rs | 14 +++++++------- library/core/src/marker.rs | 4 ++-- library/core/src/ops/drop.rs | 2 +- library/core/src/option.rs | 1 + library/core/src/pin.rs | 16 ++++++++-------- 8 files changed, 47 insertions(+), 46 deletions(-) diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 380f67f91f947..49275975f046f 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -61,8 +61,8 @@ impl Layout { /// * `align` must be a power of two, /// /// * `size`, when rounded up to the nearest multiple of `align`, - /// must not overflow `isize` (i.e., the rounded value must be - /// less than or equal to `isize::MAX`). + /// must not overflow `isize` (i.e., the rounded value must be + /// less than or equal to `isize::MAX`). #[stable(feature = "alloc_layout", since = "1.28.0")] #[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")] #[inline] diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 7ce03e3d83198..2cd5c19bf4e66 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1941,21 +1941,21 @@ impl fmt::Display for RefMut<'_, T> { /// The precise Rust aliasing rules are somewhat in flux, but the main points are not contentious: /// /// - If you create a safe reference with lifetime `'a` (either a `&T` or `&mut T` reference), then -/// you must not access the data in any way that contradicts that reference for the remainder of -/// `'a`. For example, this means that if you take the `*mut T` from an `UnsafeCell` and cast it -/// to an `&T`, then the data in `T` must remain immutable (modulo any `UnsafeCell` data found -/// within `T`, of course) until that reference's lifetime expires. Similarly, if you create a `&mut -/// T` reference that is released to safe code, then you must not access the data within the -/// `UnsafeCell` until that reference expires. +/// you must not access the data in any way that contradicts that reference for the remainder of +/// `'a`. For example, this means that if you take the `*mut T` from an `UnsafeCell` and cast it +/// to an `&T`, then the data in `T` must remain immutable (modulo any `UnsafeCell` data found +/// within `T`, of course) until that reference's lifetime expires. Similarly, if you create a +/// `&mut T` reference that is released to safe code, then you must not access the data within the +/// `UnsafeCell` until that reference expires. /// /// - For both `&T` without `UnsafeCell<_>` and `&mut T`, you must also not deallocate the data -/// until the reference expires. As a special exception, given an `&T`, any part of it that is -/// inside an `UnsafeCell<_>` may be deallocated during the lifetime of the reference, after the -/// last time the reference is used (dereferenced or reborrowed). Since you cannot deallocate a part -/// of what a reference points to, this means the memory an `&T` points to can be deallocated only if -/// *every part of it* (including padding) is inside an `UnsafeCell`. +/// until the reference expires. As a special exception, given an `&T`, any part of it that is +/// inside an `UnsafeCell<_>` may be deallocated during the lifetime of the reference, after the +/// last time the reference is used (dereferenced or reborrowed). Since you cannot deallocate a part +/// of what a reference points to, this means the memory an `&T` points to can be deallocated only if +/// *every part of it* (including padding) is inside an `UnsafeCell`. /// -/// However, whenever a `&UnsafeCell` is constructed or dereferenced, it must still point to +/// However, whenever a `&UnsafeCell` is constructed or dereferenced, it must still point to /// live memory and the compiler is allowed to insert spurious reads if it can prove that this /// memory has not yet been deallocated. /// @@ -1963,10 +1963,10 @@ impl fmt::Display for RefMut<'_, T> { /// for single-threaded code: /// /// 1. A `&T` reference can be released to safe code and there it can co-exist with other `&T` -/// references, but not with a `&mut T` +/// references, but not with a `&mut T` /// /// 2. A `&mut T` reference may be released to safe code provided neither other `&mut T` nor `&T` -/// co-exist with it. A `&mut T` must always be unique. +/// co-exist with it. A `&mut T` must always be unique. /// /// Note that whilst mutating the contents of an `&UnsafeCell` (even while other /// `&UnsafeCell` references alias the cell) is diff --git a/library/core/src/error.rs b/library/core/src/error.rs index 7f5c6ac42bc1c..88e633c9eef3f 100644 --- a/library/core/src/error.rs +++ b/library/core/src/error.rs @@ -447,28 +447,28 @@ where /// separated by API boundaries: /// /// * Consumer - the consumer requests objects using a Request instance; eg a crate that offers -/// fancy `Error`/`Result` reporting to users wants to request a Backtrace from a given `dyn Error`. +/// fancy `Error`/`Result` reporting to users wants to request a Backtrace from a given `dyn Error`. /// /// * Producer - the producer provides objects when requested via Request; eg. a library with an -/// an `Error` implementation that automatically captures backtraces at the time instances are -/// created. +/// an `Error` implementation that automatically captures backtraces at the time instances are +/// created. /// /// The consumer only needs to know where to submit their request and are expected to handle the /// request not being fulfilled by the use of `Option` in the responses offered by the producer. /// /// * A Producer initializes the value of one of its fields of a specific type. (or is otherwise -/// prepared to generate a value requested). eg, `backtrace::Backtrace` or -/// `std::backtrace::Backtrace` +/// prepared to generate a value requested). eg, `backtrace::Backtrace` or +/// `std::backtrace::Backtrace` /// * A Consumer requests an object of a specific type (say `std::backtrace::Backtrace`). In the -/// case of a `dyn Error` trait object (the Producer), there are functions called `request_ref` and -/// `request_value` to simplify obtaining an `Option` for a given type. +/// case of a `dyn Error` trait object (the Producer), there are functions called `request_ref` and +/// `request_value` to simplify obtaining an `Option` for a given type. /// * The Producer, when requested, populates the given Request object which is given as a mutable -/// reference. +/// reference. /// * The Consumer extracts a value or reference to the requested type from the `Request` object -/// wrapped in an `Option`; in the case of `dyn Error` the aforementioned `request_ref` and ` -/// request_value` methods mean that `dyn Error` users don't have to deal with the `Request` type at -/// all (but `Error` implementors do). The `None` case of the `Option` suggests only that the -/// Producer cannot currently offer an instance of the requested type, not it can't or never will. +/// wrapped in an `Option`; in the case of `dyn Error` the aforementioned `request_ref` and ` +/// request_value` methods mean that `dyn Error` users don't have to deal with the `Request` type at +/// all (but `Error` implementors do). The `None` case of the `Option` suggests only that the +/// Producer cannot currently offer an instance of the requested type, not it can't or never will. /// /// # Examples /// diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index c593737af8ac6..223b50dda09b6 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -349,10 +349,10 @@ impl FormattingOptions { /// Sets or removes the sign (the `+` or the `-` flag). /// /// - `+`: This is intended for numeric types and indicates that the sign - /// should always be printed. By default only the negative sign of signed - /// values is printed, and the sign of positive or unsigned values is - /// omitted. This flag indicates that the correct sign (+ or -) should - /// always be printed. + /// should always be printed. By default only the negative sign of signed + /// values is printed, and the sign of positive or unsigned values is + /// omitted. This flag indicates that the correct sign (+ or -) should + /// always be printed. /// - `-`: Currently not used #[unstable(feature = "formatting_options", issue = "118117")] pub fn sign(&mut self, sign: Option) -> &mut Self { @@ -439,9 +439,9 @@ impl FormattingOptions { /// Sets or removes the precision. /// /// - For non-numeric types, this can be considered a “maximum width”. If - /// the resulting string is longer than this width, then it is truncated - /// down to this many characters and that truncated value is emitted with - /// proper fill, alignment and width if those parameters are set. + /// the resulting string is longer than this width, then it is truncated + /// down to this many characters and that truncated value is emitted with + /// proper fill, alignment and width if those parameters are set. /// - For integral types, this is ignored. /// - For floating-point types, this indicates how many digits after the /// decimal point should be printed. diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 67f95a02af3c1..0f9a1ff02d164 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -211,8 +211,8 @@ pub trait PointeeSized { /// - The type is sized. /// - The type outlives `'a`. /// - Structs `Foo<..., T1, ..., Tn, ...>` implement `Unsize>` -/// where any number of (type and const) parameters may be changed if all of these conditions -/// are met: +/// where any number of (type and const) parameters may be changed if all of these conditions +/// are met: /// - Only the last field of `Foo` has a type involving the parameters `T1`, ..., `Tn`. /// - All other parameters of the struct are equal. /// - `Field: Unsize>`, where `Field<...>` stands for the actual diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs index 5d040804a8d1c..bbef702320715 100644 --- a/library/core/src/ops/drop.rs +++ b/library/core/src/ops/drop.rs @@ -11,7 +11,7 @@ /// This destructor consists of two components: /// - A call to `Drop::drop` for that value, if this special `Drop` trait is implemented for its type. /// - The automatically generated "drop glue" which recursively calls the destructors -/// of all the fields of this value. +/// of all the fields of this value. /// /// As Rust automatically calls the destructors of all contained fields, /// you don't have to implement `Drop` in most cases. But there are some cases where diff --git a/library/core/src/option.rs b/library/core/src/option.rs index f2a1e901188ff..f83a73fa56671 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -125,6 +125,7 @@ //! `Option::::None` //! - `transmute::<_, [u8; size_of::()]>(Option::::None)` is sound and produces //! `[0u8; size_of::()]` +//! //! These cases are identified by the second column: //! //! | `T` | Transmuting between `[0u8; size_of::()]` and `Option::::None` sound? | diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 3ca6feb679b73..14bf7ba90150e 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -137,10 +137,10 @@ //! 2. An operation causes the value to depend on its own address not changing //! * e.g. calling [`poll`] for the first time on the produced [`Future`] //! 3. Further pieces of the safe interface of the type use internal [`unsafe`] operations which -//! assume that the address of the value is stable +//! assume that the address of the value is stable //! * e.g. subsequent calls to [`poll`] //! 4. Before the value is invalidated (e.g. deallocated), it is *dropped*, giving it a chance to -//! notify anything with pointers to itself that those pointers will be invalidated +//! notify anything with pointers to itself that those pointers will be invalidated //! * e.g. [`drop`]ping the [`Future`] [^pin-drop-future] //! //! There are two possible ways to ensure the invariants required for 2. and 3. above (which @@ -148,8 +148,8 @@ //! //! 1. Have the value detect when it is moved and update all the pointers that point to itself. //! 2. Guarantee that the address of the value does not change (and that memory is not re-used -//! for anything else) during the time that the pointers to it are expected to be valid to -//! dereference. +//! for anything else) during the time that the pointers to it are expected to be valid to +//! dereference. //! //! Since, as we discussed, Rust can move values without notifying them that they have moved, the //! first option is ruled out. @@ -160,11 +160,11 @@ //! be able to enforce this invariant in Rust: //! //! 1. Offer a wholly `unsafe` API to interact with the object, thus requiring every caller to -//! uphold the invariant themselves +//! uphold the invariant themselves //! 2. Store the value that must not be moved behind a carefully managed pointer internal to -//! the object +//! the object //! 3. Leverage the type system to encode and enforce this invariant by presenting a restricted -//! API surface to interact with *any* object that requires these invariants +//! API surface to interact with *any* object that requires these invariants //! //! The first option is quite obviously undesirable, as the [`unsafe`]ty of the interface will //! become viral throughout all code that interacts with the object. @@ -530,7 +530,7 @@ //! but it also implies that, //! //! 2. The memory location that stores the value must not get invalidated or otherwise repurposed -//! during the lifespan of the pinned value until its [`drop`] returns or panics +//! during the lifespan of the pinned value until its [`drop`] returns or panics //! //! This point is subtle but required for intrusive data structures to be implemented soundly. //! From 995eeeb54cda2f3c7884e14a82bbe1f279143388 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 5 Jul 2025 17:47:28 +0000 Subject: [PATCH 05/20] Don't call predicates_of on a dummy obligation cause's body id --- .../src/error_reporting/traits/ambiguity.rs | 33 +++++++++++-------- .../ambiguity-in-dropck-err-reporting.rs | 18 ++++++++++ .../ambiguity-in-dropck-err-reporting.stderr | 19 +++++++++++ 3 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.rs create mode 100644 tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 39f115ce0cd56..a8ba1baf6b9bf 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -4,7 +4,7 @@ use rustc_errors::{Applicability, Diag, E0283, E0284, E0790, MultiSpan, struct_s use rustc_hir as hir; use rustc_hir::LangItem; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; use rustc_hir::intravisit::Visitor as _; use rustc_infer::infer::{BoundRegionConversionTime, InferCtxt}; use rustc_infer::traits::util::elaborate; @@ -128,19 +128,26 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( }, ); - let predicates = - tcx.predicates_of(obligation.cause.body_id.to_def_id()).instantiate_identity(tcx); - for (pred, span) in elaborate(tcx, predicates.into_iter()) { - let kind = pred.kind(); - if let ty::ClauseKind::Trait(trait_pred) = kind.skip_binder() - && param_env_candidate_may_apply(kind.rebind(trait_pred)) - { - if kind.rebind(trait_pred.trait_ref) - == ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_pred.def_id())) + // If our `body_id` has been set (and isn't just from a dummy obligation cause), + // then try to look for a param-env clause that would apply. The way we compute + // this is somewhat manual, since we need the spans, so we elaborate this directly + // from `predicates_of` rather than actually looking at the param-env which + // otherwise would be more appropriate. + let body_id = obligation.cause.body_id; + if body_id != CRATE_DEF_ID { + let predicates = tcx.predicates_of(body_id.to_def_id()).instantiate_identity(tcx); + for (pred, span) in elaborate(tcx, predicates.into_iter()) { + let kind = pred.kind(); + if let ty::ClauseKind::Trait(trait_pred) = kind.skip_binder() + && param_env_candidate_may_apply(kind.rebind(trait_pred)) { - ambiguities.push(CandidateSource::ParamEnv(tcx.def_span(trait_pred.def_id()))) - } else { - ambiguities.push(CandidateSource::ParamEnv(span)) + if kind.rebind(trait_pred.trait_ref) + == ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_pred.def_id())) + { + ambiguities.push(CandidateSource::ParamEnv(tcx.def_span(trait_pred.def_id()))) + } else { + ambiguities.push(CandidateSource::ParamEnv(span)) + } } } } diff --git a/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.rs b/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.rs new file mode 100644 index 0000000000000..ad313823fe40e --- /dev/null +++ b/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.rs @@ -0,0 +1,18 @@ +// Regression test for #143481, where we were calling `predicates_of` on +// a Crate HIR node because we were using a dummy obligation cause's body id +// without checking that it was meaningful first. + +trait Role { + type Inner; +} +struct HandshakeCallback(C); +impl Role for HandshakeCallback { + //~^ ERROR missing generics + type Inner = usize; +} +struct Handshake(R::Inner); +fn accept() -> Handshake> { + todo!() +} + +fn main() {} diff --git a/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.stderr b/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.stderr new file mode 100644 index 0000000000000..17ace03e891f2 --- /dev/null +++ b/tests/ui/traits/error-reporting/ambiguity-in-dropck-err-reporting.stderr @@ -0,0 +1,19 @@ +error[E0107]: missing generics for struct `HandshakeCallback` + --> $DIR/ambiguity-in-dropck-err-reporting.rs:9:25 + | +LL | impl Role for HandshakeCallback { + | ^^^^^^^^^^^^^^^^^ expected 1 generic argument + | +note: struct defined here, with 1 generic parameter: `C` + --> $DIR/ambiguity-in-dropck-err-reporting.rs:8:8 + | +LL | struct HandshakeCallback(C); + | ^^^^^^^^^^^^^^^^^ - +help: add missing generic argument + | +LL | impl Role for HandshakeCallback { + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. From b63f920ccf6e148547aea4c0fd045c4536aac483 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 6 Jul 2025 17:30:09 +0000 Subject: [PATCH 06/20] More carefully consider span context when suggesting remove &mut --- .../src/error_reporting/traits/suggestions.rs | 13 ++++++----- tests/ui/suggestions/suggest-remove-refs-6.rs | 12 ++++++++++ .../suggestions/suggest-remove-refs-6.stderr | 22 +++++++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 tests/ui/suggestions/suggest-remove-refs-6.rs create mode 100644 tests/ui/suggestions/suggest-remove-refs-6.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 362052e9fdbdd..1dc1588842f2c 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1511,12 +1511,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { 'outer: loop { while let hir::ExprKind::AddrOf(_, _, borrowed) = expr.kind { count += 1; - let span = if expr.span.eq_ctxt(borrowed.span) { - expr.span.until(borrowed.span) - } else { - expr.span.with_hi(expr.span.lo() + BytePos(1)) - }; + let span = + if let Some(borrowed_span) = borrowed.span.find_ancestor_inside(expr.span) { + expr.span.until(borrowed_span) + } else { + break 'outer; + }; + // Double check that the span we extracted actually corresponds to a borrow, + // rather than some macro garbage. match self.tcx.sess.source_map().span_to_snippet(span) { Ok(snippet) if snippet.starts_with("&") => {} _ => break 'outer, diff --git a/tests/ui/suggestions/suggest-remove-refs-6.rs b/tests/ui/suggestions/suggest-remove-refs-6.rs new file mode 100644 index 0000000000000..0d06aed480688 --- /dev/null +++ b/tests/ui/suggestions/suggest-remove-refs-6.rs @@ -0,0 +1,12 @@ +// Regression test for #143523. + +trait Trait {} + +impl Trait for Vec {} + +fn foo(_: impl Trait) {} + +fn main() { + foo(&mut vec![1]); + //~^ ERROR the trait bound `&mut Vec<{integer}>: Trait` is not satisfied +} diff --git a/tests/ui/suggestions/suggest-remove-refs-6.stderr b/tests/ui/suggestions/suggest-remove-refs-6.stderr new file mode 100644 index 0000000000000..bdc5a8a904909 --- /dev/null +++ b/tests/ui/suggestions/suggest-remove-refs-6.stderr @@ -0,0 +1,22 @@ +error[E0277]: the trait bound `&mut Vec<{integer}>: Trait` is not satisfied + --> $DIR/suggest-remove-refs-6.rs:10:9 + | +LL | foo(&mut vec![1]); + | --- ^^^^^^^^^^^^ the trait `Trait` is not implemented for `&mut Vec<{integer}>` + | | + | required by a bound introduced by this call + | +note: required by a bound in `foo` + --> $DIR/suggest-remove-refs-6.rs:7:16 + | +LL | fn foo(_: impl Trait) {} + | ^^^^^ required by this bound in `foo` +help: consider removing the leading `&`-reference + | +LL - foo(&mut vec![1]); +LL + foo(vec![1]); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From b4e68e212ece6896ea574c6345e14d4350c5c517 Mon Sep 17 00:00:00 2001 From: Bastian Kersting Date: Wed, 2 Jul 2025 20:33:28 +0300 Subject: [PATCH 07/20] Respect endianness correctly in CheckEnums test suite The endianness can change the test expectation for the enum check. This change is fixing the failing tests on big endian by changing the tests so that they behave the same as on little endian. --- ...non_enum_break.rs => convert_non_integer_break.rs} | 7 +++---- ...he_break.rs => convert_non_integer_niche_break.rs} | 0 ...um_niche_ok.rs => convert_non_integer_niche_ok.rs} | 0 ...nvert_non_enum_ok.rs => convert_non_integer_ok.rs} | 7 +++---- tests/ui/mir/enum/niche_option_tuple_break.rs | 11 ++++++----- tests/ui/mir/enum/with_niche_int_break.rs | 4 ++-- 6 files changed, 14 insertions(+), 15 deletions(-) rename tests/ui/mir/enum/{convert_non_enum_break.rs => convert_non_integer_break.rs} (84%) rename tests/ui/mir/enum/{convert_non_enum_niche_break.rs => convert_non_integer_niche_break.rs} (100%) rename tests/ui/mir/enum/{convert_non_enum_niche_ok.rs => convert_non_integer_niche_ok.rs} (100%) rename tests/ui/mir/enum/{convert_non_enum_ok.rs => convert_non_integer_ok.rs} (82%) diff --git a/tests/ui/mir/enum/convert_non_enum_break.rs b/tests/ui/mir/enum/convert_non_integer_break.rs similarity index 84% rename from tests/ui/mir/enum/convert_non_enum_break.rs rename to tests/ui/mir/enum/convert_non_integer_break.rs index de062c39907a7..29795190bf6a0 100644 --- a/tests/ui/mir/enum/convert_non_enum_break.rs +++ b/tests/ui/mir/enum/convert_non_integer_break.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -C debug-assertions -//@ error-pattern: trying to construct an enum from an invalid value 0x10000 +//@ error-pattern: trying to construct an enum from an invalid value #[allow(dead_code)] #[repr(u32)] @@ -11,10 +11,9 @@ enum Foo { #[allow(dead_code)] struct Bar { - a: u16, - b: u16, + a: u32, } fn main() { - let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 0, b: 1 }) }; + let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 3 }) }; } diff --git a/tests/ui/mir/enum/convert_non_enum_niche_break.rs b/tests/ui/mir/enum/convert_non_integer_niche_break.rs similarity index 100% rename from tests/ui/mir/enum/convert_non_enum_niche_break.rs rename to tests/ui/mir/enum/convert_non_integer_niche_break.rs diff --git a/tests/ui/mir/enum/convert_non_enum_niche_ok.rs b/tests/ui/mir/enum/convert_non_integer_niche_ok.rs similarity index 100% rename from tests/ui/mir/enum/convert_non_enum_niche_ok.rs rename to tests/ui/mir/enum/convert_non_integer_niche_ok.rs diff --git a/tests/ui/mir/enum/convert_non_enum_ok.rs b/tests/ui/mir/enum/convert_non_integer_ok.rs similarity index 82% rename from tests/ui/mir/enum/convert_non_enum_ok.rs rename to tests/ui/mir/enum/convert_non_integer_ok.rs index 37fc64342ca93..c98315313863d 100644 --- a/tests/ui/mir/enum/convert_non_enum_ok.rs +++ b/tests/ui/mir/enum/convert_non_integer_ok.rs @@ -10,11 +10,10 @@ enum Foo { #[allow(dead_code)] struct Bar { - a: u16, - b: u16, + a: u32, } fn main() { - let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 0, b: 0 }) }; - let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 1, b: 0 }) }; + let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 0 }) }; + let _val: Foo = unsafe { std::mem::transmute::<_, Foo>(Bar { a: 1 }) }; } diff --git a/tests/ui/mir/enum/niche_option_tuple_break.rs b/tests/ui/mir/enum/niche_option_tuple_break.rs index 43eef3a4cc5f0..affdc4784a3f4 100644 --- a/tests/ui/mir/enum/niche_option_tuple_break.rs +++ b/tests/ui/mir/enum/niche_option_tuple_break.rs @@ -1,8 +1,9 @@ //@ run-fail //@ compile-flags: -C debug-assertions -//@ error-pattern: trying to construct an enum from an invalid value 0x3 +//@ error-pattern: trying to construct an enum from an invalid value #[allow(dead_code)] +#[repr(u32)] enum Foo { A, B, @@ -10,11 +11,11 @@ enum Foo { #[allow(dead_code)] struct Bar { - a: usize, - b: usize, + a: u32, + b: u32, } fn main() { - let _val: Option<(usize, Foo)> = - unsafe { std::mem::transmute::<_, Option<(usize, Foo)>>(Bar { a: 3, b: 3 }) }; + let _val: Option<(u32, Foo)> = + unsafe { std::mem::transmute::<_, Option<(u32, Foo)>>(Bar { a: 3, b: 3 }) }; } diff --git a/tests/ui/mir/enum/with_niche_int_break.rs b/tests/ui/mir/enum/with_niche_int_break.rs index 0ec60a33564af..6a97eaa8f4f5b 100644 --- a/tests/ui/mir/enum/with_niche_int_break.rs +++ b/tests/ui/mir/enum/with_niche_int_break.rs @@ -1,6 +1,6 @@ //@ run-fail //@ compile-flags: -C debug-assertions -//@ error-pattern: trying to construct an enum from an invalid value 0x4 +//@ error-pattern: trying to construct an enum from an invalid value #[allow(dead_code)] #[repr(u16)] @@ -17,5 +17,5 @@ enum Nested { } fn main() { - let _val: Nested = unsafe { std::mem::transmute::(4) }; + let _val: Nested = unsafe { std::mem::transmute::(u32::MAX) }; } From e2891c0fb9060f80e6aa24e0dc0a9c43b0861b8f Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 7 Jul 2025 14:54:50 -0400 Subject: [PATCH 08/20] configure.py: Write last key in each section The loop that writes the keys in each section of bootstrap.toml accumulates all the commented lines before a given key and emits them when it reaches the next key in the section. This ends up dropping lines accumulated for the last key --- src/bootstrap/configure.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index c077555b90699..bec7a1c41b451 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -752,6 +752,10 @@ def write_uncommented(target, f): is_comment = True continue is_comment = is_comment and line.startswith("#") + # Write the last accumulated block + if len(block) > 0 and not is_comment: + for ln in block: + f.write(ln + "\n") return f From b6d21308672c9a0aa5c73beeb1d528aab3d347ed Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 7 Jul 2025 15:45:18 -0400 Subject: [PATCH 09/20] Add docstring --- src/bootstrap/configure.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index bec7a1c41b451..94e02f942dce7 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -739,6 +739,10 @@ def configure_file(sections, top_level_keys, targets, config): def write_uncommented(target, f): + """Writes each block in 'target' that is not composed entirely of comments to 'f'. + + A block is a sequence of non-empty lines separated by empty lines. + """ block = [] is_comment = True From 045557797431bfff807145341efbe8f8fb08817e Mon Sep 17 00:00:00 2001 From: Dillon Amburgey Date: Tue, 8 Jul 2025 06:17:03 -0500 Subject: [PATCH 10/20] fix: correct parameter names in LLVMRustBuildMinNum and LLVMRustBuildMaxNum FFI declarations --- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 91ada856d5977..b9dd10ff014fe 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1980,12 +1980,12 @@ unsafe extern "C" { pub(crate) fn LLVMRustBuildMinNum<'a>( B: &Builder<'a>, LHS: &'a Value, - LHS: &'a Value, + RHS: &'a Value, ) -> &'a Value; pub(crate) fn LLVMRustBuildMaxNum<'a>( B: &Builder<'a>, LHS: &'a Value, - LHS: &'a Value, + RHS: &'a Value, ) -> &'a Value; // Atomic Operations From 3ba8e330f9960a52b2c8ca10c8cba425514919f9 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 8 Jul 2025 07:34:51 -0400 Subject: [PATCH 11/20] Rewrite for clarity move common code to a helper function Co-Authored-By: Kobzol --- src/bootstrap/configure.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 94e02f942dce7..86208b942614e 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -744,22 +744,24 @@ def write_uncommented(target, f): A block is a sequence of non-empty lines separated by empty lines. """ block = [] - is_comment = True + + def flush(last): + # If the block is entiry made of comments, ignore it + entire_block_comments = all(ln.startswith("#") or ln == "" for ln in block) + if not entire_block_comments and len(block) > 0: + for line in block: + f.write(line + "\n") + # Required to output a newline before the start of a new section + if last: + f.write("\n") + block.clear() for line in target: block.append(line) if len(line) == 0: - if not is_comment: - for ln in block: - f.write(ln + "\n") - block = [] - is_comment = True - continue - is_comment = is_comment and line.startswith("#") - # Write the last accumulated block - if len(block) > 0 and not is_comment: - for ln in block: - f.write(ln + "\n") + flush(last=False) + + flush(last=True) return f From c4bf37d35824cf22dade0c1c4595186a29a8714d Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 2 Jul 2025 18:10:57 +0200 Subject: [PATCH 12/20] Always inline InterpCx::layout_of after perf regression --- compiler/rustc_const_eval/src/interpret/eval_context.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 068d6369f8769..41fc8d47cd369 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -96,7 +96,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// This inherent method takes priority over the trait method with the same name in LayoutOf, /// and allows wrapping the actual [LayoutOf::layout_of] with a tracing span. /// See [LayoutOf::layout_of] for the original documentation. - #[inline] + #[inline(always)] pub fn layout_of( &self, ty: Ty<'tcx>, From 07143afee43a4b516ca446e5e49570411043dfdb Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 5 Jul 2025 11:13:04 +0200 Subject: [PATCH 13/20] Replace TRACING_ENABLED with enter_trace_span() Hopefully this will make tracing calls be optimized out properly when tracing is disabled --- .../rustc_const_eval/src/interpret/machine.rs | 20 +++++++++------- .../rustc_const_eval/src/interpret/mod.rs | 1 + .../rustc_const_eval/src/interpret/util.rs | 23 +++++++++---------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 844c19fea2dba..33afadd94f56b 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -18,8 +18,8 @@ use rustc_target::callconv::FnAbi; use super::{ AllocBytes, AllocId, AllocKind, AllocRange, Allocation, CTFE_ALLOC_SALT, ConstAllocation, - CtfeProvenance, FnArg, Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, MemoryKind, - Misalignment, OpTy, PlaceTy, Pointer, Provenance, RangeSet, interp_ok, throw_unsup, + CtfeProvenance, EnteredTraceSpan, FnArg, Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, + MemoryKind, Misalignment, OpTy, PlaceTy, Pointer, Provenance, RangeSet, interp_ok, throw_unsup, }; /// Data returned by [`Machine::after_stack_pop`], and consumed by @@ -147,12 +147,6 @@ pub trait Machine<'tcx>: Sized { /// already been checked before. const ALL_CONSTS_ARE_PRECHECKED: bool = true; - /// Determines whether rustc_const_eval functions that make use of the [Machine] should make - /// tracing calls (to the `tracing` library). By default this is `false`, meaning the tracing - /// calls will supposedly be optimized out. This flag is set to `true` inside Miri, to allow - /// tracing the interpretation steps, among other things. - const TRACING_ENABLED: bool = false; - /// Whether memory accesses should be alignment-checked. fn enforce_alignment(ecx: &InterpCx<'tcx, Self>) -> bool; @@ -634,6 +628,16 @@ pub trait Machine<'tcx>: Sized { /// Compute the value passed to the constructors of the `AllocBytes` type for /// abstract machine allocations. fn get_default_alloc_params(&self) -> ::AllocParams; + + /// Allows enabling/disabling tracing calls from within `rustc_const_eval` at compile time, by + /// delegating the entering of [tracing::Span]s to implementors of the [Machine] trait. The + /// default implementation corresponds to tracing being disabled, meaning the tracing calls will + /// supposedly be optimized out completely. To enable tracing, override this trait method and + /// return `span.entered()`. Also see [crate::enter_trace_span]. + #[must_use] + fn enter_trace_span(_span: tracing::Span) -> impl EnteredTraceSpan { + () + } } /// A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index 8303f891f98b1..2fc372dd01978 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -37,6 +37,7 @@ pub use self::place::{MPlaceTy, MemPlaceMeta, PlaceTy, Writeable}; use self::place::{MemPlace, Place}; pub use self::projection::{OffsetMode, Projectable}; pub use self::stack::{Frame, FrameInfo, LocalState, ReturnContinuation, StackPopInfo}; +pub use self::util::EnteredTraceSpan; pub(crate) use self::util::create_static_alloc; pub use self::validity::{CtfeValidationMode, RangeSet, RefTracking}; pub use self::visitor::ValueVisitor; diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index 99add01f95c60..eeab32fd79c67 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -46,21 +46,20 @@ pub(crate) fn create_static_alloc<'tcx>( interp_ok(ecx.ptr_to_mplace(Pointer::from(alloc_id).into(), layout)) } -/// This struct is needed to enforce `#[must_use]` on [tracing::span::EnteredSpan] -/// while wrapping them in an `Option`. -#[must_use] -pub enum MaybeEnteredSpan { - Some(tracing::span::EnteredSpan), - None, -} +/// A marker trait returned by [crate::interpret::Machine::enter_trace_span], identifying either a +/// real [tracing::span::EnteredSpan] in case tracing is enabled, or the dummy type `()` when +/// tracing is disabled. +pub trait EnteredTraceSpan {} +impl EnteredTraceSpan for () {} +impl EnteredTraceSpan for tracing::span::EnteredSpan {} +/// Shortand for calling [crate::interpret::Machine::enter_trace_span] on a [tracing::info_span]. +/// This is supposed to be compiled out when [crate::interpret::Machine::enter_trace_span] has the +/// default implementation (i.e. when it does not actually enter the span but instead returns `()`). +/// Note: the result of this macro **must be used** because the span is exited when it's dropped. #[macro_export] macro_rules! enter_trace_span { ($machine:ident, $($tt:tt)*) => { - if $machine::TRACING_ENABLED { - $crate::interpret::util::MaybeEnteredSpan::Some(tracing::info_span!($($tt)*).entered()) - } else { - $crate::interpret::util::MaybeEnteredSpan::None - } + $machine::enter_trace_span(tracing::info_span!($($tt)*)) } } From 3cacaa7d0ebd8994f521fbcfc5277f8725f9348c Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 6 Jul 2025 08:53:50 +0200 Subject: [PATCH 14/20] Add inline(always) to Machine::enter_trace_span --- compiler/rustc_const_eval/src/interpret/machine.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 33afadd94f56b..64aa971d14e9b 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -635,6 +635,7 @@ pub trait Machine<'tcx>: Sized { /// supposedly be optimized out completely. To enable tracing, override this trait method and /// return `span.entered()`. Also see [crate::enter_trace_span]. #[must_use] + #[inline(always)] fn enter_trace_span(_span: tracing::Span) -> impl EnteredTraceSpan { () } From e8c8330ba1a0fb7dcf8e74a8758569ab71261ef7 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 6 Jul 2025 08:58:19 +0200 Subject: [PATCH 15/20] Make enter_trace_span take a closure for better optimization --- compiler/rustc_const_eval/src/interpret/machine.rs | 2 +- compiler/rustc_const_eval/src/interpret/util.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 64aa971d14e9b..d150ed69250e5 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -636,7 +636,7 @@ pub trait Machine<'tcx>: Sized { /// return `span.entered()`. Also see [crate::enter_trace_span]. #[must_use] #[inline(always)] - fn enter_trace_span(_span: tracing::Span) -> impl EnteredTraceSpan { + fn enter_trace_span(_span: impl FnOnce() -> tracing::Span) -> impl EnteredTraceSpan { () } } diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index eeab32fd79c67..72650d545c3ca 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -60,6 +60,6 @@ impl EnteredTraceSpan for tracing::span::EnteredSpan {} #[macro_export] macro_rules! enter_trace_span { ($machine:ident, $($tt:tt)*) => { - $machine::enter_trace_span(tracing::info_span!($($tt)*)) + $machine::enter_trace_span(|| tracing::info_span!($($tt)*)) } } From e5f7d4d783c1567ddc16e02091bae8bacfca1418 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 8 Jul 2025 15:37:01 +0200 Subject: [PATCH 16/20] Implement enter_trace_span() in MiriMachine --- src/tools/miri/src/machine.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 693b8916d89f3..35399dbf4cb0c 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1014,8 +1014,6 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { const PANIC_ON_ALLOC_FAIL: bool = false; - const TRACING_ENABLED: bool = cfg!(feature = "tracing"); - #[inline(always)] fn enforce_alignment(ecx: &MiriInterpCx<'tcx>) -> bool { ecx.machine.check_alignment != AlignmentCheck::None @@ -1827,6 +1825,16 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { #[cfg(not(target_os = "linux"))] MiriAllocParams::Global } + + fn enter_trace_span(span: impl FnOnce() -> tracing::Span) -> impl EnteredTraceSpan { + #[cfg(feature = "tracing")] + { span().entered() } + #[cfg(not(feature = "tracing"))] + { + let _ = span; // so we avoid the "unused variable" warning + () + } + } } /// Trait for callbacks handling asynchronous machine operations. From fab9c64e2d98af65820a660f345106cc586b0006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 8 Jul 2025 19:03:33 +0200 Subject: [PATCH 17/20] Add triagebot stdarch mention ping --- triagebot.toml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 4e3dff219f1d6..6b989102f1237 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -931,6 +931,15 @@ instead. """ cc = ["@tgross35"] +[mentions."library/stdarch"] +message = """ +`stdarch` is developed in its own repository. If possible, consider \ +making this change to \ +[rust-lang/stdarch](https://github.com/rust-lang/stdarch) \ +instead. +""" +cc = ["@Amanieu", "@folkertdev", "@sayantn"] + [mentions."library/core/src/intrinsics/simd.rs"] message = """ Some changes occurred to the platform-builtins intrinsics. Make sure the From 7c8a6d978bb47827eeef15448ca95f82af32c381 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 8 Jul 2025 14:18:07 -0400 Subject: [PATCH 18/20] Spelling --- src/bootstrap/configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 86208b942614e..b05a5cc8b818c 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -746,7 +746,7 @@ def write_uncommented(target, f): block = [] def flush(last): - # If the block is entiry made of comments, ignore it + # If the block is entirely made of comments, ignore it entire_block_comments = all(ln.startswith("#") or ln == "" for ln in block) if not entire_block_comments and len(block) > 0: for line in block: From 96cdbb9ba77b9a840a1637e4dab05bb2cc64fef0 Mon Sep 17 00:00:00 2001 From: George Tokmaji Date: Tue, 8 Jul 2025 21:19:38 +0200 Subject: [PATCH 19/20] Win: Use exceptions with empty data for SEH panic exception copies instead of a new panic For unwinding with SEH, we currently construct a C++ exception with the panic data. Being a regular C++ exception, it interacts with the C++ exception handling machinery and can be retrieved via `std::current_exception`, which needs to copy the exception. We can't support that, so we panic, which throws another exception, which the C++ runtime tries to copy and store into the exception_ptr, which panics again, which causes the C++ runtime to store a `bad_exception` instance. However, this doesn't work because the panics thrown by the copy function will be dropped without being rethrown, and causes unnecessary log spam in stderr. Fix this by directly throwing an exception without data, which doesn't cause log spam and can be dropped without being rethrown. --- library/panic_unwind/src/seh.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs index 003ac4f0cd37f..668e988abff39 100644 --- a/library/panic_unwind/src/seh.rs +++ b/library/panic_unwind/src/seh.rs @@ -61,6 +61,7 @@ struct Exception { // and its destructor is executed by the C++ runtime. When we take the Box // out of the exception, we need to leave the exception in a valid state // for its destructor to run without double-dropping the Box. + // We also construct this as None for copies of the exception. data: Option>, } @@ -264,7 +265,11 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor { // runtime under a try/catch block and the panic that we generate here will be // used as the result of the exception copy. This is used by the C++ runtime to // support capturing exceptions with std::exception_ptr, which we can't support -// because Box isn't clonable. +// because Box isn't clonable. Thus we throw an exception without data, +// which the C++ runtime will attempt to copy, which will once again fail, and +// a std::bad_exception instance ends up in the std::exception_ptr instance. +// The lack of data doesn't matter because the exception will never be rethrown +// - it is purely used to signal to the C++ runtime that copying failed. macro_rules! define_cleanup { ($abi:tt $abi2:tt) => { unsafe extern $abi fn exception_cleanup(e: *mut Exception) { @@ -278,7 +283,9 @@ macro_rules! define_cleanup { unsafe extern $abi2 fn exception_copy( _dest: *mut Exception, _src: *mut Exception ) -> *mut Exception { - panic!("Rust panics cannot be copied"); + unsafe { + throw_exception(None); + } } } } @@ -291,6 +298,10 @@ cfg_if::cfg_if! { } pub(crate) unsafe fn panic(data: Box) -> u32 { + unsafe { throw_exception(Some(data)) } +} + +unsafe fn throw_exception(data: Option>) -> ! { use core::intrinsics::{AtomicOrdering, atomic_store}; // _CxxThrowException executes entirely on this stack frame, so there's no @@ -300,8 +311,7 @@ pub(crate) unsafe fn panic(data: Box) -> u32 { // The ManuallyDrop is needed here since we don't want Exception to be // dropped when unwinding. Instead it will be dropped by exception_cleanup // which is invoked by the C++ runtime. - let mut exception = - ManuallyDrop::new(Exception { canary: (&raw const TYPE_DESCRIPTOR), data: Some(data) }); + let mut exception = ManuallyDrop::new(Exception { canary: (&raw const TYPE_DESCRIPTOR), data }); let throw_ptr = (&raw mut exception) as *mut _; // This... may seems surprising, and justifiably so. On 32-bit MSVC the From 87e7539fcdfa45b2aab618c044f888432c5d097d Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 8 Jul 2025 16:38:35 -0700 Subject: [PATCH 20/20] Disable docs for `compiler-builtins` and `sysroot` Bootstrap already had a manual doc filter for the `sysroot` crate, but other library crates keep themselves out of the public docs by setting `[lib] doc = false` in their manifest. This seems like a better solution to hide `compiler-builtins` docs, and removes the `sysroot` hack too. --- library/compiler-builtins/compiler-builtins/Cargo.toml | 2 ++ library/sysroot/Cargo.toml | 4 ++++ src/bootstrap/src/core/build_steps/doc.rs | 4 ---- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/library/compiler-builtins/compiler-builtins/Cargo.toml b/library/compiler-builtins/compiler-builtins/Cargo.toml index c5446cd76e326..3ccb05f73fb84 100644 --- a/library/compiler-builtins/compiler-builtins/Cargo.toml +++ b/library/compiler-builtins/compiler-builtins/Cargo.toml @@ -19,6 +19,8 @@ links = "compiler-rt" bench = false doctest = false test = false +# make sure this crate isn't included in public standard library docs +doc = false [dependencies] core = { path = "../../core", optional = true } diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index 3adc022497167..514728887fbca 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -5,6 +5,10 @@ name = "sysroot" version = "0.0.0" edition = "2024" +[lib] +# make sure this crate isn't included in public standard library docs +doc = false + # this is a dummy crate to ensure that all required crates appear in the sysroot [dependencies] proc_macro = { path = "../proc_macro", public = true } diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index f7c4c5ad0bbd3..9e839b11c0862 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -739,10 +739,6 @@ fn doc_std( } for krate in requested_crates { - if krate == "sysroot" { - // The sysroot crate is an implementation detail, don't include it in public docs. - continue; - } cargo.arg("-p").arg(krate); }