about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs32
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs5
-rw-r--r--compiler/rustc_incremental/src/persist/fs.rs20
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs19
-rw-r--r--library/core/src/intrinsics/mir.rs9
-rw-r--r--library/std/src/sys/solid/os.rs30
-rw-r--r--library/std/src/sys/unix/os.rs21
-rw-r--r--library/std/src/sys/wasi/os.rs23
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.rs4
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr6
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr6
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.rs4
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.none.stderr4
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.rs4
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr6
-rw-r--r--src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr6
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.none.stderr4
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.rs2
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.stack.stderr4
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.tree.stderr4
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.rs6
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.stderr8
-rw-r--r--src/tools/miri/tests/pass/function_calls/return_place_on_heap.rs2
-rw-r--r--tests/mir-opt/building/custom/terminators.rs4
-rw-r--r--tests/mir-opt/copy-prop/borrowed_local.rs4
-rw-r--r--tests/mir-opt/copy-prop/custom_move_arg.rs4
-rw-r--r--tests/mir-opt/copy-prop/move_projection.rs4
-rw-r--r--tests/mir-opt/reference_prop.rs10
-rw-r--r--tests/rustdoc-gui/search-form-elements.goml386
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr20
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-1.rs1
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-2.rs2
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-2.stderr37
35 files changed, 275 insertions, 436 deletions
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 5bc0e2ee86c..31a03fabe4f 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -389,34 +389,26 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                 if let ty::Ref(reg, cast_ty, mutbl) = *self.cast_ty.kind() {
                     if let ty::RawPtr(TypeAndMut { ty: expr_ty, .. }) = *self.expr_ty.kind()
                         && fcx
-                            .try_coerce(
-                                self.expr,
+                            .can_coerce(
                                 Ty::new_ref(fcx.tcx,
                                     fcx.tcx.lifetimes.re_erased,
                                     TypeAndMut { ty: expr_ty, mutbl },
                                 ),
                                 self.cast_ty,
-                                AllowTwoPhase::No,
-                                None,
                             )
-                            .is_ok()
                     {
                         sugg = Some((format!("&{}*", mutbl.prefix_str()), cast_ty == expr_ty));
                     } else if let ty::Ref(expr_reg, expr_ty, expr_mutbl) = *self.expr_ty.kind()
                         && expr_mutbl == Mutability::Not
                         && mutbl == Mutability::Mut
                         && fcx
-                            .try_coerce(
-                                self.expr,
+                            .can_coerce(
                                 Ty::new_ref(fcx.tcx,
                                     expr_reg,
                                     TypeAndMut { ty: expr_ty, mutbl: Mutability::Mut },
                                 ),
                                 self.cast_ty,
-                                AllowTwoPhase::No,
-                                None,
                             )
-                            .is_ok()
                     {
                         sugg_mutref = true;
                     }
@@ -424,30 +416,22 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                     if !sugg_mutref
                         && sugg == None
                         && fcx
-                            .try_coerce(
-                                self.expr,
+                            .can_coerce(
                                 Ty::new_ref(fcx.tcx,reg, TypeAndMut { ty: self.expr_ty, mutbl }),
                                 self.cast_ty,
-                                AllowTwoPhase::No,
-                                None,
                             )
-                            .is_ok()
                     {
                         sugg = Some((format!("&{}", mutbl.prefix_str()), false));
                     }
                 } else if let ty::RawPtr(TypeAndMut { mutbl, .. }) = *self.cast_ty.kind()
                     && fcx
-                        .try_coerce(
-                            self.expr,
+                        .can_coerce(
                             Ty::new_ref(fcx.tcx,
                                 fcx.tcx.lifetimes.re_erased,
                                 TypeAndMut { ty: self.expr_ty, mutbl },
                             ),
                             self.cast_ty,
-                            AllowTwoPhase::No,
-                            None,
                         )
-                        .is_ok()
                 {
                     sugg = Some((format!("&{}", mutbl.prefix_str()), false));
                 }
@@ -760,7 +744,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                     ty::FnDef(..) => {
                         // Attempt a coercion to a fn pointer type.
                         let f = fcx.normalize(self.expr_span, self.expr_ty.fn_sig(fcx.tcx));
-                        let res = fcx.try_coerce(
+                        let res = fcx.coerce(
                             self.expr,
                             self.expr_ty,
                             Ty::new_fn_ptr(fcx.tcx, f),
@@ -860,7 +844,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
 
             (_, DynStar) => {
                 if fcx.tcx.features().dyn_star {
-                    bug!("should be handled by `try_coerce`")
+                    bug!("should be handled by `coerce`")
                 } else {
                     Err(CastError::IllegalCast)
                 }
@@ -956,7 +940,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
 
                 // Coerce to a raw pointer so that we generate AddressOf in MIR.
                 let array_ptr_type = Ty::new_ptr(fcx.tcx, m_expr);
-                fcx.try_coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No, None)
+                fcx.coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No, None)
                     .unwrap_or_else(|_| {
                         bug!(
                         "could not cast from reference to array to pointer to array ({:?} to {:?})",
@@ -992,7 +976,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
     }
 
     fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<(), ty::error::TypeError<'tcx>> {
-        match fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty, AllowTwoPhase::No, None) {
+        match fcx.coerce(self.expr, self.expr_ty, self.cast_ty, AllowTwoPhase::No, None) {
             Ok(_) => Ok(()),
             Err(err) => Err(err),
         }
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 726914a995b..fca675ea9d8 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1005,7 +1005,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// adjusted type of the expression, if successful.
     /// Adjustments are only recorded if the coercion succeeded.
     /// The expressions *must not* have any preexisting adjustments.
-    pub fn try_coerce(
+    pub fn coerce(
         &self,
         expr: &hir::Expr<'_>,
         expr_ty: Ty<'tcx>,
@@ -1036,7 +1036,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         })
     }
 
-    /// Same as `try_coerce()`, but without side-effects.
+    /// Same as `coerce()`, but without side-effects.
     ///
     /// Returns false if the coercion creates any obligations that result in
     /// errors.
@@ -1494,7 +1494,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                 // Special-case the first expression we are coercing.
                 // To be honest, I'm not entirely sure why we do this.
                 // We don't allow two-phase borrows, see comment in try_find_coercion_lub for why
-                fcx.try_coerce(
+                fcx.coerce(
                     expression,
                     expression_ty,
                     self.expected_ty,
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 6aeabc1bebb..2c16f21b491 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -254,7 +254,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) -> (Ty<'tcx>, Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>>) {
         let expected = self.resolve_vars_with_obligations(expected);
 
-        let e = match self.try_coerce(expr, checked_ty, expected, allow_two_phase, None) {
+        let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) {
             Ok(ty) => return (ty, None),
             Err(e) => e,
         };
@@ -475,7 +475,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 {
                     let Some(arg_ty) = self.node_ty_opt(arg_expr.hir_id) else { continue; };
                     let arg_ty = arg_ty.fold_with(&mut fudger);
-                    let _ = self.try_coerce(
+                    let _ = self.coerce(
                         arg_expr,
                         arg_ty,
                         *expected_arg_ty,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 004c8affcf0..4def7867384 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -260,9 +260,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // fulfillment error to be more accurate.
             let coerced_ty = self.resolve_vars_with_obligations(coerced_ty);
 
-            let coerce_error = self
-                .try_coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None)
-                .err();
+            let coerce_error =
+                self.coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None).err();
 
             if coerce_error.is_some() {
                 return Compatibility::Incompatible(coerce_error);
diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs
index 1111a1a17e2..db8ea2bfe48 100644
--- a/compiler/rustc_incremental/src/persist/fs.rs
+++ b/compiler/rustc_incremental/src/persist/fs.rs
@@ -538,9 +538,13 @@ where
             continue;
         }
 
-        let timestamp = extract_timestamp_from_session_dir(&directory_name).unwrap_or_else(|_| {
-            bug!("unexpected incr-comp session dir: {}", session_dir.display())
-        });
+        let timestamp = match extract_timestamp_from_session_dir(&directory_name) {
+            Ok(timestamp) => timestamp,
+            Err(e) => {
+                debug!("unexpected incr-comp session dir: {}: {}", session_dir.display(), e);
+                continue;
+            }
+        };
 
         if timestamp > best_candidate.0 {
             best_candidate = (timestamp, Some(session_dir.clone()));
@@ -562,14 +566,14 @@ fn is_session_directory_lock_file(file_name: &str) -> bool {
     file_name.starts_with("s-") && file_name.ends_with(LOCK_FILE_EXT)
 }
 
-fn extract_timestamp_from_session_dir(directory_name: &str) -> Result<SystemTime, ()> {
+fn extract_timestamp_from_session_dir(directory_name: &str) -> Result<SystemTime, &'static str> {
     if !is_session_directory(directory_name) {
-        return Err(());
+        return Err("not a directory");
     }
 
     let dash_indices: Vec<_> = directory_name.match_indices('-').map(|(idx, _)| idx).collect();
     if dash_indices.len() != 3 {
-        return Err(());
+        return Err("not three dashes in name");
     }
 
     string_to_timestamp(&directory_name[dash_indices[0] + 1..dash_indices[1]])
@@ -581,11 +585,11 @@ fn timestamp_to_string(timestamp: SystemTime) -> String {
     base_n::encode(micros as u128, INT_ENCODE_BASE)
 }
 
-fn string_to_timestamp(s: &str) -> Result<SystemTime, ()> {
+fn string_to_timestamp(s: &str) -> Result<SystemTime, &'static str> {
     let micros_since_unix_epoch = u64::from_str_radix(s, INT_ENCODE_BASE as u32);
 
     if micros_since_unix_epoch.is_err() {
-        return Err(());
+        return Err("timestamp not an int");
     }
 
     let micros_since_unix_epoch = micros_since_unix_epoch.unwrap();
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
index fe5190900e9..26662f5de45 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -61,9 +61,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
                 })
             },
             @call("mir_call", args) => {
-                let destination = self.parse_place(args[0])?;
-                let target = self.parse_block(args[1])?;
-                self.parse_call(args[2], destination, target)
+                self.parse_call(args)
             },
             ExprKind::Match { scrutinee, arms, .. } => {
                 let discr = self.parse_operand(*scrutinee)?;
@@ -109,13 +107,14 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
         Ok(SwitchTargets::new(values.into_iter().zip(targets), otherwise))
     }
 
-    fn parse_call(
-        &self,
-        expr_id: ExprId,
-        destination: Place<'tcx>,
-        target: BasicBlock,
-    ) -> PResult<TerminatorKind<'tcx>> {
-        parse_by_kind!(self, expr_id, _, "function call",
+    fn parse_call(&self, args: &[ExprId]) -> PResult<TerminatorKind<'tcx>> {
+        let (destination, call) = parse_by_kind!(self, args[0], _, "function call",
+            ExprKind::Assign { lhs, rhs } => (*lhs, *rhs),
+        );
+        let destination = self.parse_place(destination)?;
+        let target = self.parse_block(args[1])?;
+
+        parse_by_kind!(self, call, _, "function call",
             ExprKind::Call { fun, args, from_hir_call, fn_span, .. } => {
                 let fun = self.parse_operand(*fun)?;
                 let args = args
diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs
index 036edbebbf3..ef0a2fd4ec4 100644
--- a/library/core/src/intrinsics/mir.rs
+++ b/library/core/src/intrinsics/mir.rs
@@ -104,17 +104,18 @@
 //! }
 //!
 //! #[custom_mir(dialect = "runtime", phase = "optimized")]
+#![cfg_attr(bootstrap, doc = "#[cfg(any())]")] // disable the following function in doctests when `bootstrap` is set
 //! fn push_and_pop<T>(v: &mut Vec<T>, value: T) {
 //!     mir!(
-//!         let unused;
+//!         let _unused;
 //!         let popped;
 //!
 //!         {
-//!             Call(unused, pop, Vec::push(v, value))
+//!             Call(_unused = Vec::push(v, value), pop)
 //!         }
 //!
 //!         pop = {
-//!             Call(popped, drop, Vec::pop(v))
+//!             Call(popped = Vec::pop(v), drop)
 //!         }
 //!
 //!         drop = {
@@ -275,7 +276,7 @@ define!("mir_return", fn Return() -> BasicBlock);
 define!("mir_goto", fn Goto(destination: BasicBlock) -> BasicBlock);
 define!("mir_unreachable", fn Unreachable() -> BasicBlock);
 define!("mir_drop", fn Drop<T>(place: T, goto: BasicBlock));
-define!("mir_call", fn Call<T>(place: T, goto: BasicBlock, call: T));
+define!("mir_call", fn Call(call: (), goto: BasicBlock));
 define!("mir_storage_live", fn StorageLive<T>(local: T));
 define!("mir_storage_dead", fn StorageDead<T>(local: T));
 define!("mir_deinit", fn Deinit<T>(place: T));
diff --git a/library/std/src/sys/solid/os.rs b/library/std/src/sys/solid/os.rs
index 717c08434a8..9f4e66d628b 100644
--- a/library/std/src/sys/solid/os.rs
+++ b/library/std/src/sys/solid/os.rs
@@ -81,6 +81,10 @@ pub fn current_exe() -> io::Result<PathBuf> {
 
 static ENV_LOCK: RwLock<()> = RwLock::new(());
 
+pub fn env_read_lock() -> impl Drop {
+    ENV_LOCK.read().unwrap_or_else(PoisonError::into_inner)
+}
+
 pub struct Env {
     iter: vec::IntoIter<(OsString, OsString)>,
 }
@@ -134,7 +138,7 @@ pub fn env() -> Env {
     }
 
     unsafe {
-        let _guard = ENV_LOCK.read();
+        let _guard = env_read_lock();
         let mut result = Vec::new();
         if !environ.is_null() {
             while !(*environ).is_null() {
@@ -168,17 +172,21 @@ pub fn env() -> Env {
 pub fn getenv(k: &OsStr) -> Option<OsString> {
     // environment variables with a nul byte can't be set, so their value is
     // always None as well
-    let s = run_with_cstr(k.as_bytes(), |k| {
-        let _guard = ENV_LOCK.read();
-        Ok(unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char)
-    })
-    .ok()?;
+    run_with_cstr(k.as_bytes(), |k| {
+        let _guard = env_read_lock();
+        let v = unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char;
 
-    if s.is_null() {
-        None
-    } else {
-        Some(OsStringExt::from_vec(unsafe { CStr::from_ptr(s) }.to_bytes().to_vec()))
-    }
+        if v.is_null() {
+            Ok(None)
+        } else {
+            // SAFETY: `v` cannot be mutated while executing this line since we've a read lock
+            let bytes = unsafe { CStr::from_ptr(v) }.to_bytes().to_vec();
+
+            Ok(Some(OsStringExt::from_vec(bytes)))
+        }
+    })
+    .ok()
+    .flatten()
 }
 
 pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs
index 215f63d04f7..57e1a36dace 100644
--- a/library/std/src/sys/unix/os.rs
+++ b/library/std/src/sys/unix/os.rs
@@ -594,16 +594,21 @@ pub fn env() -> Env {
 pub fn getenv(k: &OsStr) -> Option<OsString> {
     // environment variables with a nul byte can't be set, so their value is
     // always None as well
-    let s = run_with_cstr(k.as_bytes(), |k| {
+    run_with_cstr(k.as_bytes(), |k| {
         let _guard = env_read_lock();
-        Ok(unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char)
+        let v = unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char;
+
+        if v.is_null() {
+            Ok(None)
+        } else {
+            // SAFETY: `v` cannot be mutated while executing this line since we've a read lock
+            let bytes = unsafe { CStr::from_ptr(v) }.to_bytes().to_vec();
+
+            Ok(Some(OsStringExt::from_vec(bytes)))
+        }
     })
-    .ok()?;
-    if s.is_null() {
-        None
-    } else {
-        Some(OsStringExt::from_vec(unsafe { CStr::from_ptr(s) }.to_bytes().to_vec()))
-    }
+    .ok()
+    .flatten()
 }
 
 pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
diff --git a/library/std/src/sys/wasi/os.rs b/library/std/src/sys/wasi/os.rs
index e0de284c5e2..d53bddd8e9d 100644
--- a/library/std/src/sys/wasi/os.rs
+++ b/library/std/src/sys/wasi/os.rs
@@ -225,16 +225,23 @@ pub fn env() -> Env {
 }
 
 pub fn getenv(k: &OsStr) -> Option<OsString> {
-    let s = run_with_cstr(k.as_bytes(), |k| unsafe {
+    // environment variables with a nul byte can't be set, so their value is
+    // always None as well
+    run_with_cstr(k.as_bytes(), |k| {
         let _guard = env_read_lock();
-        Ok(libc::getenv(k.as_ptr()) as *const libc::c_char)
+        let v = unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char;
+
+        if v.is_null() {
+            Ok(None)
+        } else {
+            // SAFETY: `v` cannot be mutated while executing this line since we've a read lock
+            let bytes = unsafe { CStr::from_ptr(v) }.to_bytes().to_vec();
+
+            Ok(Some(OsStringExt::from_vec(bytes)))
+        }
     })
-    .ok()?;
-    if s.is_null() {
-        None
-    } else {
-        Some(OsStringExt::from_vec(unsafe { CStr::from_ptr(s) }.to_bytes().to_vec()))
-    }
+    .ok()
+    .flatten()
 }
 
 pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.rs b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.rs
index 625a8bda8af..d47af50d407 100644
--- a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.rs
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.rs
@@ -8,13 +8,13 @@ pub struct S(i32);
 #[custom_mir(dialect = "runtime", phase = "optimized")]
 fn main() {
     mir! {
-        let unit: ();
+        let _unit: ();
         {
             let non_copy = S(42);
             let ptr = std::ptr::addr_of_mut!(non_copy);
             // Inside `callee`, the first argument and `*ptr` are basically
             // aliasing places!
-            Call(unit, after_call, callee(Move(*ptr), ptr))
+            Call(_unit = callee(Move(*ptr), ptr), after_call)
         }
         after_call = {
             Return()
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr
index 471dc1dd6dd..381442e69b1 100644
--- a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.stack.stderr
@@ -10,7 +10,7 @@ help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
   --> $DIR/arg_inplace_mutate.rs:LL:CC
    |
 LL | /     mir! {
-LL | |         let unit: ();
+LL | |         let _unit: ();
 LL | |         {
 LL | |             let non_copy = S(42);
 ...  |
@@ -27,8 +27,8 @@ LL |     unsafe { ptr.write(S(0)) };
 note: inside `main`
   --> $DIR/arg_inplace_mutate.rs:LL:CC
    |
-LL |             Call(unit, after_call, callee(Move(*ptr), ptr))
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |             Call(_unit = callee(Move(*ptr), ptr), after_call)
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr
index 8393b80f25b..544cd575ada 100644
--- a/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_mutate.tree.stderr
@@ -12,7 +12,7 @@ help: the accessed tag <TAG> was created here
   --> $DIR/arg_inplace_mutate.rs:LL:CC
    |
 LL | /     mir! {
-LL | |         let unit: ();
+LL | |         let _unit: ();
 LL | |         {
 LL | |             let non_copy = S(42);
 ...  |
@@ -29,8 +29,8 @@ LL |     unsafe { ptr.write(S(0)) };
 note: inside `main`
   --> $DIR/arg_inplace_mutate.rs:LL:CC
    |
-LL |             Call(unit, after_call, callee(Move(*ptr), ptr))
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |             Call(_unit = callee(Move(*ptr), ptr), after_call)
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.rs b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.rs
index 093b55759fd..ea773048dd4 100644
--- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.rs
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.rs
@@ -6,12 +6,12 @@ pub struct S(i32);
 #[custom_mir(dialect = "runtime", phase = "optimized")]
 fn main() {
     mir! {
-        let unit: ();
+        let _unit: ();
         let _observe: i32;
         {
             let non_copy = S(42);
             // This could change `non_copy` in-place
-            Call(unit, after_call, change_arg(Move(non_copy)))
+            Call(_unit = change_arg(Move(non_copy)), after_call)
         }
         after_call = {
             // So now we must not be allowed to observe non-copy again.
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.none.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.none.stderr
index baa91484793..cba23c21d12 100644
--- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.none.stderr
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.none.stderr
@@ -11,8 +11,8 @@ LL |     unsafe { ptr.read() };
 note: inside `main`
   --> $DIR/arg_inplace_observe_during.rs:LL:CC
    |
-LL |             Call(unit, after_call, change_arg(Move(*ptr), ptr))
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |             Call(_unit = change_arg(Move(*ptr), ptr), after_call)
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
 
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.rs b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.rs
index 2e57872db96..8c6a7df7a6d 100644
--- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.rs
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.rs
@@ -9,12 +9,12 @@ pub struct S(i32);
 #[custom_mir(dialect = "runtime", phase = "optimized")]
 fn main() {
     mir! {
-        let unit: ();
+        let _unit: ();
         {
             let non_copy = S(42);
             let ptr = std::ptr::addr_of_mut!(non_copy);
             // This could change `non_copy` in-place
-            Call(unit, after_call, change_arg(Move(*ptr), ptr))
+            Call(_unit = change_arg(Move(*ptr), ptr), after_call)
         }
         after_call = {
             Return()
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr
index a842d3a8044..f8532186be2 100644
--- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.stack.stderr
@@ -10,7 +10,7 @@ help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
   --> $DIR/arg_inplace_observe_during.rs:LL:CC
    |
 LL | /     mir! {
-LL | |         let unit: ();
+LL | |         let _unit: ();
 LL | |         {
 LL | |             let non_copy = S(42);
 ...  |
@@ -27,8 +27,8 @@ LL |     x.0 = 0;
 note: inside `main`
   --> $DIR/arg_inplace_observe_during.rs:LL:CC
    |
-LL |             Call(unit, after_call, change_arg(Move(*ptr), ptr))
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |             Call(_unit = change_arg(Move(*ptr), ptr), after_call)
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr
index 5af4856bbe3..c33645bdd28 100644
--- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr
+++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_during.tree.stderr
@@ -12,7 +12,7 @@ help: the accessed tag <TAG> was created here
   --> $DIR/arg_inplace_observe_during.rs:LL:CC
    |
 LL | /     mir! {
-LL | |         let unit: ();
+LL | |         let _unit: ();
 LL | |         {
 LL | |             let non_copy = S(42);
 ...  |
@@ -29,8 +29,8 @@ LL |     x.0 = 0;
 note: inside `main`
   --> $DIR/arg_inplace_observe_during.rs:LL:CC
    |
-LL |             Call(unit, after_call, change_arg(Move(*ptr), ptr))
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |             Call(_unit = change_arg(Move(*ptr), ptr), after_call)
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.none.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.none.stderr
index 9d9dfc89f89..0a31adabf73 100644
--- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.none.stderr
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.none.stderr
@@ -11,8 +11,8 @@ LL |     unsafe { ptr.read() };
 note: inside `main`
   --> $DIR/return_pointer_aliasing.rs:LL:CC
    |
-LL |             Call(*ptr, after_call, myfun(ptr))
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |             Call(*ptr = myfun(ptr), after_call)
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
 
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.rs b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.rs
index 829809102fa..3d560af3d5e 100644
--- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.rs
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.rs
@@ -15,7 +15,7 @@ pub fn main() {
             let ptr = &raw mut x;
             // We arrange for `myfun` to have a pointer that aliases
             // its return place. Even just reading from that pointer is UB.
-            Call(*ptr, after_call, myfun(ptr))
+            Call(*ptr = myfun(ptr), after_call)
         }
 
         after_call = {
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.stack.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.stack.stderr
index d486dcb95df..875cc5edad9 100644
--- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.stack.stderr
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.stack.stderr
@@ -27,8 +27,8 @@ LL |     unsafe { ptr.read() };
 note: inside `main`
   --> $DIR/return_pointer_aliasing.rs:LL:CC
    |
-LL |             Call(*ptr, after_call, myfun(ptr))
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |             Call(*ptr = myfun(ptr), after_call)
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.tree.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.tree.stderr
index c491a904a10..66c2fb8db19 100644
--- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.tree.stderr
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing.tree.stderr
@@ -29,8 +29,8 @@ LL |     unsafe { ptr.read() };
 note: inside `main`
   --> $DIR/return_pointer_aliasing.rs:LL:CC
    |
-LL |             Call(*ptr, after_call, myfun(ptr))
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |             Call(*ptr = myfun(ptr), after_call)
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.rs b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.rs
index 7e9a6320026..9d53faccd1e 100644
--- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.rs
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.rs
@@ -9,11 +9,11 @@ use std::intrinsics::mir::*;
 pub fn main() {
     mir! {
         {
-            let x = 0;
-            let ptr = &raw mut x;
+            let _x = 0;
+            let ptr = &raw mut _x;
             // We arrange for `myfun` to have a pointer that aliases
             // its return place. Even just reading from that pointer is UB.
-            Call(x, after_call, myfun(ptr))
+            Call(_x = myfun(ptr), after_call)
         }
 
         after_call = {
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.stderr
index 33a8a4b46bd..443ee8643fc 100644
--- a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.stderr
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.stderr
@@ -13,8 +13,8 @@ help: the accessed tag <TAG> was created here
    |
 LL | /     mir! {
 LL | |         {
-LL | |             let x = 0;
-LL | |             let ptr = &raw mut x;
+LL | |             let _x = 0;
+LL | |             let ptr = &raw mut _x;
 ...  |
 LL | |         }
 LL | |     }
@@ -29,8 +29,8 @@ LL |     unsafe { ptr.write(0) };
 note: inside `main`
   --> $DIR/return_pointer_aliasing2.rs:LL:CC
    |
-LL |             Call(x, after_call, myfun(ptr))
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |             Call(_x = myfun(ptr), after_call)
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
diff --git a/src/tools/miri/tests/pass/function_calls/return_place_on_heap.rs b/src/tools/miri/tests/pass/function_calls/return_place_on_heap.rs
index dcfebd0f82b..d410a875b1b 100644
--- a/src/tools/miri/tests/pass/function_calls/return_place_on_heap.rs
+++ b/src/tools/miri/tests/pass/function_calls/return_place_on_heap.rs
@@ -11,7 +11,7 @@ pub fn main() {
         {
             let x = 0;
             let ptr = &raw mut x;
-            Call(*ptr, after_call, myfun())
+            Call(*ptr = myfun(), after_call)
         }
 
         after_call = {
diff --git a/tests/mir-opt/building/custom/terminators.rs b/tests/mir-opt/building/custom/terminators.rs
index f1240566168..123118f654e 100644
--- a/tests/mir-opt/building/custom/terminators.rs
+++ b/tests/mir-opt/building/custom/terminators.rs
@@ -12,7 +12,7 @@ fn ident<T>(t: T) -> T {
 fn direct_call(x: i32) -> i32 {
     mir!(
         {
-            Call(RET, retblock, ident(x))
+            Call(RET = ident(x), retblock)
         }
 
         retblock = {
@@ -26,7 +26,7 @@ fn direct_call(x: i32) -> i32 {
 fn indirect_call(x: i32, f: fn(i32) -> i32) -> i32 {
     mir!(
         {
-            Call(RET, retblock, f(x))
+            Call(RET = f(x), retblock)
         }
 
         retblock = {
diff --git a/tests/mir-opt/copy-prop/borrowed_local.rs b/tests/mir-opt/copy-prop/borrowed_local.rs
index a89b64441d0..bf94dc57d33 100644
--- a/tests/mir-opt/copy-prop/borrowed_local.rs
+++ b/tests/mir-opt/copy-prop/borrowed_local.rs
@@ -21,11 +21,11 @@ fn f() -> bool {
             let b = a;
             // We cannot propagate the place `a`.
             let r2 = &b;
-            Call(RET, next, cmp_ref(r1, r2))
+            Call(RET = cmp_ref(r1, r2), next)
         }
         next = {
             // But we can propagate the value `a`.
-            Call(RET, ret, opaque(b))
+            Call(RET = opaque(b), ret)
         }
         ret = {
             Return()
diff --git a/tests/mir-opt/copy-prop/custom_move_arg.rs b/tests/mir-opt/copy-prop/custom_move_arg.rs
index a90db08fa51..d1c5ffdff0d 100644
--- a/tests/mir-opt/copy-prop/custom_move_arg.rs
+++ b/tests/mir-opt/copy-prop/custom_move_arg.rs
@@ -13,11 +13,11 @@ struct NotCopy(bool);
 fn f(_1: NotCopy) {
     mir!({
         let _2 = _1;
-        Call(RET, bb1, opaque(Move(_1)))
+        Call(RET = opaque(Move(_1)), bb1)
     }
     bb1 = {
         let _3 = Move(_2);
-        Call(RET, bb2, opaque(_3))
+        Call(RET = opaque(_3), bb2)
     }
     bb2 = {
         Return()
diff --git a/tests/mir-opt/copy-prop/move_projection.rs b/tests/mir-opt/copy-prop/move_projection.rs
index 40f51ce8406..f94addb5629 100644
--- a/tests/mir-opt/copy-prop/move_projection.rs
+++ b/tests/mir-opt/copy-prop/move_projection.rs
@@ -17,10 +17,10 @@ fn f(a: Foo) -> bool {
             let b = a;
             // This is a move out of a copy, so must become a copy of `a.0`.
             let c = Move(b.0);
-            Call(RET, bb1, opaque(Move(a)))
+            Call(RET = opaque(Move(a)), bb1)
         }
         bb1 = {
-            Call(RET, ret, opaque(Move(c)))
+            Call(RET = opaque(Move(c)), ret)
         }
         ret = {
             Return()
diff --git a/tests/mir-opt/reference_prop.rs b/tests/mir-opt/reference_prop.rs
index 4083b45470b..610660131b1 100644
--- a/tests/mir-opt/reference_prop.rs
+++ b/tests/mir-opt/reference_prop.rs
@@ -426,7 +426,7 @@ fn multiple_storage() {
             // As there are multiple `StorageLive` statements for `x`, we cannot know if this `z`'s
             // pointer address is the address of `x`, so do nothing.
             let y = *z;
-            Call(RET, retblock, opaque(y))
+            Call(RET = opaque(y), retblock)
         }
 
         retblock = {
@@ -452,7 +452,7 @@ fn dominate_storage() {
         }
         bb1 = {
             let c = *r;
-            Call(RET, bb2, opaque(c))
+            Call(RET = opaque(c), bb2)
         }
         bb2 = {
             StorageDead(x);
@@ -486,18 +486,18 @@ fn maybe_dead(m: bool) {
         bb1 = {
             StorageDead(x);
             StorageDead(y);
-            Call(RET, bb2, opaque(u))
+            Call(RET = opaque(u), bb2)
         }
         bb2 = {
             // As `x` may be `StorageDead`, `a` may be dangling, so we do nothing.
             let z = *a;
-            Call(RET, bb3, opaque(z))
+            Call(RET = opaque(z), bb3)
         }
         bb3 = {
             // As `y` may be `StorageDead`, `b` may be dangling, so we do nothing.
             // This implies that we also do not substitute `b` in `bb0`.
             let t = *b;
-            Call(RET, retblock, opaque(t))
+            Call(RET = opaque(t), retblock)
         }
         retblock = {
             Return()
diff --git a/tests/rustdoc-gui/search-form-elements.goml b/tests/rustdoc-gui/search-form-elements.goml
index 83c6980909c..a4e22364859 100644
--- a/tests/rustdoc-gui/search-form-elements.goml
+++ b/tests/rustdoc-gui/search-form-elements.goml
@@ -2,262 +2,138 @@
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 show-text: true
 
-// Ayu theme
-set-local-storage: {
-    "rustdoc-theme": "ayu",
-    "rustdoc-use-system-theme": "false",
-}
-reload:
-
-assert-css: (
-    ".search-input",
-    {
-        "border-color": "rgb(92, 103, 115)",
-        "background-color": "rgb(20, 25, 32)",
-        "color": "rgb(255, 255, 255)",
-    },
-)
-focus: ".search-input"
-// Nothing should change.
-assert-css: (
-    ".search-input",
-    {
-        "border-color": "rgb(92, 103, 115)",
-        "background-color": "rgb(20, 25, 32)",
-        "color": "rgb(255, 255, 255)",
-    },
-)
-
-assert-css: (
-    "#help-button",
-    {"border-color": "rgb(197, 197, 197)"},
-)
-assert-css: (
-    "#help-button > a",
-    {
-        "color": "rgb(255, 255, 255)",
-        "border-color": "rgb(92, 103, 115)",
-        "background-color": "rgb(20, 25, 32)",
-    },
-)
-move-cursor-to: "#help-button"
-assert-css: (
-    "#help-button:hover",
-    {"border-color": "rgb(197, 197, 197)"},
-)
-// Only "border-color" should change.
-assert-css: (
-    "#help-button:hover > a",
-    {
-        "color": "rgb(255, 255, 255)",
-        "border-color": "rgb(224, 224, 224)",
-        "background-color": "rgb(20, 25, 32)",
-    },
-)
-// Link color inside
-click: "#help-button"
-assert-css: (
-    "#help a",
-    {
-        "color": "rgb(57, 175, 215)",
-    },
-)
-
-assert-css: (
-    "#settings-menu",
-    {"border-color": "rgb(197, 197, 197)"},
-)
-assert-css: (
-    "#settings-menu > a",
-    {
-        "border-color": "rgb(92, 103, 115)",
-        "background-color": "rgb(20, 25, 32)",
-    },
-)
-move-cursor-to: "#settings-menu"
-assert-css: (
-    "#settings-menu:hover",
-    {"border-color": "rgb(197, 197, 197)"},
-)
-// Only "border-color" should change.
-assert-css: (
-    "#settings-menu:hover > a",
-    {
-        "border-color": "rgb(224, 224, 224)",
-        "background-color": "rgb(20, 25, 32)",
-    },
-)
-
-// Dark theme
-set-local-storage: {
-    "rustdoc-theme": "dark",
-    "rustdoc-use-system-theme": "false",
-}
-reload:
-
-assert-css: (
-    ".search-input",
-    {
-        "border-color": "rgb(224, 224, 224)",
-        "background-color": "rgb(240, 240, 240)",
-        "color": "rgb(17, 17, 17)",
-    },
-)
-focus: ".search-input"
-// Only "border-color" should change.
-assert-css: (
-    ".search-input",
-    {
-        "border-color": "rgb(0, 141, 253)",
-        "background-color": "rgb(240, 240, 240)",
-        "color": "rgb(17, 17, 17)",
-    },
-)
-
-assert-css: (
-    "#help-button",
-    {"border-color": "rgb(221, 221, 221)"},
-)
-assert-css: (
-    "#help-button > a",
-    {
-        "color": "rgb(0, 0, 0)",
-        "border-color": "rgb(224, 224, 224)",
-        "background-color": "rgb(240, 240, 240)",
-    },
-)
-move-cursor-to: "#help-button"
-assert-css: (
-    "#help-button:hover",
-    {"border-color": "rgb(221, 221, 221)"},
-)
-// Only "border-color" should change.
-assert-css: (
-    "#help-button:hover > a",
-    {
-        "color": "rgb(0, 0, 0)",
-        "border-color": "rgb(255, 185, 0)",
-        "background-color": "rgb(240, 240, 240)",
-    },
-)
-// Link color inside
-click: "#help-button"
-assert-css: (
-    "#help a",
-    {
-        "color": "rgb(210, 153, 29)",
+define-function: (
+    "check-search-colors",
+    (
+        theme, border, background, search_input_color, search_input_border_focus,
+        menu_button_border, menu_button_a_color, menu_button_a_border_hover, menu_a_color,
+    ),
+    block {
+        set-local-storage: {
+            "rustdoc-theme": |theme|,
+            "rustdoc-use-system-theme": "false",
+        }
+        reload:
+        assert-css: (
+            ".search-input",
+            {
+                "border-color": |border|,
+                "background-color": |background|,
+                "color": |search_input_color|,
+            },
+        )
+        // Focus on search input.
+        focus: ".search-input"
+        assert-css: (
+            ".search-input",
+            {
+                "border-color": |search_input_border_focus|,
+                "background-color": |background|,
+                "color": |search_input_color|,
+            },
+        )
+        assert-css: (
+            "#help-button",
+            {"border-color": |menu_button_border|},
+        )
+        assert-css: (
+            "#help-button > a",
+            {
+                "color": |menu_button_a_color|,
+                "border-color": |border|,
+                "background-color": |background|,
+            },
+        )
+        // Hover help button.
+        move-cursor-to: "#help-button"
+        assert-css: (
+            "#help-button:hover",
+            {"border-color": |menu_button_border|},
+        )
+        assert-css: (
+            "#help-button > a",
+            {
+                "color": |menu_button_a_color|,
+                "border-color": |menu_button_a_border_hover|,
+                "background-color": |background|,
+            },
+        )
+        // Link color inside
+        click: "#help-button"
+        assert-css: (
+            "#help a",
+            {
+                "color": |menu_a_color|,
+            },
+        )
+        assert-css: (
+            "#settings-menu",
+            {"border-color": |menu_button_border|},
+        )
+        assert-css: (
+            "#settings-menu > a",
+            {
+                "color": |menu_button_a_color|,
+                "border-color": |border|,
+                "background-color": |background|,
+            },
+        )
+        // Hover settings menu.
+        move-cursor-to: "#settings-menu"
+        assert-css: (
+            "#settings-menu:hover",
+            {"border-color": |menu_button_border|},
+        )
+        assert-css: (
+            "#settings-menu:hover > a",
+            {
+                "color": |menu_button_a_color|,
+                "border-color": |menu_button_a_border_hover|,
+                "background-color": |background|,
+            },
+        )
     },
 )
 
-assert-css: (
-    "#settings-menu",
-    {"border-color": "rgb(221, 221, 221)"},
-)
-assert-css: (
-    "#settings-menu > a",
-    {
-        "border-color": "rgb(224, 224, 224)",
-        "background-color": "rgb(240, 240, 240)",
-    },
-)
-move-cursor-to: "#settings-menu"
-assert-css: (
-    "#settings-menu:hover",
-    {"border-color": "rgb(221, 221, 221)"},
-)
-// Only "border-color" should change.
-assert-css: (
-    "#settings-menu:hover > a",
-    {
-        "color": "rgb(0, 0, 0)",
-        "border-color": "rgb(255, 185, 0)",
-        "background-color": "rgb(240, 240, 240)",
-    },
-)
-
-// Light theme
-set-local-storage: {
-    "rustdoc-theme": "light",
-    "rustdoc-use-system-theme": "false",
-}
-reload:
-
-assert-css: (
-    ".search-input",
-    {
-        "border-color": "rgb(224, 224, 224)",
-        "background-color": "rgb(255, 255, 255)",
-        "color": "rgb(0, 0, 0)",
-    },
-)
-focus: ".search-input"
-// Nothing should change.
-assert-css: (
-    ".search-input",
-    {
-        "border-color": "rgb(102, 175, 233)",
-        "background-color": "rgb(255, 255, 255)",
-        "color": "rgb(0, 0, 0)",
-    },
-)
-
-assert-css: (
-    "#help-button",
-    {"border-color": "rgb(0, 0, 0)"},
-)
-assert-css: (
-    "#help-button > a",
-    {
-        "color": "rgb(0, 0, 0)",
-        "border-color": "rgb(224, 224, 224)",
-        "background-color": "rgb(255, 255, 255)",
-    },
-)
-move-cursor-to: "#help-button"
-assert-css: (
-    "#help-button:hover",
-    {"border-color": "rgb(0, 0, 0)"},
-)
-// Only "border-color" should change.
-assert-css: (
-    "#help-button:hover > a",
-    {
-        "color": "rgb(0, 0, 0)",
-        "border-color": "rgb(113, 113, 113)",
-        "background-color": "rgb(255, 255, 255)",
-    },
-)
-// Link color inside
-click: "#help-button"
-assert-css: (
-    "#help a",
-    {
-        "color": "rgb(56, 115, 173)",
-    },
-)
-
-assert-css: (
-    "#settings-menu",
-    {"border-color": "rgb(0, 0, 0)"},
-)
-assert-css: (
-    "#settings-menu > a",
-    {
-        "border-color": "rgb(224, 224, 224)",
-        "background-color": "rgb(255, 255, 255)",
-    },
-)
-move-cursor-to: "#settings-menu"
-assert-css: (
-    "#settings-menu:hover",
-    {"border-color": "rgb(0, 0, 0)"},
-)
-// Only "border-color" should change.
-assert-css: (
-    "#settings-menu:hover > a",
-    {
-        "color": "rgb(0, 0, 0)",
-        "border-color": "rgb(113, 113, 113)",
-        "background-color": "rgb(255, 255, 255)",
-    },
+call-function: (
+    "check-search-colors",
+    {
+        "theme": "ayu",
+        "border": "#5c6773",
+        "background": "#141920",
+        "search_input_color": "#fff",
+        "search_input_border_focus": "#5c6773",
+        "menu_button_border": "#c5c5c5",
+        "menu_button_a_color": "#fff",
+        "menu_button_a_border_hover": "#e0e0e0",
+        "menu_a_color": "#39afd7",
+    }
+)
+call-function: (
+    "check-search-colors",
+    {
+        "theme": "dark",
+        "border": "#e0e0e0",
+        "background": "#f0f0f0",
+        "search_input_color": "#111",
+        "search_input_border_focus": "#008dfd",
+        "menu_button_border": "#ddd",
+        "menu_button_a_color": "#000",
+        "menu_button_a_border_hover": "#ffb900",
+        "menu_a_color": "#d2991d",
+    }
+)
+call-function: (
+    "check-search-colors",
+    {
+        "theme": "light",
+        "border": "#e0e0e0",
+        "background": "#fff",
+        "search_input_color": "#000",
+        "search_input_border_focus": "#66afe9",
+        "menu_button_border": "#000",
+        "menu_button_a_color": "#000",
+        "menu_button_a_border_hover": "#717171",
+        "menu_a_color": "#3873ad",
+    }
 )
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr
index d48d9b89d1d..b612005fcb0 100644
--- a/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr
@@ -2,22 +2,8 @@ error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
   --> $DIR/type-checking-test-1.rs:19:13
    |
 LL |     let _ = x as &dyn Bar<_>; // Ambiguous
-   |             ^^^^^^^^^^^^^^^^ invalid cast
-   |
-help: consider borrowing the value
-   |
-LL |     let _ = &x as &dyn Bar<_>; // Ambiguous
-   |             +
-
-error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied
-  --> $DIR/type-checking-test-1.rs:19:13
-   |
-LL |     let _ = x as &dyn Bar<_>; // Ambiguous
-   |             ^ the trait `Bar<_>` is not implemented for `&dyn Foo`
-   |
-   = note: required for the cast from `&&dyn Foo` to `&dyn Bar<_>`
+   |             ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0277, E0605.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0605`.
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.rs b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs
index 7c7beec0809..afea8521e87 100644
--- a/tests/ui/traits/trait-upcasting/type-checking-test-1.rs
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs
@@ -18,7 +18,6 @@ fn test_specific(x: &dyn Foo) {
 fn test_unknown_version(x: &dyn Foo) {
     let _ = x as &dyn Bar<_>; // Ambiguous
                               //~^ ERROR non-primitive cast
-                              //[current]~^^ ERROR the trait bound `&dyn Foo: Bar<_>` is not satisfied
 }
 
 fn test_infer_version(x: &dyn Foo) {
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-2.rs b/tests/ui/traits/trait-upcasting/type-checking-test-2.rs
index 36b11dffdb1..b024b27750b 100644
--- a/tests/ui/traits/trait-upcasting/type-checking-test-2.rs
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-2.rs
@@ -18,13 +18,11 @@ fn test_specific2(x: &dyn Foo<u32>) {
 fn test_specific3(x: &dyn Foo<i32>) {
     let _ = x as &dyn Bar<u32>; // Error
                                 //~^ ERROR non-primitive cast
-                                //~^^ ERROR the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
 }
 
 fn test_infer_arg(x: &dyn Foo<u32>) {
     let a = x as &dyn Bar<_>; // Ambiguous
                               //~^ ERROR non-primitive cast
-                              //~^^ ERROR the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
     let _ = a.bar();
 }
 
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr
index 856303ef4dd..3e59b9d3363 100644
--- a/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr
@@ -2,41 +2,14 @@ error[E0605]: non-primitive cast: `&dyn Foo<i32>` as `&dyn Bar<u32>`
   --> $DIR/type-checking-test-2.rs:19:13
    |
 LL |     let _ = x as &dyn Bar<u32>; // Error
-   |             ^^^^^^^^^^^^^^^^^^ invalid cast
-   |
-help: consider borrowing the value
-   |
-LL |     let _ = &x as &dyn Bar<u32>; // Error
-   |             +
-
-error[E0277]: the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
-  --> $DIR/type-checking-test-2.rs:19:13
-   |
-LL |     let _ = x as &dyn Bar<u32>; // Error
-   |             ^ the trait `Bar<u32>` is not implemented for `&dyn Foo<i32>`
-   |
-   = note: required for the cast from `&&dyn Foo<i32>` to `&dyn Bar<u32>`
+   |             ^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
 
 error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>`
-  --> $DIR/type-checking-test-2.rs:25:13
+  --> $DIR/type-checking-test-2.rs:24:13
    |
 LL |     let a = x as &dyn Bar<_>; // Ambiguous
-   |             ^^^^^^^^^^^^^^^^ invalid cast
-   |
-help: consider borrowing the value
-   |
-LL |     let a = &x as &dyn Bar<_>; // Ambiguous
-   |             +
-
-error[E0277]: the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
-  --> $DIR/type-checking-test-2.rs:25:13
-   |
-LL |     let a = x as &dyn Bar<_>; // Ambiguous
-   |             ^ the trait `Bar<_>` is not implemented for `&dyn Foo<u32>`
-   |
-   = note: required for the cast from `&&dyn Foo<u32>` to `&dyn Bar<_>`
+   |             ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0277, E0605.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0605`.