From 0ce025175d6919b93f057f2650ced63b16f03ced Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Fri, 28 Mar 2025 13:40:53 +0100
Subject: [PATCH 01/17] uses_power_alignment: wording tweaks

---
 compiler/rustc_lint/src/types.rs | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 7109fefbe783e..d98b439ba89fe 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -756,10 +756,10 @@ declare_lint! {
     /// *subsequent* fields of the associated structs to use an alignment value
     /// where the floating-point type is aligned on a 4-byte boundary.
     ///
-    /// The power alignment rule for structs needed for C compatibility is
-    /// unimplementable within `repr(C)` in the compiler without building in
-    /// handling of references to packed fields and infectious nested layouts,
-    /// so a warning is produced in these situations.
+    /// Effectively, subsequent floating-point fields act as-if they are `repr(packed(4))`. This
+    /// would be unsound to do in a `repr(C)` type without all the restrictions that come with
+    /// `repr(packed)`. Rust instead chooses a layout that maintains soundness of Rust code, at the
+    /// expense of incompatibility with C code.
     ///
     /// ### Example
     ///
@@ -791,8 +791,10 @@ declare_lint! {
     ///  - offset_of!(Floats, a) == 0
     ///  - offset_of!(Floats, b) == 8
     ///  - offset_of!(Floats, c) == 12
-    /// However, rust currently aligns `c` at offset_of!(Floats, c) == 16.
-    /// Thus, a warning should be produced for the above struct in this case.
+    ///
+    /// However, Rust currently aligns `c` at `offset_of!(Floats, c) == 16`.
+    /// Using offset 12 would be unsound since `f64` generally must be 8-aligned on this target.
+    /// Thus, a warning is produced for the above struct.
     USES_POWER_ALIGNMENT,
     Warn,
     "Structs do not follow the power alignment rule under repr(C)"

From 87ff60c0b476f28c22df2f886233477dab27e034 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 1 Apr 2025 16:31:22 +0200
Subject: [PATCH 02/17] check_struct_for_power_alignment: simplify code

---
 compiler/rustc_lint/src/types.rs | 21 ++++++---------------
 1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index d98b439ba89fe..d81136192a131 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1623,15 +1623,13 @@ impl ImproperCTypesDefinitions {
         cx: &LateContext<'tcx>,
         ty: Ty<'tcx>,
     ) -> bool {
+        assert!(cx.tcx.sess.target.os == "aix");
         // Structs (under repr(C)) follow the power alignment rule if:
         //   - the first field of the struct is a floating-point type that
         //     is greater than 4-bytes, or
         //   - the first field of the struct is an aggregate whose
         //     recursively first field is a floating-point type greater than
         //     4 bytes.
-        if cx.tcx.sess.target.os != "aix" {
-            return false;
-        }
         if ty.is_floating_point() && ty.primitive_size(cx.tcx).bytes() > 4 {
             return true;
         } else if let Adt(adt_def, _) = ty.kind()
@@ -1663,21 +1661,14 @@ impl ImproperCTypesDefinitions {
             && !adt_def.all_fields().next().is_none()
         {
             let struct_variant_data = item.expect_struct().1;
-            for (index, ..) in struct_variant_data.fields().iter().enumerate() {
+            for field_def in struct_variant_data.fields().iter().skip(1) {
                 // Struct fields (after the first field) are checked for the
                 // power alignment rule, as fields after the first are likely
                 // to be the fields that are misaligned.
-                if index != 0 {
-                    let first_field_def = struct_variant_data.fields()[index];
-                    let def_id = first_field_def.def_id;
-                    let ty = cx.tcx.type_of(def_id).instantiate_identity();
-                    if self.check_arg_for_power_alignment(cx, ty) {
-                        cx.emit_span_lint(
-                            USES_POWER_ALIGNMENT,
-                            first_field_def.span,
-                            UsesPowerAlignment,
-                        );
-                    }
+                let def_id = field_def.def_id;
+                let ty = cx.tcx.type_of(def_id).instantiate_identity();
+                if self.check_arg_for_power_alignment(cx, ty) {
+                    cx.emit_span_lint(USES_POWER_ALIGNMENT, field_def.span, UsesPowerAlignment);
                 }
             }
         }

From 55a419f444378afb5eceb361959fa57eefce2be1 Mon Sep 17 00:00:00 2001
From: Lieselotte <52315535+she3py@users.noreply.github.com>
Date: Mon, 28 Apr 2025 21:40:29 +0200
Subject: [PATCH 03/17] Remove backticks from `ShouldPanic::YesWithMessage`'s
 `TrFailedMsg`

---
 library/test/src/test_result.rs                          | 9 ++++-----
 library/test/src/tests.rs                                | 6 +++---
 .../test-should-panic-failed-show-span.run.stdout        | 6 +++---
 3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/library/test/src/test_result.rs b/library/test/src/test_result.rs
index a312894c25c47..4cb43fc45fd6c 100644
--- a/library/test/src/test_result.rs
+++ b/library/test/src/test_result.rs
@@ -61,16 +61,15 @@ pub(crate) fn calc_result(
             } else if let Some(panic_str) = maybe_panic_str {
                 TestResult::TrFailedMsg(format!(
                     r#"panic did not contain expected string
-      panic message: `{panic_str:?}`,
- expected substring: `{msg:?}`"#
+      panic message: {panic_str:?}
+ expected substring: {msg:?}"#
                 ))
             } else {
                 TestResult::TrFailedMsg(format!(
                     r#"expected panic with string value,
  found non-string value: `{:?}`
-     expected substring: `{:?}`"#,
-                    (*err).type_id(),
-                    msg
+     expected substring: {msg:?}"#,
+                    (*err).type_id()
                 ))
             }
         }
diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs
index 47f581fefae1f..d986bd74f772b 100644
--- a/library/test/src/tests.rs
+++ b/library/test/src/tests.rs
@@ -200,8 +200,8 @@ fn test_should_panic_bad_message() {
     }
     let expected = "foobar";
     let failed_msg = r#"panic did not contain expected string
-      panic message: `"an error message"`,
- expected substring: `"foobar"`"#;
+      panic message: "an error message"
+ expected substring: "foobar""#;
     let desc = TestDescAndFn {
         desc: TestDesc {
             name: StaticTestName("whatever"),
@@ -238,7 +238,7 @@ fn test_should_panic_non_string_message_type() {
     let failed_msg = format!(
         r#"expected panic with string value,
  found non-string value: `{:?}`
-     expected substring: `"foobar"`"#,
+     expected substring: "foobar""#,
         TypeId::of::<i32>()
     );
     let desc = TestDescAndFn {
diff --git a/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stdout b/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stdout
index 75600b4d3d660..93204abb96873 100644
--- a/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stdout
+++ b/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stdout
@@ -15,12 +15,12 @@ note: test did not panic as expected at $DIR/test-should-panic-failed-show-span.
 note: test did not panic as expected at $DIR/test-should-panic-failed-show-span.rs:31:4
 ---- should_panic_with_substring_panics_with_incorrect_string stdout ----
 note: panic did not contain expected string
-      panic message: `"ZOMGWTFBBQ"`,
- expected substring: `"message"`
+      panic message: "ZOMGWTFBBQ"
+ expected substring: "message"
 ---- should_panic_with_substring_panics_with_non_string_value stdout ----
 note: expected panic with string value,
  found non-string value: `TypeId($HEX)`
-     expected substring: `"message"`
+     expected substring: "message"
 
 failures:
     should_panic_with_any_message_does_not_panic

From 5b1e4954a109725019e6bd24bb1e33b879079512 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <n.nethercote@gmail.com>
Date: Thu, 24 Apr 2025 07:15:08 +1000
Subject: [PATCH 04/17] Add a few extra tests to
 `tests/ui/macros/stringify.rs`.

---
 tests/ui/macros/stringify.rs | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs
index 3490d3efc5992..ee62b28b96751 100644
--- a/tests/ui/macros/stringify.rs
+++ b/tests/ui/macros/stringify.rs
@@ -288,6 +288,9 @@ fn test_expr() {
     // ExprKind::OffsetOf: untestable because this test works pre-expansion.
 
     // ExprKind::MacCall
+    c1!(expr, [ mac!() ], "mac!()");
+    c1!(expr, [ mac![] ], "mac![]");
+    c1!(expr, [ mac! {} ], "mac! {}");
     c1!(expr, [ mac!(...) ], "mac!(...)");
     c1!(expr, [ mac![...] ], "mac![...]");
     c1!(expr, [ mac! { ... } ], "mac! { ... }");
@@ -354,6 +357,7 @@ fn test_item() {
 
     // ItemKind::Use
     c1!(item, [ pub use crate::{a, b::c}; ], "pub use crate::{ a, b::c };"); // FIXME
+    c1!(item, [ pub use crate::{ e, ff }; ], "pub use crate::{ e, ff };");
     c1!(item, [ pub use A::*; ], "pub use A::*;");
 
     // ItemKind::Static
@@ -482,9 +486,12 @@ fn test_item() {
     c1!(item, [ impl ~const Struct {} ], "impl ~const Struct {}");
 
     // ItemKind::MacCall
+    c1!(item, [ mac!(); ], "mac!();");
+    c1!(item, [ mac![]; ], "mac![];");
+    c1!(item, [ mac! {} ], "mac! {}");
     c1!(item, [ mac!(...); ], "mac!(...);");
     c1!(item, [ mac![...]; ], "mac![...];");
-    c1!(item, [ mac! { ... } ], "mac! { ... }");
+    c1!(item, [ mac! {...} ], "mac! { ... }");
 
     // ItemKind::MacroDef
     c1!(item,
@@ -598,8 +605,11 @@ fn test_pat() {
     c1!(pat, [ (pat) ], "(pat)");
 
     // PatKind::MacCall
+    c1!(pat, [ mac!() ], "mac!()");
+    c1!(pat, [ mac![] ], "mac![]");
+    c1!(pat, [ mac! {} ], "mac! {}");
     c1!(pat, [ mac!(...) ], "mac!(...)");
-    c1!(pat, [ mac![...] ], "mac![...]");
+    c1!(pat, [ mac! [ ... ] ], "mac! [...]");
     c1!(pat, [ mac! { ... } ], "mac! { ... }");
 
     // Attributes are not allowed on patterns.
@@ -644,6 +654,9 @@ fn test_stmt() {
     c1!(stmt, [ ; ], ";");
 
     // StmtKind::MacCall
+    c1!(stmt, [ mac! ( ) ], "mac! ()");
+    c1!(stmt, [ mac![] ], "mac![]");
+    c1!(stmt, [ mac!{} ], "mac!{}");
     c1!(stmt, [ mac!(...) ], "mac!(...)");
     c1!(stmt, [ mac![...] ], "mac![...]");
     c1!(stmt, [ mac! { ... } ], "mac! { ... }");
@@ -739,6 +752,9 @@ fn test_ty() {
     // TyKind::ImplicitSelf: there is no syntax for this.
 
     // TyKind::MacCall
+    c1!(ty, [ mac!() ], "mac!()");
+    c1!(ty, [ mac![] ], "mac![]");
+    c1!(ty, [ mac! { } ], "mac! {}");
     c1!(ty, [ mac!(...) ], "mac!(...)");
     c1!(ty, [ mac![...] ], "mac![...]");
     c1!(ty, [ mac! { ... } ], "mac! { ... }");

From 99f6b6328e7b418abe2e3bcf49b4504c2866671e Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <n.nethercote@gmail.com>
Date: Fri, 17 May 2024 17:31:34 +1000
Subject: [PATCH 05/17] Improve pretty-printing of braces.

Most notably, the `FIXME` for suboptimal printing of `use` groups in
`tests/ui/macros/stringify.rs` is fixed. And all other test output
changes result in pretty printed output being closer to the original
formatting in the source code.
---
 compiler/rustc_ast_pretty/src/pprust/state.rs | 33 ++++++++++++++-----
 compiler/rustc_builtin_macros/src/autodiff.rs |  4 +--
 compiler/rustc_expand/src/build.rs            | 14 ++++----
 compiler/rustc_hir_pretty/src/lib.rs          |  1 +
 tests/ui/macros/stringify.rs                  |  4 +--
 tests/ui/macros/trace_faulty_macros.stderr    |  6 ++--
 tests/ui/proc-macro/attr-complex-fn.stdout    |  2 +-
 tests/ui/proc-macro/weird-braces.stdout       |  9 +++--
 tests/ui/unpretty/expanded-exhaustive.stdout  |  2 +-
 9 files changed, 46 insertions(+), 29 deletions(-)

diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 985359e1234e8..0d9178b5e2c93 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -634,6 +634,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
                 false,
                 None,
                 *delim,
+                None,
                 tokens,
                 true,
                 span,
@@ -679,6 +680,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
                     false,
                     None,
                     *delim,
+                    Some(spacing.open),
                     tts,
                     convert_dollar_crate,
                     dspan.entire(),
@@ -735,6 +737,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
         has_bang: bool,
         ident: Option<Ident>,
         delim: Delimiter,
+        open_spacing: Option<Spacing>,
         tts: &TokenStream,
         convert_dollar_crate: bool,
         span: Span,
@@ -758,16 +761,26 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
                     self.nbsp();
                 }
                 self.word("{");
-                if !tts.is_empty() {
+
+                // Respect `Alone`, if provided, and print a space. Unless the list is empty.
+                let open_space = (open_spacing == None || open_spacing == Some(Spacing::Alone))
+                    && !tts.is_empty();
+                if open_space {
                     self.space();
                 }
                 let ib = self.ibox(0);
                 self.print_tts(tts, convert_dollar_crate);
                 self.end(ib);
-                let empty = tts.is_empty();
-                self.bclose(span, empty, cb.unwrap());
+
+                // Use `open_space` for the spacing *before* the closing delim.
+                // Because spacing on delimiters is lost when going through
+                // proc macros, and otherwise we can end up with ugly cases
+                // like `{ x}`. Symmetry is better.
+                self.bclose(span, !open_space, cb.unwrap());
             }
             delim => {
+                // `open_spacing` is ignored. We never print spaces after
+                // non-brace opening delims or before non-brace closing delims.
                 let token_str = self.token_kind_to_string(&delim.as_open_token_kind());
                 self.word(token_str);
                 let ib = self.ibox(0);
@@ -797,6 +810,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
             has_bang,
             Some(*ident),
             macro_def.body.delim,
+            None,
             &macro_def.body.tokens,
             true,
             sp,
@@ -844,9 +858,9 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
         self.end(ib);
     }
 
-    fn bclose_maybe_open(&mut self, span: rustc_span::Span, empty: bool, cb: Option<BoxMarker>) {
+    fn bclose_maybe_open(&mut self, span: rustc_span::Span, no_space: bool, cb: Option<BoxMarker>) {
         let has_comment = self.maybe_print_comment(span.hi());
-        if !empty || has_comment {
+        if !no_space || has_comment {
             self.break_offset_if_not_bol(1, -INDENT_UNIT);
         }
         self.word("}");
@@ -855,9 +869,9 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
         }
     }
 
-    fn bclose(&mut self, span: rustc_span::Span, empty: bool, cb: BoxMarker) {
+    fn bclose(&mut self, span: rustc_span::Span, no_space: bool, cb: BoxMarker) {
         let cb = Some(cb);
-        self.bclose_maybe_open(span, empty, cb)
+        self.bclose_maybe_open(span, no_space, cb)
     }
 
     fn break_offset_if_not_bol(&mut self, n: usize, off: isize) {
@@ -1423,8 +1437,8 @@ impl<'a> State<'a> {
             }
         }
 
-        let empty = !has_attrs && blk.stmts.is_empty();
-        self.bclose_maybe_open(blk.span, empty, cb);
+        let no_space = !has_attrs && blk.stmts.is_empty();
+        self.bclose_maybe_open(blk.span, no_space, cb);
         self.ann.post(self, AnnNode::Block(blk))
     }
 
@@ -1471,6 +1485,7 @@ impl<'a> State<'a> {
             true,
             None,
             m.args.delim,
+            None,
             &m.args.tokens,
             true,
             m.span(),
diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs
index 6d97dfa3a4d41..8c5c20c7af48c 100644
--- a/compiler/rustc_builtin_macros/src/autodiff.rs
+++ b/compiler/rustc_builtin_macros/src/autodiff.rs
@@ -323,9 +323,9 @@ mod llvm_enzyme {
             Spacing::Joint,
         )];
         let never_arg = ast::DelimArgs {
-            dspan: ast::tokenstream::DelimSpan::from_single(span),
+            dspan: DelimSpan::from_single(span),
             delim: ast::token::Delimiter::Parenthesis,
-            tokens: ast::tokenstream::TokenStream::from_iter(ts2),
+            tokens: TokenStream::from_iter(ts2),
         };
         let inline_item = ast::AttrItem {
             unsafety: ast::Safety::Default,
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index 6d616cf84bbd4..14b8cc90d97d6 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -1,8 +1,10 @@
 use rustc_ast::ptr::P;
+use rustc_ast::token::Delimiter;
+use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::util::literal;
 use rustc_ast::{
     self as ast, AnonConst, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, PatKind, UnOp,
-    attr, token,
+    attr, token, tokenstream,
 };
 use rustc_span::source_map::Spanned;
 use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
@@ -55,13 +57,13 @@ impl<'a> ExtCtxt<'a> {
         &self,
         span: Span,
         path: ast::Path,
-        delim: ast::token::Delimiter,
-        tokens: ast::tokenstream::TokenStream,
+        delim: Delimiter,
+        tokens: TokenStream,
     ) -> P<ast::MacCall> {
         P(ast::MacCall {
             path,
             args: P(ast::DelimArgs {
-                dspan: ast::tokenstream::DelimSpan { open: span, close: span },
+                dspan: tokenstream::DelimSpan { open: span, close: span },
                 delim,
                 tokens,
             }),
@@ -480,8 +482,8 @@ impl<'a> ExtCtxt<'a> {
                     span,
                     [sym::std, sym::unreachable].map(|s| Ident::new(s, span)).to_vec(),
                 ),
-                ast::token::Delimiter::Parenthesis,
-                ast::tokenstream::TokenStream::default(),
+                Delimiter::Parenthesis,
+                TokenStream::default(),
             ),
         )
     }
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index b878147522dc8..d5ae8f7a95479 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -146,6 +146,7 @@ impl<'a> State<'a> {
                     false,
                     None,
                     *delim,
+                    None,
                     &tokens,
                     true,
                     span,
diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs
index ee62b28b96751..3f3d9252adbe8 100644
--- a/tests/ui/macros/stringify.rs
+++ b/tests/ui/macros/stringify.rs
@@ -356,7 +356,7 @@ fn test_item() {
     c1!(item, [ pub extern crate self as std; ], "pub extern crate self as std;");
 
     // ItemKind::Use
-    c1!(item, [ pub use crate::{a, b::c}; ], "pub use crate::{ a, b::c };"); // FIXME
+    c1!(item, [ pub use crate::{a, b::c}; ], "pub use crate::{a, b::c};");
     c1!(item, [ pub use crate::{ e, ff }; ], "pub use crate::{ e, ff };");
     c1!(item, [ pub use A::*; ], "pub use A::*;");
 
@@ -491,7 +491,7 @@ fn test_item() {
     c1!(item, [ mac! {} ], "mac! {}");
     c1!(item, [ mac!(...); ], "mac!(...);");
     c1!(item, [ mac![...]; ], "mac![...];");
-    c1!(item, [ mac! {...} ], "mac! { ... }");
+    c1!(item, [ mac! {...} ], "mac! {...}");
 
     // ItemKind::MacroDef
     c1!(item,
diff --git a/tests/ui/macros/trace_faulty_macros.stderr b/tests/ui/macros/trace_faulty_macros.stderr
index 73fed66e61906..e90d7a98db4c7 100644
--- a/tests/ui/macros/trace_faulty_macros.stderr
+++ b/tests/ui/macros/trace_faulty_macros.stderr
@@ -87,9 +87,9 @@ LL |     let a = pat_macro!();
    |             ^^^^^^^^^^^^
    |
    = note: expanding `pat_macro! {  }`
-   = note: to `pat_macro! (A { a : a, b : 0, c : _, .. });`
-   = note: expanding `pat_macro! { A { a : a, b : 0, c : _, .. } }`
-   = note: to `A { a : a, b : 0, c : _, .. }`
+   = note: to `pat_macro! (A {a : a, b : 0, c : _, ..});`
+   = note: expanding `pat_macro! { A {a : a, b : 0, c : _, ..} }`
+   = note: to `A {a : a, b : 0, c : _, ..}`
 
 note: trace_macro
   --> $DIR/trace_faulty_macros.rs:53:5
diff --git a/tests/ui/proc-macro/attr-complex-fn.stdout b/tests/ui/proc-macro/attr-complex-fn.stdout
index 7c23d1ecae45d..9bbb746bb4d62 100644
--- a/tests/ui/proc-macro/attr-complex-fn.stdout
+++ b/tests/ui/proc-macro/attr-complex-fn.stdout
@@ -77,7 +77,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
         span: $DIR/attr-complex-fn.rs:19:42: 19:44 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): impl<T> MyTrait<T> for MyStruct<{ true }> { #![rustc_dummy] }
+PRINT-ATTR INPUT (DISPLAY): impl<T> MyTrait<T> for MyStruct<{true}> { #![rustc_dummy] }
 PRINT-ATTR RE-COLLECTED (DISPLAY): impl < T > MyTrait < T > for MyStruct < { true } > { #![rustc_dummy] }
 PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): impl < T > MyTrait < T > for MyStruct < { true } > { #! [rustc_dummy] }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
diff --git a/tests/ui/proc-macro/weird-braces.stdout b/tests/ui/proc-macro/weird-braces.stdout
index 7da769ef0d247..0215deb05c302 100644
--- a/tests/ui/proc-macro/weird-braces.stdout
+++ b/tests/ui/proc-macro/weird-braces.stdout
@@ -5,7 +5,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
         span: $DIR/weird-braces.rs:16:25: 16:36 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): #[print_target_and_args(second_outer)] impl Bar<{ 1 > 0 }> for Foo<{ true }>
+PRINT-ATTR INPUT (DISPLAY): #[print_target_and_args(second_outer)] impl Bar<{1 > 0}> for Foo<{true}>
 {
     #![print_target_and_args(first_inner)]
     #![print_target_and_args(second_inner)]
@@ -191,7 +191,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
         span: $DIR/weird-braces.rs:17:25: 17:37 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): impl Bar<{ 1 > 0 }> for Foo<{ true }>
+PRINT-ATTR INPUT (DISPLAY): impl Bar<{1 > 0}> for Foo<{true}>
 {
     #![print_target_and_args(first_inner)]
     #![print_target_and_args(second_inner)]
@@ -350,8 +350,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
         span: $DIR/weird-braces.rs:19:30: 19:41 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): impl Bar<{ 1 > 0 }> for Foo<{ true }>
-{ #![print_target_and_args(second_inner)] }
+PRINT-ATTR INPUT (DISPLAY): impl Bar<{1 > 0}> for Foo<{true}> { #![print_target_and_args(second_inner)] }
 PRINT-ATTR RE-COLLECTED (DISPLAY): impl Bar < { 1 > 0 } > for Foo < { true } >
 { #![print_target_and_args(second_inner)] }
 PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): impl Bar < { 1 > 0 } > for Foo < { true } >
@@ -470,7 +469,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
         span: $DIR/weird-braces.rs:20:30: 20:42 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): impl Bar<{ 1 > 0 }> for Foo<{ true }> {}
+PRINT-ATTR INPUT (DISPLAY): impl Bar<{1 > 0}> for Foo<{true}> {}
 PRINT-ATTR RE-COLLECTED (DISPLAY): impl Bar < { 1 > 0 } > for Foo < { true } > {}
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout
index 841edf63c9191..c6ffbb0d316bb 100644
--- a/tests/ui/unpretty/expanded-exhaustive.stdout
+++ b/tests/ui/unpretty/expanded-exhaustive.stdout
@@ -505,7 +505,7 @@ mod items {
     mod item_mac_call { }
     /// ItemKind::MacroDef
     mod item_macro_def {
-        macro_rules! mac { () => { ... }; }
+        macro_rules! mac { () => {...}; }
         pub macro stringify { () => {} }
     }
     /// ItemKind::Delegation

From cf12e290fd5e356cef3c9d95643ea4dd4b093dfd Mon Sep 17 00:00:00 2001
From: Adrian Friedli <adrian.friedli@husqvarnagroup.com>
Date: Tue, 29 Apr 2025 10:20:25 +0200
Subject: [PATCH 06/17] enable msa feature for mips in codegen tests

---
 tests/codegen/const-vector.rs            |  2 ++
 tests/codegen/repr/transparent.rs        |  3 ++-
 tests/codegen/simd/extract-insert-dyn.rs | 10 +++++++++-
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/tests/codegen/const-vector.rs b/tests/codegen/const-vector.rs
index 1d4edc39b1c88..289b67371ce43 100644
--- a/tests/codegen/const-vector.rs
+++ b/tests/codegen/const-vector.rs
@@ -9,6 +9,7 @@
 #![feature(rustc_attrs)]
 #![feature(simd_ffi)]
 #![feature(arm_target_feature)]
+#![feature(mips_target_feature)]
 #![allow(non_camel_case_types)]
 
 // Setting up structs that can be used as const vectors
@@ -45,6 +46,7 @@ extern "unadjusted" {
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
+#[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 pub fn do_call() {
     unsafe {
         // CHECK: call void @test_i8x2(<2 x i8> <i8 32, i8 64>
diff --git a/tests/codegen/repr/transparent.rs b/tests/codegen/repr/transparent.rs
index 5475bfb6b65ef..29b627462a4d9 100644
--- a/tests/codegen/repr/transparent.rs
+++ b/tests/codegen/repr/transparent.rs
@@ -9,7 +9,7 @@
 // For LoongArch: see codegen/loongarch-abi
 
 #![crate_type = "lib"]
-#![feature(repr_simd, transparent_unions, arm_target_feature)]
+#![feature(repr_simd, transparent_unions, arm_target_feature, mips_target_feature)]
 
 use std::marker::PhantomData;
 
@@ -142,6 +142,7 @@ pub struct Vector(f32x4);
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
+#[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 pub extern "C" fn test_Vector(_: Vector) -> Vector {
     loop {}
 }
diff --git a/tests/codegen/simd/extract-insert-dyn.rs b/tests/codegen/simd/extract-insert-dyn.rs
index 2c64f5d3c0939..7d032c6bb3ef3 100644
--- a/tests/codegen/simd/extract-insert-dyn.rs
+++ b/tests/codegen/simd/extract-insert-dyn.rs
@@ -1,6 +1,6 @@
 //@compile-flags: -C opt-level=3 -C no-prepopulate-passes
 
-#![feature(core_intrinsics, repr_simd, arm_target_feature)]
+#![feature(core_intrinsics, repr_simd, arm_target_feature, mips_target_feature)]
 #![no_std]
 #![crate_type = "lib"]
 #![allow(non_camel_case_types)]
@@ -24,6 +24,7 @@ pub struct i8x16([i8; 16]);
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
+#[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 unsafe extern "C" fn dyn_simd_extract(x: i8x16, idx: u32) -> i8 {
     simd_extract_dyn(x, idx)
 }
@@ -34,6 +35,7 @@ unsafe extern "C" fn dyn_simd_extract(x: i8x16, idx: u32) -> i8 {
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
+#[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 unsafe extern "C" fn literal_dyn_simd_extract(x: i8x16) -> i8 {
     simd_extract_dyn(x, 7)
 }
@@ -44,6 +46,7 @@ unsafe extern "C" fn literal_dyn_simd_extract(x: i8x16) -> i8 {
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
+#[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 unsafe extern "C" fn const_dyn_simd_extract(x: i8x16) -> i8 {
     simd_extract_dyn(x, const { 3 + 4 })
 }
@@ -54,6 +57,7 @@ unsafe extern "C" fn const_dyn_simd_extract(x: i8x16) -> i8 {
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
+#[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 unsafe extern "C" fn const_simd_extract(x: i8x16) -> i8 {
     simd_extract(x, const { 3 + 4 })
 }
@@ -64,6 +68,7 @@ unsafe extern "C" fn const_simd_extract(x: i8x16) -> i8 {
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
+#[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 unsafe extern "C" fn dyn_simd_insert(x: i8x16, e: i8, idx: u32) -> i8x16 {
     simd_insert_dyn(x, idx, e)
 }
@@ -74,6 +79,7 @@ unsafe extern "C" fn dyn_simd_insert(x: i8x16, e: i8, idx: u32) -> i8x16 {
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
+#[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 unsafe extern "C" fn literal_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
     simd_insert_dyn(x, 7, e)
 }
@@ -84,6 +90,7 @@ unsafe extern "C" fn literal_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
+#[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 unsafe extern "C" fn const_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
     simd_insert_dyn(x, const { 3 + 4 }, e)
 }
@@ -94,6 +101,7 @@ unsafe extern "C" fn const_dyn_simd_insert(x: i8x16, e: i8) -> i8x16 {
 #[cfg_attr(target_family = "wasm", target_feature(enable = "simd128"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "neon"))]
 #[cfg_attr(target_arch = "x86", target_feature(enable = "sse"))]
+#[cfg_attr(target_arch = "mips", target_feature(enable = "msa"))]
 unsafe extern "C" fn const_simd_insert(x: i8x16, e: i8) -> i8x16 {
     simd_insert(x, const { 3 + 4 }, e)
 }

From 4fe94badef30e6a8b13f27ef3a0b8c8e0de866fa Mon Sep 17 00:00:00 2001
From: Pietro Albini <pietro.albini@ferrous-systems.com>
Date: Tue, 29 Apr 2025 10:59:14 +0200
Subject: [PATCH 07/17] add `rust.debug-assertions-tools` option

---
 bootstrap.example.toml                    |  6 ++++++
 src/bootstrap/src/core/builder/cargo.rs   | 14 +++++++++-----
 src/bootstrap/src/core/config/config.rs   |  8 ++++++++
 src/bootstrap/src/utils/change_tracker.rs |  5 +++++
 4 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/bootstrap.example.toml b/bootstrap.example.toml
index b8f863bbed13d..1371fd6442f96 100644
--- a/bootstrap.example.toml
+++ b/bootstrap.example.toml
@@ -570,6 +570,12 @@
 # Defaults to rust.debug-assertions value
 #debug-assertions-std = rust.debug-assertions (boolean)
 
+# Whether or not debug assertions are enabled for the tools built by bootstrap.
+# Overrides the `debug-assertions` option, if defined.
+#
+# Defaults to rust.debug-assertions value
+#debug-assertions-tools = rust.debug-assertions (boolean)
+
 # Whether or not to leave debug! and trace! calls in the rust binary.
 #
 # Defaults to rust.debug-assertions value
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index e4503b2645624..36b3c95d638cc 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -872,11 +872,15 @@ impl Builder<'_> {
         }
         cargo.env(
             profile_var("DEBUG_ASSERTIONS"),
-            if mode == Mode::Std {
-                self.config.std_debug_assertions.to_string()
-            } else {
-                self.config.rustc_debug_assertions.to_string()
-            },
+            match mode {
+                Mode::Std => self.config.std_debug_assertions,
+                Mode::Rustc => self.config.rustc_debug_assertions,
+                Mode::Codegen => self.config.rustc_debug_assertions,
+                Mode::ToolBootstrap => self.config.tools_debug_assertions,
+                Mode::ToolStd => self.config.tools_debug_assertions,
+                Mode::ToolRustc => self.config.tools_debug_assertions,
+            }
+            .to_string(),
         );
         cargo.env(
             profile_var("OVERFLOW_CHECKS"),
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 23b623d9bab23..65a3e7667e7f0 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -306,6 +306,7 @@ pub struct Config {
 
     pub rustc_debug_assertions: bool,
     pub std_debug_assertions: bool,
+    pub tools_debug_assertions: bool,
 
     pub rust_overflow_checks: bool,
     pub rust_overflow_checks_std: bool,
@@ -1280,6 +1281,7 @@ define_config! {
         rustc_debug_assertions: Option<bool> = "debug-assertions",
         randomize_layout: Option<bool> = "randomize-layout",
         std_debug_assertions: Option<bool> = "debug-assertions-std",
+        tools_debug_assertions: Option<bool> = "debug-assertions-tools",
         overflow_checks: Option<bool> = "overflow-checks",
         overflow_checks_std: Option<bool> = "overflow-checks-std",
         debug_logging: Option<bool> = "debug-logging",
@@ -1937,6 +1939,7 @@ impl Config {
         let mut debug = None;
         let mut rustc_debug_assertions = None;
         let mut std_debug_assertions = None;
+        let mut tools_debug_assertions = None;
         let mut overflow_checks = None;
         let mut overflow_checks_std = None;
         let mut debug_logging = None;
@@ -2000,6 +2003,7 @@ impl Config {
                 codegen_units_std,
                 rustc_debug_assertions: rustc_debug_assertions_toml,
                 std_debug_assertions: std_debug_assertions_toml,
+                tools_debug_assertions: tools_debug_assertions_toml,
                 overflow_checks: overflow_checks_toml,
                 overflow_checks_std: overflow_checks_std_toml,
                 debug_logging: debug_logging_toml,
@@ -2084,6 +2088,7 @@ impl Config {
             debug = debug_toml;
             rustc_debug_assertions = rustc_debug_assertions_toml;
             std_debug_assertions = std_debug_assertions_toml;
+            tools_debug_assertions = tools_debug_assertions_toml;
             overflow_checks = overflow_checks_toml;
             overflow_checks_std = overflow_checks_std_toml;
             debug_logging = debug_logging_toml;
@@ -2509,6 +2514,8 @@ impl Config {
         let default = debug == Some(true);
         config.rustc_debug_assertions = rustc_debug_assertions.unwrap_or(default);
         config.std_debug_assertions = std_debug_assertions.unwrap_or(config.rustc_debug_assertions);
+        config.tools_debug_assertions =
+            tools_debug_assertions.unwrap_or(config.rustc_debug_assertions);
         config.rust_overflow_checks = overflow_checks.unwrap_or(default);
         config.rust_overflow_checks_std =
             overflow_checks_std.unwrap_or(config.rust_overflow_checks);
@@ -3568,6 +3575,7 @@ fn check_incompatible_options_for_ci_rustc(
         codegen_units_std: _,
         rustc_debug_assertions: _,
         std_debug_assertions: _,
+        tools_debug_assertions: _,
         overflow_checks: _,
         overflow_checks_std: _,
         debuginfo_level: _,
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 3f1885a425f83..d926185ffaf1c 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -401,4 +401,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "Added new option `include` to create config extensions.",
     },
+    ChangeInfo {
+        change_id: 140438,
+        severity: ChangeSeverity::Info,
+        summary: "Added a new option `rust.debug-assertions-tools` to control debug asssertions for tools.",
+    },
 ];

From 2393e447eba2edf86c90812a78b78b37a5374f6b Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 29 Apr 2025 11:03:30 +0200
Subject: [PATCH 08/17] miri: algebraic intrinsics: bring back float
 non-determinism

---
 .../src/interpret/intrinsics.rs               |   3 +-
 .../rustc_const_eval/src/interpret/machine.rs |   8 ++
 src/tools/miri/src/intrinsics/mod.rs          |  27 +---
 src/tools/miri/src/machine.rs                 |  10 ++
 src/tools/miri/src/math.rs                    |  26 ++++
 src/tools/miri/tests/pass/float.rs            | 119 +++++++++---------
 6 files changed, 107 insertions(+), 86 deletions(-)

diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 40c63f2b250f5..63043de97390f 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -178,8 +178,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
                 let res = self.binary_op(op, &a, &b)?;
                 // `binary_op` already called `generate_nan` if needed.
-
-                // FIXME: Miri should add some non-determinism to the result here to catch any dependences on exact computations. This has previously been done, but the behaviour was removed as part of constification.
+                let res = M::apply_float_nondet(self, res)?;
                 self.write_immediate(*res, dest)?;
             }
 
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index e5026eff21f46..a1386b4e1be49 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -276,6 +276,14 @@ pub trait Machine<'tcx>: Sized {
         F2::NAN
     }
 
+    /// Apply non-determinism to float operations that do not return a precise result.
+    fn apply_float_nondet(
+        _ecx: &mut InterpCx<'tcx, Self>,
+        val: ImmTy<'tcx, Self::Provenance>,
+    ) -> InterpResult<'tcx, ImmTy<'tcx, Self::Provenance>> {
+        interp_ok(val)
+    }
+
     /// Determines the result of `min`/`max` on floats when the arguments are equal.
     fn equal_float_min_max<F: Float>(_ecx: &InterpCx<'tcx, Self>, a: F, _b: F) -> F {
         // By default, we pick the left argument.
diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs
index 7d60a7e5c4895..3334c0b5edf96 100644
--- a/src/tools/miri/src/intrinsics/mod.rs
+++ b/src/tools/miri/src/intrinsics/mod.rs
@@ -7,13 +7,13 @@ use rand::Rng;
 use rustc_abi::Size;
 use rustc_apfloat::{Float, Round};
 use rustc_middle::mir;
-use rustc_middle::ty::{self, FloatTy, ScalarInt};
+use rustc_middle::ty::{self, FloatTy};
 use rustc_span::{Symbol, sym};
 
 use self::atomic::EvalContextExt as _;
 use self::helpers::{ToHost, ToSoft, check_intrinsic_arg_count};
 use self::simd::EvalContextExt as _;
-use crate::math::apply_random_float_error_ulp;
+use crate::math::apply_random_float_error_to_imm;
 use crate::*;
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
@@ -473,26 +473,3 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         interp_ok(EmulateItemResult::NeedsReturn)
     }
 }
-
-/// Applies a random 16ULP floating point error to `val` and returns the new value.
-/// Will fail if `val` is not a floating point number.
-fn apply_random_float_error_to_imm<'tcx>(
-    ecx: &mut MiriInterpCx<'tcx>,
-    val: ImmTy<'tcx>,
-    ulp_exponent: u32,
-) -> InterpResult<'tcx, ImmTy<'tcx>> {
-    let scalar = val.to_scalar_int()?;
-    let res: ScalarInt = match val.layout.ty.kind() {
-        ty::Float(FloatTy::F16) =>
-            apply_random_float_error_ulp(ecx, scalar.to_f16(), ulp_exponent).into(),
-        ty::Float(FloatTy::F32) =>
-            apply_random_float_error_ulp(ecx, scalar.to_f32(), ulp_exponent).into(),
-        ty::Float(FloatTy::F64) =>
-            apply_random_float_error_ulp(ecx, scalar.to_f64(), ulp_exponent).into(),
-        ty::Float(FloatTy::F128) =>
-            apply_random_float_error_ulp(ecx, scalar.to_f128(), ulp_exponent).into(),
-        _ => bug!("intrinsic called with non-float input type"),
-    };
-
-    interp_ok(ImmTy::from_scalar_int(res, val.layout))
-}
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index ea59d327be846..10b288882ce6f 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -1199,6 +1199,16 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         ecx.generate_nan(inputs)
     }
 
+    #[inline(always)]
+    fn apply_float_nondet(
+        ecx: &mut InterpCx<'tcx, Self>,
+        val: ImmTy<'tcx>,
+    ) -> InterpResult<'tcx, ImmTy<'tcx>> {
+        crate::math::apply_random_float_error_to_imm(
+            ecx, val, 2 /* log2(4) */
+        )
+    }
+
     #[inline(always)]
     fn equal_float_min_max<F: Float>(ecx: &MiriInterpCx<'tcx>, a: F, b: F) -> F {
         ecx.equal_float_min_max(a, b)
diff --git a/src/tools/miri/src/math.rs b/src/tools/miri/src/math.rs
index fdd021f85394b..2ff29c7ac1aad 100644
--- a/src/tools/miri/src/math.rs
+++ b/src/tools/miri/src/math.rs
@@ -1,6 +1,9 @@
 use rand::Rng as _;
 use rustc_apfloat::Float as _;
 use rustc_apfloat::ieee::IeeeFloat;
+use rustc_middle::ty::{self, FloatTy, ScalarInt};
+
+use crate::*;
 
 /// Disturbes a floating-point result by a relative error in the range (-2^scale, 2^scale).
 ///
@@ -43,6 +46,29 @@ pub(crate) fn apply_random_float_error_ulp<F: rustc_apfloat::Float>(
     apply_random_float_error(ecx, val, err_scale)
 }
 
+/// Applies a random 16ULP floating point error to `val` and returns the new value.
+/// Will fail if `val` is not a floating point number.
+pub(crate) fn apply_random_float_error_to_imm<'tcx>(
+    ecx: &mut MiriInterpCx<'tcx>,
+    val: ImmTy<'tcx>,
+    ulp_exponent: u32,
+) -> InterpResult<'tcx, ImmTy<'tcx>> {
+    let scalar = val.to_scalar_int()?;
+    let res: ScalarInt = match val.layout.ty.kind() {
+        ty::Float(FloatTy::F16) =>
+            apply_random_float_error_ulp(ecx, scalar.to_f16(), ulp_exponent).into(),
+        ty::Float(FloatTy::F32) =>
+            apply_random_float_error_ulp(ecx, scalar.to_f32(), ulp_exponent).into(),
+        ty::Float(FloatTy::F64) =>
+            apply_random_float_error_ulp(ecx, scalar.to_f64(), ulp_exponent).into(),
+        ty::Float(FloatTy::F128) =>
+            apply_random_float_error_ulp(ecx, scalar.to_f128(), ulp_exponent).into(),
+        _ => bug!("intrinsic called with non-float input type"),
+    };
+
+    interp_ok(ImmTy::from_scalar_int(res, val.layout))
+}
+
 pub(crate) fn sqrt<S: rustc_apfloat::ieee::Semantics>(x: IeeeFloat<S>) -> IeeeFloat<S> {
     match x.category() {
         // preserve zero sign
diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs
index 575d70579a4e3..98a88cfd62dc8 100644
--- a/src/tools/miri/tests/pass/float.rs
+++ b/src/tools/miri/tests/pass/float.rs
@@ -1292,8 +1292,7 @@ fn test_non_determinism() {
             }
         }
         // We saw the same thing N times.
-        // FIXME: temporarily disabled as it breaks std tests.
-        //panic!("expected non-determinism, got {rounds} times the same result: {first:?}");
+        panic!("expected non-determinism, got {rounds} times the same result: {first:?}");
     }
 
     macro_rules! test_operations_f {
@@ -1319,66 +1318,68 @@ fn test_non_determinism() {
     }
     pub fn test_operations_f32(a: f32, b: f32) {
         test_operations_f!(a, b);
-        ensure_nondet(|| a.log(b));
-        ensure_nondet(|| a.exp());
-        ensure_nondet(|| 10f32.exp2());
-        ensure_nondet(|| f32::consts::E.ln());
-        ensure_nondet(|| 1f32.ln_1p());
-        ensure_nondet(|| 10f32.log10());
-        ensure_nondet(|| 8f32.log2());
-        ensure_nondet(|| 27.0f32.cbrt());
-        ensure_nondet(|| 3.0f32.hypot(4.0f32));
-        ensure_nondet(|| 1f32.sin());
-        ensure_nondet(|| 0f32.cos());
-        // On i686-pc-windows-msvc , these functions are implemented by calling the `f64` version,
-        // which means the little rounding errors Miri introduces are discard by the cast down to `f32`.
-        // Just skip the test for them.
-        if !cfg!(all(target_os = "windows", target_env = "msvc", target_arch = "x86")) {
-            ensure_nondet(|| 1.0f32.tan());
-            ensure_nondet(|| 1.0f32.asin());
-            ensure_nondet(|| 5.0f32.acos());
-            ensure_nondet(|| 1.0f32.atan());
-            ensure_nondet(|| 1.0f32.atan2(2.0f32));
-            ensure_nondet(|| 1.0f32.sinh());
-            ensure_nondet(|| 1.0f32.cosh());
-            ensure_nondet(|| 1.0f32.tanh());
-        }
-        ensure_nondet(|| 1.0f32.asinh());
-        ensure_nondet(|| 2.0f32.acosh());
-        ensure_nondet(|| 0.5f32.atanh());
-        ensure_nondet(|| 5.0f32.gamma());
-        ensure_nondet(|| 5.0f32.ln_gamma());
-        ensure_nondet(|| 5.0f32.erf());
-        ensure_nondet(|| 5.0f32.erfc());
+        // FIXME: temporarily disabled as it breaks std tests.
+        // ensure_nondet(|| a.log(b));
+        // ensure_nondet(|| a.exp());
+        // ensure_nondet(|| 10f32.exp2());
+        // ensure_nondet(|| f32::consts::E.ln());
+        // ensure_nondet(|| 1f32.ln_1p());
+        // ensure_nondet(|| 10f32.log10());
+        // ensure_nondet(|| 8f32.log2());
+        // ensure_nondet(|| 27.0f32.cbrt());
+        // ensure_nondet(|| 3.0f32.hypot(4.0f32));
+        // ensure_nondet(|| 1f32.sin());
+        // ensure_nondet(|| 0f32.cos());
+        // // On i686-pc-windows-msvc , these functions are implemented by calling the `f64` version,
+        // // which means the little rounding errors Miri introduces are discard by the cast down to `f32`.
+        // // Just skip the test for them.
+        // if !cfg!(all(target_os = "windows", target_env = "msvc", target_arch = "x86")) {
+        //     ensure_nondet(|| 1.0f32.tan());
+        //     ensure_nondet(|| 1.0f32.asin());
+        //     ensure_nondet(|| 5.0f32.acos());
+        //     ensure_nondet(|| 1.0f32.atan());
+        //     ensure_nondet(|| 1.0f32.atan2(2.0f32));
+        //     ensure_nondet(|| 1.0f32.sinh());
+        //     ensure_nondet(|| 1.0f32.cosh());
+        //     ensure_nondet(|| 1.0f32.tanh());
+        // }
+        // ensure_nondet(|| 1.0f32.asinh());
+        // ensure_nondet(|| 2.0f32.acosh());
+        // ensure_nondet(|| 0.5f32.atanh());
+        // ensure_nondet(|| 5.0f32.gamma());
+        // ensure_nondet(|| 5.0f32.ln_gamma());
+        // ensure_nondet(|| 5.0f32.erf());
+        // ensure_nondet(|| 5.0f32.erfc());
     }
     pub fn test_operations_f64(a: f64, b: f64) {
         test_operations_f!(a, b);
-        ensure_nondet(|| a.log(b));
-        ensure_nondet(|| a.exp());
-        ensure_nondet(|| 50f64.exp2());
-        ensure_nondet(|| 3f64.ln());
-        ensure_nondet(|| 1f64.ln_1p());
-        ensure_nondet(|| f64::consts::E.log10());
-        ensure_nondet(|| f64::consts::E.log2());
-        ensure_nondet(|| 27.0f64.cbrt());
-        ensure_nondet(|| 3.0f64.hypot(4.0f64));
-        ensure_nondet(|| 1f64.sin());
-        ensure_nondet(|| 0f64.cos());
-        ensure_nondet(|| 1.0f64.tan());
-        ensure_nondet(|| 1.0f64.asin());
-        ensure_nondet(|| 5.0f64.acos());
-        ensure_nondet(|| 1.0f64.atan());
-        ensure_nondet(|| 1.0f64.atan2(2.0f64));
-        ensure_nondet(|| 1.0f64.sinh());
-        ensure_nondet(|| 1.0f64.cosh());
-        ensure_nondet(|| 1.0f64.tanh());
-        ensure_nondet(|| 1.0f64.asinh());
-        ensure_nondet(|| 3.0f64.acosh());
-        ensure_nondet(|| 0.5f64.atanh());
-        ensure_nondet(|| 5.0f64.gamma());
-        ensure_nondet(|| 5.0f64.ln_gamma());
-        ensure_nondet(|| 5.0f64.erf());
-        ensure_nondet(|| 5.0f64.erfc());
+        // FIXME: temporarily disabled as it breaks std tests.
+        // ensure_nondet(|| a.log(b));
+        // ensure_nondet(|| a.exp());
+        // ensure_nondet(|| 50f64.exp2());
+        // ensure_nondet(|| 3f64.ln());
+        // ensure_nondet(|| 1f64.ln_1p());
+        // ensure_nondet(|| f64::consts::E.log10());
+        // ensure_nondet(|| f64::consts::E.log2());
+        // ensure_nondet(|| 27.0f64.cbrt());
+        // ensure_nondet(|| 3.0f64.hypot(4.0f64));
+        // ensure_nondet(|| 1f64.sin());
+        // ensure_nondet(|| 0f64.cos());
+        // ensure_nondet(|| 1.0f64.tan());
+        // ensure_nondet(|| 1.0f64.asin());
+        // ensure_nondet(|| 5.0f64.acos());
+        // ensure_nondet(|| 1.0f64.atan());
+        // ensure_nondet(|| 1.0f64.atan2(2.0f64));
+        // ensure_nondet(|| 1.0f64.sinh());
+        // ensure_nondet(|| 1.0f64.cosh());
+        // ensure_nondet(|| 1.0f64.tanh());
+        // ensure_nondet(|| 1.0f64.asinh());
+        // ensure_nondet(|| 3.0f64.acosh());
+        // ensure_nondet(|| 0.5f64.atanh());
+        // ensure_nondet(|| 5.0f64.gamma());
+        // ensure_nondet(|| 5.0f64.ln_gamma());
+        // ensure_nondet(|| 5.0f64.erf());
+        // ensure_nondet(|| 5.0f64.erfc());
     }
     pub fn test_operations_f128(a: f128, b: f128) {
         test_operations_f!(a, b);

From 478b3789ce41248db5d6c14ccce48f2634350182 Mon Sep 17 00:00:00 2001
From: mejrs <59372212+mejrs@users.noreply.github.com>
Date: Tue, 29 Apr 2025 12:19:29 +0200
Subject: [PATCH 09/17] Move `on impl position` test to proper directory

---
 .../{ => on_unimplemented}/on_impl_trait.rs               | 5 +++--
 .../{ => on_unimplemented}/on_impl_trait.stderr           | 8 ++++----
 2 files changed, 7 insertions(+), 6 deletions(-)
 rename tests/ui/diagnostic_namespace/{ => on_unimplemented}/on_impl_trait.rs (75%)
 rename tests/ui/diagnostic_namespace/{ => on_unimplemented}/on_impl_trait.stderr (88%)

diff --git a/tests/ui/diagnostic_namespace/on_impl_trait.rs b/tests/ui/diagnostic_namespace/on_unimplemented/on_impl_trait.rs
similarity index 75%
rename from tests/ui/diagnostic_namespace/on_impl_trait.rs
rename to tests/ui/diagnostic_namespace/on_unimplemented/on_impl_trait.rs
index 32a492c53a950..1ffa604b2bc06 100644
--- a/tests/ui/diagnostic_namespace/on_impl_trait.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/on_impl_trait.rs
@@ -1,5 +1,6 @@
-// used to ICE, see <https://github.com/rust-lang/rust/issues/130627>
-// Instead it should just ignore the diagnostic attribute
+//! used to ICE, see <https://github.com/rust-lang/rust/issues/130627>
+//! Instead it should just ignore the diagnostic attribute
+
 #![feature(trait_alias)]
 
 trait Test {}
diff --git a/tests/ui/diagnostic_namespace/on_impl_trait.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/on_impl_trait.stderr
similarity index 88%
rename from tests/ui/diagnostic_namespace/on_impl_trait.stderr
rename to tests/ui/diagnostic_namespace/on_unimplemented/on_impl_trait.stderr
index 59b9c31bc53ea..5eee647892271 100644
--- a/tests/ui/diagnostic_namespace/on_impl_trait.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/on_impl_trait.stderr
@@ -1,5 +1,5 @@
 warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
-  --> $DIR/on_impl_trait.rs:7:1
+  --> $DIR/on_impl_trait.rs:8:1
    |
 LL | #[diagnostic::on_unimplemented(message = "blah", label = "blah", note = "blah")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | #[diagnostic::on_unimplemented(message = "blah", label = "blah", note = "bl
    = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
 
 error[E0277]: the trait bound `{integer}: Alias` is not satisfied
-  --> $DIR/on_impl_trait.rs:15:9
+  --> $DIR/on_impl_trait.rs:16:9
    |
 LL |     foo(&1);
    |     --- ^^ the trait `Test` is not implemented for `{integer}`
@@ -15,13 +15,13 @@ LL |     foo(&1);
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/on_impl_trait.rs:5:1
+  --> $DIR/on_impl_trait.rs:6:1
    |
 LL | trait Test {}
    | ^^^^^^^^^^
    = note: required for `{integer}` to implement `Alias`
 note: required by a bound in `foo`
-  --> $DIR/on_impl_trait.rs:12:11
+  --> $DIR/on_impl_trait.rs:13:11
    |
 LL | fn foo<T: Alias>(v: &T) {}
    |           ^^^^^ required by this bound in `foo`

From fc2cd77e114a651755f39f2d9dc5cec6911f4bd9 Mon Sep 17 00:00:00 2001
From: mejrs <59372212+mejrs@users.noreply.github.com>
Date: Tue, 29 Apr 2025 12:19:55 +0200
Subject: [PATCH 10/17] Fix comment describing what the test does

---
 tests/ui/on-unimplemented/expected-comma-found-token.rs    | 7 ++-----
 .../ui/on-unimplemented/expected-comma-found-token.stderr  | 2 +-
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/tests/ui/on-unimplemented/expected-comma-found-token.rs b/tests/ui/on-unimplemented/expected-comma-found-token.rs
index 8fb34f21152ab..d60ab3341fd6d 100644
--- a/tests/ui/on-unimplemented/expected-comma-found-token.rs
+++ b/tests/ui/on-unimplemented/expected-comma-found-token.rs
@@ -1,7 +1,6 @@
-// Tests that two closures cannot simultaneously have mutable
-// access to the variable, whether that mutable access be used
-// for direct assignment or for taking mutable ref. Issue #6801.
+//! Test for invalid MetaItem syntax in the attribute
 
+#![crate_type = "lib"]
 #![feature(rustc_attrs)]
 
 #[rustc_on_unimplemented(
@@ -9,5 +8,3 @@
     label="the label" //~ ERROR expected `,`, found `label`
 )]
 trait T {}
-
-fn main() {  }
diff --git a/tests/ui/on-unimplemented/expected-comma-found-token.stderr b/tests/ui/on-unimplemented/expected-comma-found-token.stderr
index 7c0874e36a6a9..2717100a1dc64 100644
--- a/tests/ui/on-unimplemented/expected-comma-found-token.stderr
+++ b/tests/ui/on-unimplemented/expected-comma-found-token.stderr
@@ -1,5 +1,5 @@
 error: expected `,`, found `label`
-  --> $DIR/expected-comma-found-token.rs:9:5
+  --> $DIR/expected-comma-found-token.rs:8:5
    |
 LL |     message="the message"
    |                          - expected `,`

From 923ca85a18e576ac0b132e6adf41541285f55ccc Mon Sep 17 00:00:00 2001
From: Oli Scherer <github333195615777966@oli-obk.de>
Date: Tue, 29 Apr 2025 10:15:19 +0000
Subject: [PATCH 11/17] Add test

---
 .../drop-manually-drop-no-drop-impl.rs        | 17 +++++++++++++
 .../drop-manually-drop.new.stderr             | 11 +++++++++
 .../drop-manually-drop.old.stderr             | 11 +++++++++
 .../traits/const-traits/drop-manually-drop.rs | 24 +++++++++++++++++++
 4 files changed, 63 insertions(+)
 create mode 100644 tests/ui/traits/const-traits/drop-manually-drop-no-drop-impl.rs
 create mode 100644 tests/ui/traits/const-traits/drop-manually-drop.new.stderr
 create mode 100644 tests/ui/traits/const-traits/drop-manually-drop.old.stderr
 create mode 100644 tests/ui/traits/const-traits/drop-manually-drop.rs

diff --git a/tests/ui/traits/const-traits/drop-manually-drop-no-drop-impl.rs b/tests/ui/traits/const-traits/drop-manually-drop-no-drop-impl.rs
new file mode 100644
index 0000000000000..060a543d6c3db
--- /dev/null
+++ b/tests/ui/traits/const-traits/drop-manually-drop-no-drop-impl.rs
@@ -0,0 +1,17 @@
+//@[new] compile-flags: -Znext-solver
+//@ revisions: old new
+//@ check-pass
+
+use std::mem::ManuallyDrop;
+
+struct Moose;
+
+impl Drop for Moose {
+    fn drop(&mut self) {}
+}
+
+struct ConstDropper<T>(ManuallyDrop<T>);
+
+const fn foo(_var: ConstDropper<Moose>) {}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/drop-manually-drop.new.stderr b/tests/ui/traits/const-traits/drop-manually-drop.new.stderr
new file mode 100644
index 0000000000000..ab152f7389721
--- /dev/null
+++ b/tests/ui/traits/const-traits/drop-manually-drop.new.stderr
@@ -0,0 +1,11 @@
+error[E0493]: destructor of `ConstDropper<Moose>` cannot be evaluated at compile-time
+  --> $DIR/drop-manually-drop.rs:21:14
+   |
+LL | const fn foo(_var: ConstDropper<Moose>) {}
+   |              ^^^^                        - value is dropped here
+   |              |
+   |              the destructor for this type cannot be evaluated in constant functions
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/traits/const-traits/drop-manually-drop.old.stderr b/tests/ui/traits/const-traits/drop-manually-drop.old.stderr
new file mode 100644
index 0000000000000..ab152f7389721
--- /dev/null
+++ b/tests/ui/traits/const-traits/drop-manually-drop.old.stderr
@@ -0,0 +1,11 @@
+error[E0493]: destructor of `ConstDropper<Moose>` cannot be evaluated at compile-time
+  --> $DIR/drop-manually-drop.rs:21:14
+   |
+LL | const fn foo(_var: ConstDropper<Moose>) {}
+   |              ^^^^                        - value is dropped here
+   |              |
+   |              the destructor for this type cannot be evaluated in constant functions
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/traits/const-traits/drop-manually-drop.rs b/tests/ui/traits/const-traits/drop-manually-drop.rs
new file mode 100644
index 0000000000000..9dd3c1e22814b
--- /dev/null
+++ b/tests/ui/traits/const-traits/drop-manually-drop.rs
@@ -0,0 +1,24 @@
+//@[new] compile-flags: -Znext-solver
+//@ revisions: old new
+
+#![feature(const_destruct)]
+#![feature(const_trait_impl)]
+
+use std::mem::ManuallyDrop;
+
+struct Moose;
+
+impl Drop for Moose {
+    fn drop(&mut self) {}
+}
+
+struct ConstDropper<T>(ManuallyDrop<T>);
+
+impl<T> const Drop for ConstDropper<T> {
+    fn drop(&mut self) {}
+}
+
+const fn foo(_var: ConstDropper<Moose>) {}
+//~^ ERROR destructor of `ConstDropper<Moose>` cannot be evaluated at compile-time
+
+fn main() {}

From a1c70590b26943370975dd04986739901a31f5db Mon Sep 17 00:00:00 2001
From: Oli Scherer <github333195615777966@oli-obk.de>
Date: Tue, 29 Apr 2025 10:20:16 +0000
Subject: [PATCH 12/17] Treat `ManuallyDrop` as `~const Destruct`

---
 .../src/solve/assembly/structural_traits.rs           |  3 +++
 compiler/rustc_trait_selection/src/traits/effects.rs  |  3 +++
 .../traits/const-traits/drop-manually-drop.new.stderr | 11 -----------
 .../traits/const-traits/drop-manually-drop.old.stderr | 11 -----------
 tests/ui/traits/const-traits/drop-manually-drop.rs    |  2 +-
 5 files changed, 7 insertions(+), 23 deletions(-)
 delete mode 100644 tests/ui/traits/const-traits/drop-manually-drop.new.stderr
 delete mode 100644 tests/ui/traits/const-traits/drop-manually-drop.old.stderr

diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
index 035bfff89b53c..b16f74cd8e431 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -724,6 +724,9 @@ pub(in crate::solve) fn const_conditions_for_destruct<I: Interner>(
     let destruct_def_id = cx.require_lang_item(TraitSolverLangItem::Destruct);
 
     match self_ty.kind() {
+        // `ManuallyDrop` is trivially `~const Destruct` as we do not run any drop glue on it.
+        ty::Adt(adt_def, _) if adt_def.is_manually_drop() => Ok(vec![]),
+
         // An ADT is `~const Destruct` only if all of the fields are,
         // *and* if there is a `Drop` impl, that `Drop` impl is also `~const`.
         ty::Adt(adt_def, args) => {
diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs
index defbafac20b39..1b5dcef2e59df 100644
--- a/compiler/rustc_trait_selection/src/traits/effects.rs
+++ b/compiler/rustc_trait_selection/src/traits/effects.rs
@@ -252,6 +252,9 @@ fn evaluate_host_effect_for_destruct_goal<'tcx>(
     let self_ty = obligation.predicate.self_ty();
 
     let const_conditions = match *self_ty.kind() {
+        // `ManuallyDrop` is trivially `~const Destruct` as we do not run any drop glue on it.
+        ty::Adt(adt_def, _) if adt_def.is_manually_drop() => thin_vec![],
+
         // An ADT is `~const Destruct` only if all of the fields are,
         // *and* if there is a `Drop` impl, that `Drop` impl is also `~const`.
         ty::Adt(adt_def, args) => {
diff --git a/tests/ui/traits/const-traits/drop-manually-drop.new.stderr b/tests/ui/traits/const-traits/drop-manually-drop.new.stderr
deleted file mode 100644
index ab152f7389721..0000000000000
--- a/tests/ui/traits/const-traits/drop-manually-drop.new.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0493]: destructor of `ConstDropper<Moose>` cannot be evaluated at compile-time
-  --> $DIR/drop-manually-drop.rs:21:14
-   |
-LL | const fn foo(_var: ConstDropper<Moose>) {}
-   |              ^^^^                        - value is dropped here
-   |              |
-   |              the destructor for this type cannot be evaluated in constant functions
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/traits/const-traits/drop-manually-drop.old.stderr b/tests/ui/traits/const-traits/drop-manually-drop.old.stderr
deleted file mode 100644
index ab152f7389721..0000000000000
--- a/tests/ui/traits/const-traits/drop-manually-drop.old.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0493]: destructor of `ConstDropper<Moose>` cannot be evaluated at compile-time
-  --> $DIR/drop-manually-drop.rs:21:14
-   |
-LL | const fn foo(_var: ConstDropper<Moose>) {}
-   |              ^^^^                        - value is dropped here
-   |              |
-   |              the destructor for this type cannot be evaluated in constant functions
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/traits/const-traits/drop-manually-drop.rs b/tests/ui/traits/const-traits/drop-manually-drop.rs
index 9dd3c1e22814b..62e8a815f1002 100644
--- a/tests/ui/traits/const-traits/drop-manually-drop.rs
+++ b/tests/ui/traits/const-traits/drop-manually-drop.rs
@@ -1,5 +1,6 @@
 //@[new] compile-flags: -Znext-solver
 //@ revisions: old new
+//@ check-pass
 
 #![feature(const_destruct)]
 #![feature(const_trait_impl)]
@@ -19,6 +20,5 @@ impl<T> const Drop for ConstDropper<T> {
 }
 
 const fn foo(_var: ConstDropper<Moose>) {}
-//~^ ERROR destructor of `ConstDropper<Moose>` cannot be evaluated at compile-time
 
 fn main() {}

From a4ce307c0137dca593e2eaa982ee413c7ba03525 Mon Sep 17 00:00:00 2001
From: mejrs <59372212+mejrs@users.noreply.github.com>
Date: Tue, 29 Apr 2025 12:46:26 +0200
Subject: [PATCH 13/17] Coalesce duplicate missing clone tests

---
 src/tools/tidy/src/issues.txt         |  1 -
 src/tools/tidy/src/ui_tests.rs        |  2 +-
 tests/ui/issues/issue-2823.rs         | 14 -----------
 tests/ui/issues/issue-2823.stderr     | 16 ------------
 tests/ui/methods/clone-missing.rs     | 33 +++++++++++++++++-------
 tests/ui/methods/clone-missing.stderr | 25 ++++++++++++++-----
 tests/ui/noncopyable-class.rs         | 36 ---------------------------
 tests/ui/noncopyable-class.stderr     | 16 ------------
 8 files changed, 44 insertions(+), 99 deletions(-)
 delete mode 100644 tests/ui/issues/issue-2823.rs
 delete mode 100644 tests/ui/issues/issue-2823.stderr
 delete mode 100644 tests/ui/noncopyable-class.rs
 delete mode 100644 tests/ui/noncopyable-class.stderr

diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index f1ce3ccda0465..e6b5aa59622d2 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -1979,7 +1979,6 @@ ui/issues/issue-27997.rs
 ui/issues/issue-28105.rs
 ui/issues/issue-28109.rs
 ui/issues/issue-28181.rs
-ui/issues/issue-2823.rs
 ui/issues/issue-28279.rs
 ui/issues/issue-28344.rs
 ui/issues/issue-28433.rs
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 2e069af23d653..44dd1e50f5b04 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -17,7 +17,7 @@ use ignore::Walk;
 const ENTRY_LIMIT: u32 = 901;
 // FIXME: The following limits should be reduced eventually.
 
-const ISSUES_ENTRY_LIMIT: u32 = 1626;
+const ISSUES_ENTRY_LIMIT: u32 = 1624;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files
diff --git a/tests/ui/issues/issue-2823.rs b/tests/ui/issues/issue-2823.rs
deleted file mode 100644
index 7b443b4152613..0000000000000
--- a/tests/ui/issues/issue-2823.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-struct C {
-    x: isize,
-}
-
-impl Drop for C {
-    fn drop(&mut self) {
-        println!("dropping: {}", self.x);
-    }
-}
-
-fn main() {
-    let c = C{ x: 2};
-    let _d = c.clone(); //~ ERROR no method named `clone` found
-}
diff --git a/tests/ui/issues/issue-2823.stderr b/tests/ui/issues/issue-2823.stderr
deleted file mode 100644
index 5cd3f080450d6..0000000000000
--- a/tests/ui/issues/issue-2823.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0599]: no method named `clone` found for struct `C` in the current scope
-  --> $DIR/issue-2823.rs:13:16
-   |
-LL | struct C {
-   | -------- method `clone` not found for this struct
-...
-LL |     let _d = c.clone();
-   |                ^^^^^ method not found in `C`
-   |
-   = help: items from traits can only be used if the trait is implemented and in scope
-   = note: the following trait defines an item `clone`, perhaps you need to implement it:
-           candidate #1: `Clone`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/methods/clone-missing.rs b/tests/ui/methods/clone-missing.rs
index f2e4ad268c63a..c5ecd3f175e2d 100644
--- a/tests/ui/methods/clone-missing.rs
+++ b/tests/ui/methods/clone-missing.rs
@@ -1,19 +1,34 @@
-// This test checks that calling `.clone()` on a type that does not implement the `Clone` trait
-// results in a compilation error. The `Foo` struct does not derive or implement `Clone`,
-// so attempting to clone it should fail.
+//! This test checks that calling `.clone()` on a type that does
+//! not implement the `Clone` trait results in a compilation error.
+//! The `NotClone` and AlsoNotClone structs do not derive or
+//! implement `Clone`, so attempting to clone them should fail.
 
-struct Foo {
-  i: isize,
+struct NotClone {
+    i: isize,
 }
 
-fn foo(i:isize) -> Foo {
-    Foo {
-        i: i
+fn not_clone(i: isize) -> NotClone {
+    NotClone { i }
+}
+
+struct AlsoNotClone {
+    i: isize,
+    j: NotClone,
+}
+
+fn also_not_clone(i: isize) -> AlsoNotClone {
+    AlsoNotClone {
+        i,
+        j: NotClone { i: i },
     }
 }
 
 fn main() {
-    let x = foo(10);
+    let x = not_clone(10);
+    let _y = x.clone();
+    //~^ ERROR no method named `clone` found
+
+    let x = also_not_clone(10);
     let _y = x.clone();
     //~^ ERROR no method named `clone` found
 }
diff --git a/tests/ui/methods/clone-missing.stderr b/tests/ui/methods/clone-missing.stderr
index 4ab1aae4934bf..8676e73c8ca25 100644
--- a/tests/ui/methods/clone-missing.stderr
+++ b/tests/ui/methods/clone-missing.stderr
@@ -1,16 +1,29 @@
-error[E0599]: no method named `clone` found for struct `Foo` in the current scope
-  --> $DIR/clone-missing.rs:17:16
+error[E0599]: no method named `clone` found for struct `NotClone` in the current scope
+  --> $DIR/clone-missing.rs:28:16
    |
-LL | struct Foo {
-   | ---------- method `clone` not found for this struct
+LL | struct NotClone {
+   | --------------- method `clone` not found for this struct
 ...
 LL |     let _y = x.clone();
-   |                ^^^^^ method not found in `Foo`
+   |                ^^^^^ method not found in `NotClone`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `clone`, perhaps you need to implement it:
            candidate #1: `Clone`
 
-error: aborting due to 1 previous error
+error[E0599]: no method named `clone` found for struct `AlsoNotClone` in the current scope
+  --> $DIR/clone-missing.rs:32:16
+   |
+LL | struct AlsoNotClone {
+   | ------------------- method `clone` not found for this struct
+...
+LL |     let _y = x.clone();
+   |                ^^^^^ method not found in `AlsoNotClone`
+   |
+   = help: items from traits can only be used if the trait is implemented and in scope
+   = note: the following trait defines an item `clone`, perhaps you need to implement it:
+           candidate #1: `Clone`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/noncopyable-class.rs b/tests/ui/noncopyable-class.rs
deleted file mode 100644
index 11b6eb736e9db..0000000000000
--- a/tests/ui/noncopyable-class.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Test that a class with a non-copyable field can't be
-// copied
-
-#[derive(Debug)]
-struct Bar {
-  x: isize,
-}
-
-impl Drop for Bar {
-    fn drop(&mut self) {}
-}
-
-fn bar(x:isize) -> Bar {
-    Bar {
-        x: x
-    }
-}
-
-#[derive(Debug)]
-struct Foo {
-  i: isize,
-  j: Bar,
-}
-
-fn foo(i:isize) -> Foo {
-    Foo {
-        i: i,
-        j: bar(5)
-    }
-}
-
-fn main() {
-    let x = foo(10);
-    let _y = x.clone(); //~ ERROR no method named `clone` found
-    println!("{:?}", x);
-}
diff --git a/tests/ui/noncopyable-class.stderr b/tests/ui/noncopyable-class.stderr
deleted file mode 100644
index b8f7276c898f8..0000000000000
--- a/tests/ui/noncopyable-class.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0599]: no method named `clone` found for struct `Foo` in the current scope
-  --> $DIR/noncopyable-class.rs:34:16
-   |
-LL | struct Foo {
-   | ---------- method `clone` not found for this struct
-...
-LL |     let _y = x.clone();
-   |                ^^^^^ method not found in `Foo`
-   |
-   = help: items from traits can only be used if the trait is implemented and in scope
-   = note: the following trait defines an item `clone`, perhaps you need to implement it:
-           candidate #1: `Clone`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0599`.

From 64bcf3b9f66e9bc070e2d1b1ee7e643ba098f880 Mon Sep 17 00:00:00 2001
From: Zalathar <Zalathar@users.noreply.github.com>
Date: Tue, 29 Apr 2025 17:55:17 +1000
Subject: [PATCH 14/17] Rename `rustc_query_append!` to
 `rustc_with_all_queries!`

---
 compiler/rustc_macros/src/query.rs             | 18 +++++++++++++++---
 .../rustc_middle/src/dep_graph/dep_node.rs     |  4 +++-
 compiler/rustc_middle/src/query/mod.rs         |  2 +-
 compiler/rustc_query_impl/src/lib.rs           |  2 +-
 compiler/rustc_query_impl/src/plumbing.rs      |  2 +-
 5 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs
index 62bf34ad5adce..33fb13e23bf89 100644
--- a/compiler/rustc_macros/src/query.rs
+++ b/compiler/rustc_macros/src/query.rs
@@ -407,11 +407,23 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
     }
 
     TokenStream::from(quote! {
+        /// Higher-order macro that invokes the specified macro with a prepared
+        /// list of all query signatures (including modifiers).
+        ///
+        /// This allows multiple simpler macros to each have access to the list
+        /// of queries.
         #[macro_export]
-        macro_rules! rustc_query_append {
-            ($macro:ident! $( [$($other:tt)*] )?) => {
+        macro_rules! rustc_with_all_queries {
+            (
+                // The macro to invoke once, on all queries (plus extras).
+                $macro:ident!
+
+                // Within [], an optional list of extra "query" signatures to
+                // pass to the given macro, in addition to the actual queries.
+                $( [$($extra_fake_queries:tt)*] )?
+            ) => {
                 $macro! {
-                    $( $($other)* )?
+                    $( $($extra_fake_queries)* )?
                     #query_stream
                 }
             }
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index 644cdac5d5543..348a1fcf331bf 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -83,7 +83,9 @@ macro_rules! define_dep_nodes {
     };
 }
 
-rustc_query_append!(define_dep_nodes![
+// Create various data structures for each query, and also for a few things
+// that aren't queries.
+rustc_with_all_queries!(define_dep_nodes![
     /// We use this for most things when incr. comp. is turned off.
     [] fn Null() -> (),
     /// We use this to create a forever-red node.
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index b55e4d7d83176..88f4c4ae4d361 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -2578,5 +2578,5 @@ rustc_queries! {
     }
 }
 
-rustc_query_append! { define_callbacks! }
+rustc_with_all_queries! { define_callbacks! }
 rustc_feedable_queries! { define_feedable! }
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index 3c329dd0a0e89..b7d8af2c995b5 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -234,7 +234,7 @@ pub fn query_system<'a>(
     }
 }
 
-rustc_middle::rustc_query_append! { define_queries! }
+rustc_middle::rustc_with_all_queries! { define_queries! }
 
 pub fn provide(providers: &mut rustc_middle::util::Providers) {
     providers.hooks.alloc_self_profile_query_strings = alloc_self_profile_query_strings;
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index 19ccc5587d6a6..0a4a9c44eb90d 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -575,7 +575,7 @@ where
 }
 
 // NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros
-// invoked by `rustc_query_append`.
+// invoked by `rustc_with_all_queries`.
 macro_rules! define_queries {
     (
      $($(#[$attr:meta])*

From ed2f4b6d2dd0bc5023223cf4a61c14b2b811f9cd Mon Sep 17 00:00:00 2001
From: Zalathar <Zalathar@users.noreply.github.com>
Date: Tue, 29 Apr 2025 17:31:05 +1000
Subject: [PATCH 15/17] Reformat parameters to macros used by with-all-queries

---
 compiler/rustc_middle/src/dep_graph/dep_node.rs | 7 +++++--
 compiler/rustc_middle/src/query/plumbing.rs     | 7 +++++--
 compiler/rustc_query_impl/src/plumbing.rs       | 7 +++++--
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index 348a1fcf331bf..0c998a2cbb38b 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -13,8 +13,11 @@ use crate::ty::TyCtxt;
 
 macro_rules! define_dep_nodes {
     (
-     $($(#[$attr:meta])*
-        [$($modifiers:tt)*] fn $variant:ident($($K:tt)*) -> $V:ty,)*) => {
+        $(
+            $(#[$attr:meta])*
+            [$($modifiers:tt)*] fn $variant:ident($($K:tt)*) -> $V:ty,
+        )*
+    ) => {
 
         #[macro_export]
         macro_rules! make_dep_kind_array {
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index 69b6f88d72bfd..769df1ffd6f91 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -313,8 +313,11 @@ macro_rules! separate_provide_extern_default {
 
 macro_rules! define_callbacks {
     (
-     $($(#[$attr:meta])*
-        [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
+        $(
+            $(#[$attr:meta])*
+            [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,
+        )*
+    ) => {
 
         #[allow(unused_lifetimes)]
         pub mod queries {
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index 0a4a9c44eb90d..d11fa8bad9be7 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -578,8 +578,11 @@ where
 // invoked by `rustc_with_all_queries`.
 macro_rules! define_queries {
     (
-     $($(#[$attr:meta])*
-        [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
+        $(
+            $(#[$attr:meta])*
+            [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,
+        )*
+    ) => {
 
         pub(crate) mod query_impl { $(pub(crate) mod $name {
             use super::super::*;

From 851decdd4f38463239a46031da53911b06da4336 Mon Sep 17 00:00:00 2001
From: binarycat <binarycat@envs.net>
Date: Mon, 31 Mar 2025 14:43:24 -0500
Subject: [PATCH 16/17] mention provenance in the pointer::wrapping_offset docs

fixes https://github.com/rust-lang/rust/issues/139008
---
 library/core/src/ptr/const_ptr.rs | 5 +++--
 library/core/src/ptr/mut_ptr.rs   | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 7d0839aff3f73..cd8a7481262b8 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -483,8 +483,9 @@ impl<T: ?Sized> *const T {
     ///
     /// This operation itself is always safe, but using the resulting pointer is not.
     ///
-    /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not
-    /// be used to read or write other allocated objects.
+    /// The resulting pointer "remembers" the [allocated object] that `self` points to
+    /// (this is called "[Provenance](ptr/index.html#provenance)").
+    /// The pointer must not be used to read or write other allocated objects.
     ///
     /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z`
     /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index b960a3d86bef0..0a70cbc1b031f 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -482,8 +482,9 @@ impl<T: ?Sized> *mut T {
     ///
     /// This operation itself is always safe, but using the resulting pointer is not.
     ///
-    /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not
-    /// be used to read or write other allocated objects.
+    /// The resulting pointer "remembers" the [allocated object] that `self` points to
+    /// (this is called "[Provenance](ptr/index.html#provenance)").
+    /// The pointer must not be used to read or write other allocated objects.
     ///
     /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z`
     /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still

From 7275462ab9924360eaec49cfb2a02324551a250f Mon Sep 17 00:00:00 2001
From: lcnr <rust@lcnr.de>
Date: Mon, 28 Apr 2025 17:38:11 +0000
Subject: [PATCH 17/17] canonical no type foldable :<

---
 compiler/rustc_hir_typeck/src/method/probe.rs |  2 +-
 compiler/rustc_hir_typeck/src/writeback.rs    | 22 +------------------
 .../rustc_middle/src/ty/structural_impls.rs   |  2 --
 .../rustc_middle/src/ty/typeck_results.rs     |  2 ++
 compiler/rustc_type_ir/src/canonical.rs       |  2 --
 5 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 1d3a081cbb884..bda051f156084 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -1213,7 +1213,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                 debug!("pick_all_method: step={:?}", step);
                 // skip types that are from a type error or that would require dereferencing
                 // a raw pointer
-                !step.self_ty.references_error() && !step.from_unsafe_deref
+                !step.self_ty.value.references_error() && !step.from_unsafe_deref
             })
             .find_map(|step| {
                 let InferOk { value: self_ty, obligations: _ } = self
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index c5000171ad75e..807d62562dbcc 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -9,7 +9,6 @@ use rustc_errors::ErrorGuaranteed;
 use rustc_hir::intravisit::{self, InferKind, Visitor};
 use rustc_hir::{self as hir, AmbigArg, HirId};
 use rustc_infer::traits::solve::Goal;
-use rustc_middle::span_bug;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
 use rustc_middle::ty::{
@@ -513,15 +512,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         self.typeck_results.user_provided_types_mut().extend(
             fcx_typeck_results.user_provided_types().items().map(|(local_id, c_ty)| {
                 let hir_id = HirId { owner: common_hir_owner, local_id };
-
-                if cfg!(debug_assertions) && c_ty.has_infer() {
-                    span_bug!(
-                        hir_id.to_span(self.fcx.tcx),
-                        "writeback: `{:?}` has inference variables",
-                        c_ty
-                    );
-                };
-
                 (hir_id, *c_ty)
             }),
         );
@@ -532,17 +522,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
 
         self.typeck_results.user_provided_sigs.extend_unord(
-            fcx_typeck_results.user_provided_sigs.items().map(|(&def_id, c_sig)| {
-                if cfg!(debug_assertions) && c_sig.has_infer() {
-                    span_bug!(
-                        self.fcx.tcx.def_span(def_id),
-                        "writeback: `{:?}` has inference variables",
-                        c_sig
-                    );
-                };
-
-                (def_id, *c_sig)
-            }),
+            fcx_typeck_results.user_provided_sigs.items().map(|(def_id, c_sig)| (*def_id, *c_sig)),
         );
     }
 
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 2fcb2a1572aed..58f7bc75054bb 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -13,7 +13,6 @@ use rustc_type_ir::{ConstKind, TypeFolder, VisitorResult, try_visit};
 
 use super::print::PrettyPrinter;
 use super::{GenericArg, GenericArgKind, Pattern, Region};
-use crate::infer::canonical::CanonicalVarInfos;
 use crate::mir::PlaceElem;
 use crate::ty::print::{FmtPrinter, Printer, with_no_trimmed_paths};
 use crate::ty::{
@@ -780,5 +779,4 @@ list_fold! {
     &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> : mk_poly_existential_predicates,
     &'tcx ty::List<PlaceElem<'tcx>> : mk_place_elems,
     &'tcx ty::List<ty::Pattern<'tcx>> : mk_patterns,
-    CanonicalVarInfos<'tcx> : mk_canonical_var_infos,
 }
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 8c5827d36df1e..c6a45f8468690 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -716,6 +716,8 @@ pub type CanonicalUserTypeAnnotations<'tcx> =
 
 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
 pub struct CanonicalUserTypeAnnotation<'tcx> {
+    #[type_foldable(identity)]
+    #[type_visitable(ignore)]
     pub user_ty: Box<CanonicalUserType<'tcx>>,
     pub span: Span,
     pub inferred_ty: Ty<'tcx>,
diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs
index 03d3194f1065d..67b67df4b2817 100644
--- a/compiler/rustc_type_ir/src/canonical.rs
+++ b/compiler/rustc_type_ir/src/canonical.rs
@@ -34,7 +34,6 @@ pub struct CanonicalQueryInput<I: Interner, V> {
 #[derive_where(Eq; I: Interner, V: Eq)]
 #[derive_where(Debug; I: Interner, V: fmt::Debug)]
 #[derive_where(Copy; I: Interner, V: Copy)]
-#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
 #[cfg_attr(
     feature = "nightly",
     derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
@@ -147,7 +146,6 @@ impl<I: Interner> CanonicalVarInfo<I> {
 /// in the type-theory sense of the term -- i.e., a "meta" type system
 /// that analyzes type-like values.
 #[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
-#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
 #[cfg_attr(
     feature = "nightly",
     derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)