about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-07-03 08:36:39 +0000
committerbors <bors@rust-lang.org>2024-07-03 08:36:39 +0000
commit2db4ff40af2b9f93b6240dbd67ed7f2f34b19776 (patch)
tree8192fd0adacbb541238aeab5aff048607c33d328
parentd68fe4eaa81305b53cdddc2339e8efdc2aa1e013 (diff)
parentd8017308725e3d79ece669878eee12534a5725b0 (diff)
downloadrust-2db4ff40af2b9f93b6240dbd67ed7f2f34b19776.tar.gz
rust-2db4ff40af2b9f93b6240dbd67ed7f2f34b19776.zip
Auto merge of #127261 - jhpratt:rollup-cpoayvr, r=jhpratt
Rollup of 8 pull requests

Successful merges:

 - #123588 (Stabilize `hint::assert_unchecked`)
 - #126403 (Actually report normalization-based type errors correctly for alias-relate obligations in new solver)
 - #126917 (Disable rmake test `inaccessible-temp-dir` on riscv64)
 - #127115 (unreferenced-used-static: run test everywhere)
 - #127204 (Stabilize atomic_bool_fetch_not)
 - #127239 (remove unnecessary ignore-endian-big from stack-overflow-trait-infer …)
 - #127245 (Add a test for `generic_const_exprs`)
 - #127246 (Give remote-test-client a longer timeout)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs149
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/core/src/hint.rs97
-rw-r--r--library/core/src/intrinsics.rs2
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/sync/atomic.rs3
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--src/tools/remote-test-client/src/main.rs2
-rw-r--r--tests/run-make/inaccessible-temp-dir/rmake.rs8
-rw-r--r--tests/ui/const-generics/generic_const_exprs/adt_wf_hang.rs14
-rw-r--r--tests/ui/const-generics/generic_const_exprs/adt_wf_hang.stderr18
-rw-r--r--tests/ui/consts/const-assert-unchecked-ub.rs6
-rw-r--r--tests/ui/consts/const-assert-unchecked-ub.stderr2
-rw-r--r--tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr5
-rw-r--r--tests/ui/linkage-attr/unreferenced-used-static-issue-127052.rs7
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr5
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr5
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr5
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr5
-rw-r--r--tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr4
-rw-r--r--tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr4
-rw-r--r--tests/ui/sized/stack-overflow-trait-infer-98842.rs3
-rw-r--r--tests/ui/traits/next-solver/async.fail.stderr6
-rw-r--r--tests/ui/traits/next-solver/async.rs2
-rw-r--r--tests/ui/traits/next-solver/more-object-bound.stderr15
25 files changed, 266 insertions, 104 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 3e316b78454..17b6dd2bc58 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -1586,60 +1586,113 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         }
 
         self.probe(|_| {
-            let ocx = ObligationCtxt::new(self);
-
             // try to find the mismatched types to report the error with.
             //
             // this can fail if the problem was higher-ranked, in which
             // cause I have no idea for a good error message.
             let bound_predicate = predicate.kind();
-            let (values, err) = if let ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) =
-                bound_predicate.skip_binder()
-            {
-                let data = self.instantiate_binder_with_fresh_vars(
-                    obligation.cause.span,
-                    infer::BoundRegionConversionTime::HigherRankedType,
-                    bound_predicate.rebind(data),
-                );
-                let unnormalized_term = data.projection_term.to_term(self.tcx);
-                // FIXME(-Znext-solver): For diagnostic purposes, it would be nice
-                // to deeply normalize this type.
-                let normalized_term =
-                    ocx.normalize(&obligation.cause, obligation.param_env, unnormalized_term);
-
-                debug!(?obligation.cause, ?obligation.param_env);
-
-                debug!(?normalized_term, data.ty = ?data.term);
+            let (values, err) = match bound_predicate.skip_binder() {
+                ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
+                    let ocx = ObligationCtxt::new(self);
+
+                    let data = self.instantiate_binder_with_fresh_vars(
+                        obligation.cause.span,
+                        infer::BoundRegionConversionTime::HigherRankedType,
+                        bound_predicate.rebind(data),
+                    );
+                    let unnormalized_term = data.projection_term.to_term(self.tcx);
+                    // FIXME(-Znext-solver): For diagnostic purposes, it would be nice
+                    // to deeply normalize this type.
+                    let normalized_term =
+                        ocx.normalize(&obligation.cause, obligation.param_env, unnormalized_term);
+
+                    let is_normalized_term_expected = !matches!(
+                        obligation.cause.code().peel_derives(),
+                        ObligationCauseCode::WhereClause(..)
+                            | ObligationCauseCode::WhereClauseInExpr(..)
+                            | ObligationCauseCode::Coercion { .. }
+                    );
 
-                let is_normalized_term_expected = !matches!(
-                    obligation.cause.code().peel_derives(),
-                    |ObligationCauseCode::WhereClause(..)| ObligationCauseCode::WhereClauseInExpr(
-                        ..
-                    ) | ObligationCauseCode::Coercion { .. }
-                );
+                    let (expected, actual) = if is_normalized_term_expected {
+                        (normalized_term, data.term)
+                    } else {
+                        (data.term, normalized_term)
+                    };
 
-                let (expected, actual) = if is_normalized_term_expected {
-                    (normalized_term, data.term)
-                } else {
-                    (data.term, normalized_term)
-                };
+                    // constrain inference variables a bit more to nested obligations from normalize so
+                    // we can have more helpful errors.
+                    //
+                    // we intentionally drop errors from normalization here,
+                    // since the normalization is just done to improve the error message.
+                    let _ = ocx.select_where_possible();
 
-                // constrain inference variables a bit more to nested obligations from normalize so
-                // we can have more helpful errors.
-                //
-                // we intentionally drop errors from normalization here,
-                // since the normalization is just done to improve the error message.
-                let _ = ocx.select_where_possible();
+                    if let Err(new_err) =
+                        ocx.eq(&obligation.cause, obligation.param_env, expected, actual)
+                    {
+                        (
+                            Some((
+                                data.projection_term,
+                                is_normalized_term_expected,
+                                self.resolve_vars_if_possible(normalized_term),
+                                data.term,
+                            )),
+                            new_err,
+                        )
+                    } else {
+                        (None, error.err)
+                    }
+                }
+                ty::PredicateKind::AliasRelate(lhs, rhs, _) => {
+                    let derive_better_type_error =
+                        |alias_term: ty::AliasTerm<'tcx>, expected_term: ty::Term<'tcx>| {
+                            let ocx = ObligationCtxt::new(self);
+                            let normalized_term = match expected_term.unpack() {
+                                ty::TermKind::Ty(_) => self.next_ty_var(DUMMY_SP).into(),
+                                ty::TermKind::Const(_) => self.next_const_var(DUMMY_SP).into(),
+                            };
+                            ocx.register_obligation(Obligation::new(
+                                self.tcx,
+                                ObligationCause::dummy(),
+                                obligation.param_env,
+                                ty::PredicateKind::NormalizesTo(ty::NormalizesTo {
+                                    alias: alias_term,
+                                    term: normalized_term,
+                                }),
+                            ));
+                            let _ = ocx.select_where_possible();
+                            if let Err(terr) = ocx.eq(
+                                &ObligationCause::dummy(),
+                                obligation.param_env,
+                                expected_term,
+                                normalized_term,
+                            ) {
+                                Some((terr, self.resolve_vars_if_possible(normalized_term)))
+                            } else {
+                                None
+                            }
+                        };
 
-                if let Err(new_err) =
-                    ocx.eq(&obligation.cause, obligation.param_env, expected, actual)
-                {
-                    (Some((data, is_normalized_term_expected, normalized_term, data.term)), new_err)
-                } else {
-                    (None, error.err)
+                    if let Some(lhs) = lhs.to_alias_term()
+                        && let Some((better_type_err, expected_term)) =
+                            derive_better_type_error(lhs, rhs)
+                    {
+                        (
+                            Some((lhs, true, self.resolve_vars_if_possible(expected_term), rhs)),
+                            better_type_err,
+                        )
+                    } else if let Some(rhs) = rhs.to_alias_term()
+                        && let Some((better_type_err, expected_term)) =
+                            derive_better_type_error(rhs, lhs)
+                    {
+                        (
+                            Some((rhs, true, self.resolve_vars_if_possible(expected_term), lhs)),
+                            better_type_err,
+                        )
+                    } else {
+                        (None, error.err)
+                    }
                 }
-            } else {
-                (None, error.err)
+                _ => (None, error.err),
             };
 
             let msg = values
@@ -1737,15 +1790,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
     fn maybe_detailed_projection_msg(
         &self,
-        pred: ty::ProjectionPredicate<'tcx>,
+        projection_term: ty::AliasTerm<'tcx>,
         normalized_ty: ty::Term<'tcx>,
         expected_ty: ty::Term<'tcx>,
     ) -> Option<String> {
-        let trait_def_id = pred.projection_term.trait_def_id(self.tcx);
-        let self_ty = pred.projection_term.self_ty();
+        let trait_def_id = projection_term.trait_def_id(self.tcx);
+        let self_ty = projection_term.self_ty();
 
         with_forced_trimmed_paths! {
-            if self.tcx.is_lang_item(pred.projection_term.def_id,LangItem::FnOnceOutput) {
+            if self.tcx.is_lang_item(projection_term.def_id, LangItem::FnOnceOutput) {
                 let fn_kind = self_ty.prefix_string(self.tcx);
                 let item = match self_ty.kind() {
                     ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(),
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index a1a2404a2ee..703538d0f35 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -127,7 +127,6 @@
 #![feature(fmt_internals)]
 #![feature(fn_traits)]
 #![feature(hasher_prefixfree_extras)]
-#![feature(hint_assert_unchecked)]
 #![feature(inplace_iteration)]
 #![feature(iter_advance_by)]
 #![feature(iter_next_chunk)]
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index c3b16c34293..976a6c04ca6 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -111,41 +111,92 @@ pub const unsafe fn unreachable_unchecked() -> ! {
 
 /// Makes a *soundness* promise to the compiler that `cond` holds.
 ///
-/// This may allow the optimizer to simplify things,
-/// but it might also make the generated code slower.
-/// Either way, calling it will most likely make compilation take longer.
+/// This may allow the optimizer to simplify things, but it might also make the generated code
+/// slower. Either way, calling it will most likely make compilation take longer.
 ///
-/// This is a situational tool for micro-optimization, and is allowed to do nothing.
-/// Any use should come with a repeatable benchmark to show the value
-/// and allow removing it later should the optimizer get smarter and no longer need it.
+/// You may know this from other places as
+/// [`llvm.assume`](https://llvm.org/docs/LangRef.html#llvm-assume-intrinsic) or, in C,
+/// [`__builtin_assume`](https://clang.llvm.org/docs/LanguageExtensions.html#builtin-assume).
 ///
-/// The more complicated the condition the less likely this is to be fruitful.
-/// For example, `assert_unchecked(foo.is_sorted())` is a complex enough value
-/// that the compiler is unlikely to be able to take advantage of it.
+/// This promotes a correctness requirement to a soundness requirement. Don't do that without
+/// very good reason.
 ///
-/// There's also no need to `assert_unchecked` basic properties of things.  For
-/// example, the compiler already knows the range of `count_ones`, so there's no
-/// benefit to `let n = u32::count_ones(x); assert_unchecked(n <= u32::BITS);`.
+/// # Usage
 ///
-/// If ever you're tempted to write `assert_unchecked(false)`, then you're
-/// actually looking for [`unreachable_unchecked()`].
+/// This is a situational tool for micro-optimization, and is allowed to do nothing. Any use
+/// should come with a repeatable benchmark to show the value, with the expectation to drop it
+/// later should the optimizer get smarter and no longer need it.
 ///
-/// You may know this from other places
-/// as [`llvm.assume`](https://llvm.org/docs/LangRef.html#llvm-assume-intrinsic)
-/// or [`__builtin_assume`](https://clang.llvm.org/docs/LanguageExtensions.html#builtin-assume).
+/// The more complicated the condition, the less likely this is to be useful. For example,
+/// `assert_unchecked(foo.is_sorted())` is a complex enough value that the compiler is unlikely
+/// to be able to take advantage of it.
 ///
-/// This promotes a correctness requirement to a soundness requirement.
-/// Don't do that without very good reason.
+/// There's also no need to `assert_unchecked` basic properties of things.  For example, the
+/// compiler already knows the range of `count_ones`, so there is no benefit to
+/// `let n = u32::count_ones(x); assert_unchecked(n <= u32::BITS);`.
+///
+/// `assert_unchecked` is logically equivalent to `if !cond { unreachable_unchecked(); }`. If
+/// ever you are tempted to write `assert_unchecked(false)`, you should instead use
+/// [`unreachable_unchecked()`] directly.
 ///
 /// # Safety
 ///
-/// `cond` must be `true`.  It's immediate UB to call this with `false`.
+/// `cond` must be `true`. It is immediate UB to call this with `false`.
+///
+/// # Example
+///
+/// ```
+/// use core::hint;
 ///
+/// /// # Safety
+/// ///
+/// /// `p` must be nonnull and valid
+/// pub unsafe fn next_value(p: *const i32) -> i32 {
+///     // SAFETY: caller invariants guarantee that `p` is not null
+///     unsafe { hint::assert_unchecked(!p.is_null()) }
+///
+///     if p.is_null() {
+///         return -1;
+///     } else {
+///         // SAFETY: caller invariants guarantee that `p` is valid
+///         unsafe { *p + 1 }
+///     }
+/// }
+/// ```
+///
+/// Without the `assert_unchecked`, the above function produces the following with optimizations
+/// enabled:
+///
+/// ```asm
+/// next_value:
+///         test    rdi, rdi
+///         je      .LBB0_1
+///         mov     eax, dword ptr [rdi]
+///         inc     eax
+///         ret
+/// .LBB0_1:
+///         mov     eax, -1
+///         ret
+/// ```
+///
+/// Adding the assertion allows the optimizer to remove the extra check:
+///
+/// ```asm
+/// next_value:
+///         mov     eax, dword ptr [rdi]
+///         inc     eax
+///         ret
+/// ```
+///
+/// This example is quite unlike anything that would be used in the real world: it is redundant
+/// to put an an assertion right next to code that checks the same thing, and dereferencing a
+/// pointer already has the builtin assumption that it is nonnull. However, it illustrates the
+/// kind of changes the optimizer can make even when the behavior is less obviously related.
+#[track_caller]
 #[inline(always)]
 #[doc(alias = "assume")]
-#[track_caller]
-#[unstable(feature = "hint_assert_unchecked", issue = "119131")]
-#[rustc_const_unstable(feature = "const_hint_assert_unchecked", issue = "119131")]
+#[stable(feature = "hint_assert_unchecked", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "hint_assert_unchecked", since = "CURRENT_RUSTC_VERSION")]
 pub const unsafe fn assert_unchecked(cond: bool) {
     // SAFETY: The caller promised `cond` is true.
     unsafe {
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 9ba1c6a4154..720da0feece 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -959,7 +959,7 @@ extern "rust-intrinsic" {
 /// not be used if the invariant can be discovered by the optimizer on its
 /// own, or if it does not enable any significant optimizations.
 ///
-/// This intrinsic does not have a stable counterpart.
+/// The stabilized version of this intrinsic is [`core::hint::assert_unchecked`].
 #[rustc_const_stable(feature = "const_assume", since = "1.77.0")]
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 128f1c81827..c5a1fca667b 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -127,7 +127,6 @@
 #![feature(const_fmt_arguments_new)]
 #![feature(const_hash)]
 #![feature(const_heap)]
-#![feature(const_hint_assert_unchecked)]
 #![feature(const_index_range_slice_index)]
 #![feature(const_int_from_str)]
 #![feature(const_intrinsic_copy)]
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index df108f5e0e4..efc07f38f68 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -1069,7 +1069,6 @@ impl AtomicBool {
     /// # Examples
     ///
     /// ```
-    /// #![feature(atomic_bool_fetch_not)]
     /// use std::sync::atomic::{AtomicBool, Ordering};
     ///
     /// let foo = AtomicBool::new(true);
@@ -1081,7 +1080,7 @@ impl AtomicBool {
     /// assert_eq!(foo.load(Ordering::SeqCst), true);
     /// ```
     #[inline]
-    #[unstable(feature = "atomic_bool_fetch_not", issue = "98485")]
+    #[stable(feature = "atomic_bool_fetch_not", since = "CURRENT_RUSTC_VERSION")]
     #[cfg(target_has_atomic = "8")]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub fn fetch_not(&self, order: Ordering) -> bool {
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index c8691a9a609..6f9ac3d4acb 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -334,7 +334,6 @@
 #![feature(fmt_internals)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
-#![feature(hint_assert_unchecked)]
 #![feature(ip)]
 #![feature(maybe_uninit_slice)]
 #![feature(maybe_uninit_write_slice)]
diff --git a/src/tools/remote-test-client/src/main.rs b/src/tools/remote-test-client/src/main.rs
index dd2c09c430b..42de3caf547 100644
--- a/src/tools/remote-test-client/src/main.rs
+++ b/src/tools/remote-test-client/src/main.rs
@@ -71,7 +71,7 @@ fn spawn_emulator(target: &str, server: &Path, tmpdir: &Path, rootfs: Option<Pat
 
     // Wait for the emulator to come online
     loop {
-        let dur = Duration::from_millis(100);
+        let dur = Duration::from_millis(2000);
         if let Ok(mut client) = TcpStream::connect(&device_address) {
             t!(client.set_read_timeout(Some(dur)));
             t!(client.set_write_timeout(Some(dur)));
diff --git a/tests/run-make/inaccessible-temp-dir/rmake.rs b/tests/run-make/inaccessible-temp-dir/rmake.rs
index 6b3e9e0b29e..b98e151e906 100644
--- a/tests/run-make/inaccessible-temp-dir/rmake.rs
+++ b/tests/run-make/inaccessible-temp-dir/rmake.rs
@@ -13,13 +13,18 @@
 // use a directory with non-existing parent like `/does-not-exist/output`.
 // See https://github.com/rust-lang/rust/issues/66530
 
+//@ ignore-riscv64
+// FIXME: The riscv build container runs as root, and can always write
+// into `inaccessible/tmp`. Ideally, the riscv64-gnu docker container
+// would use a non-root user, but this leads to issues with
+// `mkfs.ext4 -d`, as well as mounting a loop device for the rootfs.
 //@ ignore-arm
 // Reason: linker error on `armhf-gnu`
 //@ ignore-windows
 // Reason: `set_readonly` has no effect on directories
 // and does not prevent modification.
 
-use run_make_support::{fs_wrapper, rustc, target, test_while_readonly};
+use run_make_support::{fs_wrapper, rustc, test_while_readonly};
 
 fn main() {
     // Create an inaccessible directory.
@@ -28,7 +33,6 @@ fn main() {
         // Run rustc with `-Z temps-dir` set to a directory *inside* the inaccessible one,
         // so that it can't create `tmp`.
         rustc()
-            .target(target())
             .input("program.rs")
             .arg("-Ztemps-dir=inaccessible/tmp")
             .run_fail()
diff --git a/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.rs b/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.rs
new file mode 100644
index 00000000000..5d538d2679d
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.rs
@@ -0,0 +1,14 @@
+#![feature(generic_const_exprs)]
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
+#![allow(dead_code)]
+
+#[derive(PartialEq, Eq)]
+struct U;
+
+struct S<const N: U>()
+where
+    S<{ U }>:;
+//~^ ERROR: overflow evaluating the requirement `S<{ U }> well-formed`
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.stderr b/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.stderr
new file mode 100644
index 00000000000..b244acb37dd
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.stderr
@@ -0,0 +1,18 @@
+error[E0275]: overflow evaluating the requirement `S<{ U }> well-formed`
+  --> $DIR/adt_wf_hang.rs:11:5
+   |
+LL |     S<{ U }>:;
+   |     ^^^^^^^^
+   |
+note: required by a bound in `S`
+  --> $DIR/adt_wf_hang.rs:11:5
+   |
+LL | struct S<const N: U>()
+   |        - required by a bound in this struct
+LL | where
+LL |     S<{ U }>:;
+   |     ^^^^^^^^ required by this bound in `S`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/consts/const-assert-unchecked-ub.rs b/tests/ui/consts/const-assert-unchecked-ub.rs
index 5c05b813048..ffc02eedcb7 100644
--- a/tests/ui/consts/const-assert-unchecked-ub.rs
+++ b/tests/ui/consts/const-assert-unchecked-ub.rs
@@ -1,10 +1,6 @@
-#![feature(hint_assert_unchecked)]
-#![feature(const_hint_assert_unchecked)]
-
 const _: () = unsafe {
     let n = u32::MAX.count_ones();
     std::hint::assert_unchecked(n < 32); //~ ERROR evaluation of constant value failed
 };
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/consts/const-assert-unchecked-ub.stderr b/tests/ui/consts/const-assert-unchecked-ub.stderr
index 3957a3b1c24..468f15f3472 100644
--- a/tests/ui/consts/const-assert-unchecked-ub.stderr
+++ b/tests/ui/consts/const-assert-unchecked-ub.stderr
@@ -1,5 +1,5 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const-assert-unchecked-ub.rs:6:5
+  --> $DIR/const-assert-unchecked-ub.rs:3:5
    |
 LL |     std::hint::assert_unchecked(n < 32);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `assume` called with `false`
diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr
index d189d2dbded..a686b913c55 100644
--- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr
+++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr
@@ -29,7 +29,10 @@ error[E0271]: type mismatch resolving `<SelectInt as Expression>::SqlType == Tex
   --> $DIR/as_expression.rs:57:5
    |
 LL |     SelectInt.check("bar");
-   |     ^^^^^^^^^^^^^^^^^^^^^^ types differ
+   |     ^^^^^^^^^^^^^^^^^^^^^^ expected `Integer`, found `Text`
+   |
+   = note: expected struct `Integer`
+              found struct `Text`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/linkage-attr/unreferenced-used-static-issue-127052.rs b/tests/ui/linkage-attr/unreferenced-used-static-issue-127052.rs
index aa8236b7431..0d34bf988ef 100644
--- a/tests/ui/linkage-attr/unreferenced-used-static-issue-127052.rs
+++ b/tests/ui/linkage-attr/unreferenced-used-static-issue-127052.rs
@@ -1,9 +1,10 @@
-// This is a non-regression test for issue #127052 where unreferenced `#[used]` statics couldn't be
-// removed by the MSVC linker, causing linking errors.
+// This is a non-regression test for issue #127052 where unreferenced `#[used]` statics in the
+// binary crate would be marked as "exported", but not be present in the binary, causing linking
+// errors with the MSVC linker.
 
 //@ build-pass: needs linking
-//@ only-msvc
 
 #[used]
 static FOO: u32 = 0;
+
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr
index 4a949e90d85..03536dca1e8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr
@@ -2,7 +2,10 @@ error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Inde
   --> $DIR/issue-100222.rs:34:12
    |
 LL |     fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
-   |            ^^^^^^^^^ types differ
+   |            ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output`
+   |
+   = note:      expected unit type `()`
+           found mutable reference `&mut <() as Index>::Output`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr
index 1bfce48d26a..6a70a503606 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr
@@ -2,7 +2,10 @@ error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Inde
   --> $DIR/issue-100222.rs:25:12
    |
 LL |     fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
-   |            ^^^^^^^^^ types differ
+   |            ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output`
+   |
+   = note:      expected unit type `()`
+           found mutable reference `&mut <() as Index>::Output`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr
index 4a949e90d85..03536dca1e8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr
@@ -2,7 +2,10 @@ error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Inde
   --> $DIR/issue-100222.rs:34:12
    |
 LL |     fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
-   |            ^^^^^^^^^ types differ
+   |            ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output`
+   |
+   = note:      expected unit type `()`
+           found mutable reference `&mut <() as Index>::Output`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr
index 1bfce48d26a..6a70a503606 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr
@@ -2,7 +2,10 @@ error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Inde
   --> $DIR/issue-100222.rs:25:12
    |
 LL |     fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
-   |            ^^^^^^^^^ types differ
+   |            ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output`
+   |
+   = note:      expected unit type `()`
+           found mutable reference `&mut <() as Index>::Output`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr b/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr
index 6bbd81ae3e1..c01b2ccd163 100644
--- a/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr
+++ b/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr
@@ -3,14 +3,14 @@ error[E0391]: cycle detected when computing layout of `Foo`
    = note: ...which requires computing layout of `<&'static Foo as core::ops::deref::Deref>::Target`...
    = note: ...which again requires computing layout of `Foo`, completing the cycle
 note: cycle used when const-evaluating + checking `_`
-  --> $DIR/stack-overflow-trait-infer-98842.rs:15:1
+  --> $DIR/stack-overflow-trait-infer-98842.rs:14:1
    |
 LL | const _: *const Foo = 0 as _;
    | ^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/stack-overflow-trait-infer-98842.rs:15:1
+  --> $DIR/stack-overflow-trait-infer-98842.rs:14:1
    |
 LL | const _: *const Foo = 0 as _;
    | ^^^^^^^^^^^^^^^^^^^ a cycle occurred during layout computation
diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr b/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr
index 6bbd81ae3e1..c01b2ccd163 100644
--- a/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr
+++ b/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr
@@ -3,14 +3,14 @@ error[E0391]: cycle detected when computing layout of `Foo`
    = note: ...which requires computing layout of `<&'static Foo as core::ops::deref::Deref>::Target`...
    = note: ...which again requires computing layout of `Foo`, completing the cycle
 note: cycle used when const-evaluating + checking `_`
-  --> $DIR/stack-overflow-trait-infer-98842.rs:15:1
+  --> $DIR/stack-overflow-trait-infer-98842.rs:14:1
    |
 LL | const _: *const Foo = 0 as _;
    | ^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/stack-overflow-trait-infer-98842.rs:15:1
+  --> $DIR/stack-overflow-trait-infer-98842.rs:14:1
    |
 LL | const _: *const Foo = 0 as _;
    | ^^^^^^^^^^^^^^^^^^^ a cycle occurred during layout computation
diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.rs b/tests/ui/sized/stack-overflow-trait-infer-98842.rs
index be4807b2e4a..8a958870b0e 100644
--- a/tests/ui/sized/stack-overflow-trait-infer-98842.rs
+++ b/tests/ui/sized/stack-overflow-trait-infer-98842.rs
@@ -3,8 +3,7 @@
 //@ check-fail
 //@ edition:2021
 //@ stderr-per-bitwidth
-//@ ignore-endian-big
-//~^^^^^^ ERROR cycle detected when computing layout of `Foo`
+//~^^^^^ ERROR cycle detected when computing layout of `Foo`
 
 // If the inner `Foo` is named through an associated type,
 // the "infinite size" error does not occur.
diff --git a/tests/ui/traits/next-solver/async.fail.stderr b/tests/ui/traits/next-solver/async.fail.stderr
index 83d520341bc..e47da338736 100644
--- a/tests/ui/traits/next-solver/async.fail.stderr
+++ b/tests/ui/traits/next-solver/async.fail.stderr
@@ -1,11 +1,13 @@
-error[E0271]: type mismatch resolving `<{async block@$DIR/async.rs:12:17: 12:22} as Future>::Output == i32`
+error[E0271]: expected `{async block@$DIR/async.rs:12:17: 12:22}` to be a future that resolves to `i32`, but it resolves to `()`
   --> $DIR/async.rs:12:17
    |
 LL |     needs_async(async {});
-   |     ----------- ^^^^^^^^ types differ
+   |     ----------- ^^^^^^^^ expected `()`, found `i32`
    |     |
    |     required by a bound introduced by this call
    |
+   = note: expected unit type `()`
+                   found type `i32`
 note: required by a bound in `needs_async`
   --> $DIR/async.rs:8:31
    |
diff --git a/tests/ui/traits/next-solver/async.rs b/tests/ui/traits/next-solver/async.rs
index 129e4cfaa02..fded7743547 100644
--- a/tests/ui/traits/next-solver/async.rs
+++ b/tests/ui/traits/next-solver/async.rs
@@ -10,7 +10,7 @@ fn needs_async(_: impl Future<Output = i32>) {}
 #[cfg(fail)]
 fn main() {
     needs_async(async {});
-    //[fail]~^ ERROR type mismatch
+    //[fail]~^ ERROR expected `{async block@$DIR/async.rs:12:17: 12:22}` to be a future that resolves to `i32`, but it resolves to `()`
 }
 
 #[cfg(pass)]
diff --git a/tests/ui/traits/next-solver/more-object-bound.stderr b/tests/ui/traits/next-solver/more-object-bound.stderr
index 8cc2a51ee2b..043cbdff9ab 100644
--- a/tests/ui/traits/next-solver/more-object-bound.stderr
+++ b/tests/ui/traits/next-solver/more-object-bound.stderr
@@ -1,9 +1,22 @@
 error[E0271]: type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
   --> $DIR/more-object-bound.rs:12:5
    |
+LL | fn transmute<A, B>(x: A) -> B {
+   |              -  -
+   |              |  |
+   |              |  expected type parameter
+   |              |  found type parameter
+   |              found type parameter
+   |              expected type parameter
 LL |     foo::<A, B, dyn Trait<A = A, B = B>>(x)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `A`, found type parameter `B`
    |
+   = note: expected type parameter `A`
+              found type parameter `B`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
    = note: required because it appears within the type `dyn Trait<A = A, B = B>`
 note: required by a bound in `foo`
   --> $DIR/more-object-bound.rs:18:8