about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-06-29 05:47:42 +0000
committerbors <bors@rust-lang.org>2022-06-29 05:47:42 +0000
commit493c960a3e6cdd2e2fbe8b6ea130fadea05f1ab0 (patch)
treee30296c258fa15a5e111bdc182b12bc1beffa428
parent116edb6800ea1d6615578e7f65366ae65364b3d8 (diff)
parent25fb2b47a506b1c9956d7fba14d12a5175866154 (diff)
downloadrust-493c960a3e6cdd2e2fbe8b6ea130fadea05f1ab0.tar.gz
rust-493c960a3e6cdd2e2fbe8b6ea130fadea05f1ab0.zip
Auto merge of #98656 - Dylan-DPC:rollup-hhytn0c, r=Dylan-DPC
Rollup of 7 pull requests

Successful merges:

 - #97423 (Simplify memory ordering intrinsics)
 - #97542 (Use typed indices in argument mismatch algorithm)
 - #97786 (Account for `-Z simulate-remapped-rust-src-base` when resolving remapped paths)
 - #98277 (Fix trait object reborrow suggestion)
 - #98525 (Add regression test for #79224)
 - #98549 (interpret: do not prune requires_caller_location stack frames quite so early)
 - #98603 (Some borrowck diagnostic fixes)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs53
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs55
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs58
-rw-r--r--compiler/rustc_const_eval/src/const_eval/error.rs12
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs17
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0093.md4
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs38
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs6
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs129
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/checks.rs1217
-rw-r--r--library/core/src/intrinsics.rs581
-rw-r--r--library/core/src/sync/atomic.rs160
-rw-r--r--src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs28
-rw-r--r--src/test/ui/argument-suggestions/basic.stderr2
-rw-r--r--src/test/ui/argument-suggestions/extra_arguments.stderr34
-rw-r--r--src/test/ui/argument-suggestions/issue-97484.stderr13
-rw-r--r--src/test/ui/argument-suggestions/mixed_cases.stderr8
-rw-r--r--src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr2
-rw-r--r--src/test/ui/associated-types/associated-types-eq-3.stderr2
-rw-r--r--src/test/ui/associated-types/associated-types-overridden-binding-2.stderr2
-rw-r--r--src/test/ui/associated-types/issue-65774-1.stderr2
-rw-r--r--src/test/ui/associated-types/issue-65774-2.stderr2
-rw-r--r--src/test/ui/async-await/async-block-control-flow-static-semantics.stderr4
-rw-r--r--src/test/ui/async-await/issue-86507.stderr2
-rw-r--r--src/test/ui/binop/binop-move-semantics.stderr16
-rw-r--r--src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr2
-rw-r--r--src/test/ui/borrowck/issue-85765.rs6
-rw-r--r--src/test/ui/borrowck/issue-85765.stderr6
-rw-r--r--src/test/ui/borrowck/issue-91206.rs3
-rw-r--r--src/test/ui/borrowck/issue-91206.stderr2
-rw-r--r--src/test/ui/borrowck/issue-92015.stderr2
-rw-r--r--src/test/ui/borrowck/suggest-as-ref-on-mut-closure.rs16
-rw-r--r--src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr31
-rw-r--r--src/test/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr4
-rw-r--r--src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr4
-rw-r--r--src/test/ui/const-generics/defaults/trait_objects_fail.stderr4
-rw-r--r--src/test/ui/custom_test_frameworks/mismatch.stderr2
-rw-r--r--src/test/ui/dst/dst-bad-coerce1.stderr4
-rw-r--r--src/test/ui/dst/dst-object-from-unsized-type.stderr8
-rw-r--r--src/test/ui/error-codes/E0057.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-79422.extended.stderr2
-rw-r--r--src/test/ui/intrinsics/auxiliary/cci_intrinsic.rs6
-rw-r--r--src/test/ui/intrinsics/intrinsic-atomics-cc.rs4
-rw-r--r--src/test/ui/intrinsics/intrinsic-atomics.rs76
-rw-r--r--src/test/ui/intrinsics/non-integer-atomic.rs56
-rw-r--r--src/test/ui/intrinsics/non-integer-atomic.stderr96
-rw-r--r--src/test/ui/issues/issue-14366.stderr2
-rw-r--r--src/test/ui/issues/issue-22034.stderr2
-rw-r--r--src/test/ui/issues/issue-22872.stderr2
-rw-r--r--src/test/ui/issues/issue-26094.rs2
-rw-r--r--src/test/ui/issues/issue-26094.stderr2
-rw-r--r--src/test/ui/issues/issue-4935.stderr2
-rw-r--r--src/test/ui/issues/issue-51515.rs2
-rw-r--r--src/test/ui/issues/issue-51515.stderr5
-rw-r--r--src/test/ui/issues/issue-7013.stderr2
-rw-r--r--src/test/ui/kindck/kindck-impl-type-params.stderr12
-rw-r--r--src/test/ui/methods/method-call-err-msg.stderr2
-rw-r--r--src/test/ui/mismatched_types/cast-rfc0401.stderr4
-rw-r--r--src/test/ui/mismatched_types/overloaded-calls-bad.stderr2
-rw-r--r--src/test/ui/never_type/fallback-closure-wrap.fallback.stderr2
-rw-r--r--src/test/ui/span/issue-34264.stderr4
-rw-r--r--src/test/ui/specialization/min_specialization/issue-79224.rs24
-rw-r--r--src/test/ui/specialization/min_specialization/issue-79224.stderr29
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple-errors.stderr4
-rw-r--r--src/test/ui/suggestions/derive-macro-missing-bounds.stderr8
-rw-r--r--src/test/ui/suggestions/option-content-move.stderr26
-rw-r--r--src/test/ui/suggestions/suggest-borrow-to-dyn-object.rs16
-rw-r--r--src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr19
-rw-r--r--src/test/ui/traits/coercion-generic-bad.stderr2
-rw-r--r--src/test/ui/traits/map-types.stderr2
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr2
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr4
-rw-r--r--src/test/ui/tuple/wrong_argument_ice-3.stderr2
-rw-r--r--src/test/ui/tuple/wrong_argument_ice-4.stderr2
-rw-r--r--src/test/ui/type/type-ascription-instead-of-initializer.stderr2
-rw-r--r--src/test/ui/typeck/remove-extra-argument.stderr2
-rw-r--r--src/test/ui/typeck/struct-enum-wrong-args.stderr10
-rw-r--r--src/test/ui/unop-move-semantics.stderr16
-rw-r--r--src/test/ui/unsized/unsized-fn-param.stderr8
85 files changed, 1785 insertions, 1246 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index eb5e61fa064..becb81b2e26 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -4,7 +4,7 @@ use rustc_middle::ty;
 use rustc_mir_dataflow::move_paths::{
     IllegalMoveOrigin, IllegalMoveOriginKind, LookupResult, MoveError, MovePathIndex,
 };
-use rustc_span::{sym, Span};
+use rustc_span::Span;
 
 use crate::diagnostics::UseSpans;
 use crate::prefixes::PrefixSet;
@@ -218,29 +218,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
     fn report(&mut self, error: GroupedMoveError<'tcx>) {
         let (mut err, err_span) = {
-            let (span, use_spans, original_path, kind, has_complex_bindings): (
-                Span,
-                Option<UseSpans<'tcx>>,
-                Place<'tcx>,
-                &IllegalMoveOriginKind<'_>,
-                bool,
-            ) = match error {
-                GroupedMoveError::MovesFromPlace {
-                    span,
-                    original_path,
-                    ref kind,
-                    ref binds_to,
-                    ..
+            let (span, use_spans, original_path, kind) = match error {
+                GroupedMoveError::MovesFromPlace { span, original_path, ref kind, .. }
+                | GroupedMoveError::MovesFromValue { span, original_path, ref kind, .. } => {
+                    (span, None, original_path, kind)
                 }
-                | GroupedMoveError::MovesFromValue {
-                    span,
-                    original_path,
-                    ref kind,
-                    ref binds_to,
-                    ..
-                } => (span, None, original_path, kind, !binds_to.is_empty()),
                 GroupedMoveError::OtherIllegalMove { use_spans, original_path, ref kind } => {
-                    (use_spans.args_or_use(), Some(use_spans), original_path, kind, false)
+                    (use_spans.args_or_use(), Some(use_spans), original_path, kind)
                 }
             };
             debug!(
@@ -259,7 +243,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                             target_place,
                             span,
                             use_spans,
-                            has_complex_bindings,
                         ),
                     &IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
                         self.cannot_move_out_of_interior_of_drop(span, ty)
@@ -302,7 +285,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         deref_target_place: Place<'tcx>,
         span: Span,
         use_spans: Option<UseSpans<'tcx>>,
-        has_complex_bindings: bool,
     ) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
         // Inspect the type of the content behind the
         // borrow to provide feedback about why this
@@ -399,28 +381,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 }
             }
         };
-        let ty = move_place.ty(self.body, self.infcx.tcx).ty;
-        let def_id = match *ty.kind() {
-            ty::Adt(self_def, _) => self_def.did(),
-            ty::Foreign(def_id)
-            | ty::FnDef(def_id, _)
-            | ty::Closure(def_id, _)
-            | ty::Generator(def_id, ..)
-            | ty::Opaque(def_id, _) => def_id,
-            _ => return err,
-        };
-        let diag_name = self.infcx.tcx.get_diagnostic_name(def_id);
-        if matches!(diag_name, Some(sym::Option | sym::Result))
-            && use_spans.map_or(true, |v| !v.for_closure())
-            && !has_complex_bindings
-        {
-            err.span_suggestion_verbose(
-                span.shrink_to_hi(),
-                &format!("consider borrowing the `{}`'s content", diag_name.unwrap()),
-                ".as_ref()",
-                Applicability::MaybeIncorrect,
-            );
-        } else if let Some(use_spans) = use_spans {
+        if let Some(use_spans) = use_spans {
             self.explain_captures(
                 &mut err, span, span, use_spans, move_place, None, "", "", "", false, true,
             );
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 861c5e973f1..49b24a05071 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -434,8 +434,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
                 match self.local_names[local] {
                     Some(name) if !local_decl.from_compiler_desugaring() => {
-                        let label = match local_decl.local_info.as_ref().unwrap() {
-                            box LocalInfo::User(ClearCrossCrate::Set(
+                        let label = match local_decl.local_info.as_deref().unwrap() {
+                            LocalInfo::User(ClearCrossCrate::Set(
                                 mir::BindingForm::ImplicitSelf(_),
                             )) => {
                                 let (span, suggestion) =
@@ -443,7 +443,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                                 Some((true, span, suggestion))
                             }
 
-                            box LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var(
+                            LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var(
                                 mir::VarBindingForm {
                                     binding_mode: ty::BindingMode::BindByValue(_),
                                     opt_ty_info,
@@ -473,20 +473,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                                     // on for loops, RHS points to the iterator part
                                     Some(DesugaringKind::ForLoop) => {
                                         self.suggest_similar_mut_method_for_for_loop(&mut err);
-                                        Some((
-                                            false,
-                                            opt_assignment_rhs_span.unwrap(),
-                                            format!(
-                                                "this iterator yields `{SIGIL}` {DESC}s",
-                                                SIGIL = pointer_sigil,
-                                                DESC = pointer_desc
-                                            ),
-                                        ))
+                                        err.span_label(opt_assignment_rhs_span.unwrap(), format!(
+                                            "this iterator yields `{pointer_sigil}` {pointer_desc}s",
+                                        ));
+                                        None
                                     }
                                     // don't create labels for compiler-generated spans
                                     Some(_) => None,
                                     None => {
-                                        let (span, suggestion) = if name != kw::SelfLower {
+                                        let label = if name != kw::SelfLower {
                                             suggest_ampmut(
                                                 self.infcx.tcx,
                                                 local_decl,
@@ -501,7 +496,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                                                         ..
                                                     }),
                                                 ))) => {
-                                                    suggest_ampmut_self(self.infcx.tcx, local_decl)
+                                                    let (span, sugg) = suggest_ampmut_self(
+                                                        self.infcx.tcx,
+                                                        local_decl,
+                                                    );
+                                                    (true, span, sugg)
                                                 }
                                                 // explicit self (eg `self: &'a Self`)
                                                 _ => suggest_ampmut(
@@ -512,12 +511,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                                                 ),
                                             }
                                         };
-                                        Some((true, span, suggestion))
+                                        Some(label)
                                     }
                                 }
                             }
 
-                            box LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var(
+                            LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var(
                                 mir::VarBindingForm {
                                     binding_mode: ty::BindingMode::BindByReference(_),
                                     ..
@@ -528,7 +527,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                                     .map(|replacement| (true, pattern_span, replacement))
                             }
 
-                            box LocalInfo::User(ClearCrossCrate::Clear) => {
+                            LocalInfo::User(ClearCrossCrate::Clear) => {
                                 bug!("saw cleared local state")
                             }
 
@@ -559,7 +558,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                                 }
                             }
                             Some((false, err_label_span, message)) => {
-                                err.span_label(err_label_span, &message);
+                                err.span_label(
+                                    err_label_span,
+                                    &format!(
+                                        "consider changing this binding's type to be: `{message}`"
+                                    ),
+                                );
                             }
                             None => {}
                         }
@@ -1004,7 +1008,7 @@ fn suggest_ampmut<'tcx>(
     local_decl: &mir::LocalDecl<'tcx>,
     opt_assignment_rhs_span: Option<Span>,
     opt_ty_info: Option<Span>,
-) -> (Span, String) {
+) -> (bool, Span, String) {
     if let Some(assignment_rhs_span) = opt_assignment_rhs_span
         && let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span)
     {
@@ -1028,24 +1032,24 @@ fn suggest_ampmut<'tcx>(
             let lt_name = &src[1..ws_pos];
             let ty = src[ws_pos..].trim_start();
             if !is_mutbl(ty) {
-                return (assignment_rhs_span, format!("&{lt_name} mut {ty}"));
+                return (true, assignment_rhs_span, format!("&{lt_name} mut {ty}"));
             }
         } else if let Some(stripped) = src.strip_prefix('&') {
             let stripped = stripped.trim_start();
             if !is_mutbl(stripped) {
-                return (assignment_rhs_span, format!("&mut {stripped}"));
+                return (true, assignment_rhs_span, format!("&mut {stripped}"));
             }
         }
     }
 
-    let highlight_span = match opt_ty_info {
+    let (suggestability, highlight_span) = match opt_ty_info {
         // if this is a variable binding with an explicit type,
         // try to highlight that for the suggestion.
-        Some(ty_span) => ty_span,
+        Some(ty_span) => (true, ty_span),
 
         // otherwise, just highlight the span associated with
         // the (MIR) LocalDecl.
-        None => local_decl.source_info.span,
+        None => (false, local_decl.source_info.span),
     };
 
     if let Ok(src) = tcx.sess.source_map().span_to_snippet(highlight_span)
@@ -1053,12 +1057,13 @@ fn suggest_ampmut<'tcx>(
     {
         let lt_name = &src[1..ws_pos];
         let ty = &src[ws_pos..];
-        return (highlight_span, format!("&{} mut{}", lt_name, ty));
+        return (true, highlight_span, format!("&{} mut{}", lt_name, ty));
     }
 
     let ty_mut = local_decl.ty.builtin_deref(true).unwrap();
     assert_eq!(ty_mut.mutbl, hir::Mutability::Not);
     (
+        suggestability,
         highlight_span,
         if local_decl.ty.is_region_ptr() {
             format!("&mut {}", ty_mut.ty)
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 6c30923bc3d..4be3ae11e4e 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -6,6 +6,7 @@
 #![feature(associated_type_bounds)]
 #![feature(strict_provenance)]
 #![feature(int_roundings)]
+#![feature(if_let_guard)]
 #![recursion_limit = "256"]
 #![allow(rustc::potential_query_instability)]
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index 0ed4c3f1d94..7f14b95317b 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -376,32 +376,23 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             }
 
             // This requires that atomic intrinsics follow a specific naming pattern:
-            // "atomic_<operation>[_<ordering>]", and no ordering means SeqCst
-            name if name_str.starts_with("atomic_") => {
+            // "atomic_<operation>[_<ordering>]"
+            name if let Some(atomic) = name_str.strip_prefix("atomic_") => {
                 use crate::common::AtomicOrdering::*;
                 use crate::common::{AtomicRmwBinOp, SynchronizationScope};
 
-                let split: Vec<_> = name_str.split('_').collect();
-
-                let is_cxchg = split[1] == "cxchg" || split[1] == "cxchgweak";
-                let (order, failorder) = match split.len() {
-                    2 => (SequentiallyConsistent, SequentiallyConsistent),
-                    3 => match split[2] {
-                        "unordered" => (Unordered, Unordered),
-                        "relaxed" => (Relaxed, Relaxed),
-                        "acq" => (Acquire, Acquire),
-                        "rel" => (Release, Relaxed),
-                        "acqrel" => (AcquireRelease, Acquire),
-                        "failrelaxed" if is_cxchg => (SequentiallyConsistent, Relaxed),
-                        "failacq" if is_cxchg => (SequentiallyConsistent, Acquire),
-                        _ => bx.sess().fatal("unknown ordering in atomic intrinsic"),
-                    },
-                    4 => match (split[2], split[3]) {
-                        ("acq", "failrelaxed") if is_cxchg => (Acquire, Relaxed),
-                        ("acqrel", "failrelaxed") if is_cxchg => (AcquireRelease, Relaxed),
-                        _ => bx.sess().fatal("unknown ordering in atomic intrinsic"),
-                    },
-                    _ => bx.sess().fatal("Atomic intrinsic not in correct format"),
+                let Some((instruction, ordering)) = atomic.split_once('_') else {
+                    bx.sess().fatal("Atomic intrinsic missing memory ordering");
+                };
+
+                let parse_ordering = |bx: &Bx, s| match s {
+                    "unordered" => Unordered,
+                    "relaxed" => Relaxed,
+                    "acquire" => Acquire,
+                    "release" => Release,
+                    "acqrel" => AcquireRelease,
+                    "seqcst" => SequentiallyConsistent,
+                    _ => bx.sess().fatal("unknown ordering in atomic intrinsic"),
                 };
 
                 let invalid_monomorphization = |ty| {
@@ -416,11 +407,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     );
                 };
 
-                match split[1] {
+                match instruction {
                     "cxchg" | "cxchgweak" => {
+                        let Some((success, failure)) = ordering.split_once('_') else {
+                            bx.sess().fatal("Atomic compare-exchange intrinsic missing failure memory ordering");
+                        };
                         let ty = substs.type_at(0);
                         if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
-                            let weak = split[1] == "cxchgweak";
+                            let weak = instruction == "cxchgweak";
                             let mut dst = args[0].immediate();
                             let mut cmp = args[1].immediate();
                             let mut src = args[2].immediate();
@@ -432,7 +426,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                 cmp = bx.ptrtoint(cmp, bx.type_isize());
                                 src = bx.ptrtoint(src, bx.type_isize());
                             }
-                            let pair = bx.atomic_cmpxchg(dst, cmp, src, order, failorder, weak);
+                            let pair = bx.atomic_cmpxchg(dst, cmp, src, parse_ordering(bx, success), parse_ordering(bx, failure), weak);
                             let val = bx.extract_value(pair, 0);
                             let success = bx.extract_value(pair, 1);
                             let val = bx.from_immediate(val);
@@ -460,11 +454,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                 let llty = bx.type_isize();
                                 let ptr_llty = bx.type_ptr_to(llty);
                                 source = bx.pointercast(source, ptr_llty);
-                                let result = bx.atomic_load(llty, source, order, size);
+                                let result = bx.atomic_load(llty, source, parse_ordering(bx, ordering), size);
                                 // ... and then cast the result back to a pointer
                                 bx.inttoptr(result, bx.backend_type(layout))
                             } else {
-                                bx.atomic_load(bx.backend_type(layout), source, order, size)
+                                bx.atomic_load(bx.backend_type(layout), source, parse_ordering(bx, ordering), size)
                             }
                         } else {
                             return invalid_monomorphization(ty);
@@ -484,7 +478,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                 ptr = bx.pointercast(ptr, ptr_llty);
                                 val = bx.ptrtoint(val, bx.type_isize());
                             }
-                            bx.atomic_store(val, ptr, order, size);
+                            bx.atomic_store(val, ptr, parse_ordering(bx, ordering), size);
                             return;
                         } else {
                             return invalid_monomorphization(ty);
@@ -492,12 +486,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     }
 
                     "fence" => {
-                        bx.atomic_fence(order, SynchronizationScope::CrossThread);
+                        bx.atomic_fence(parse_ordering(bx, ordering), SynchronizationScope::CrossThread);
                         return;
                     }
 
                     "singlethreadfence" => {
-                        bx.atomic_fence(order, SynchronizationScope::SingleThread);
+                        bx.atomic_fence(parse_ordering(bx, ordering), SynchronizationScope::SingleThread);
                         return;
                     }
 
@@ -531,7 +525,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                 ptr = bx.pointercast(ptr, ptr_llty);
                                 val = bx.ptrtoint(val, bx.type_isize());
                             }
-                            bx.atomic_rmw(atom_op, ptr, val, order)
+                            bx.atomic_rmw(atom_op, ptr, val, parse_ordering(bx, ordering))
                         } else {
                             return invalid_monomorphization(ty);
                         }
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index 3eeb0138b37..eb81f43c3fe 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -82,12 +82,12 @@ impl<'tcx> ConstEvalErr<'tcx> {
         'tcx: 'mir,
     {
         error.print_backtrace();
-        let stacktrace = ecx.generate_stacktrace();
-        ConstEvalErr {
-            error: error.into_kind(),
-            stacktrace,
-            span: span.unwrap_or_else(|| ecx.cur_span()),
-        }
+        let mut stacktrace = ecx.generate_stacktrace();
+        // Filter out `requires_caller_location` frames.
+        stacktrace.retain(|frame| !frame.instance.def.requires_caller_location(*ecx.tcx));
+        // If `span` is missing, use topmost remaining frame, or else the "root" span from `ecx.tcx`.
+        let span = span.or_else(|| stacktrace.first().map(|f| f.span)).unwrap_or(ecx.tcx.span);
+        ConstEvalErr { error: error.into_kind(), stacktrace, span }
     }
 
     pub fn struct_error(
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index b7e5e7aea49..09a2977af04 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -337,7 +337,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
                     }
                 };
 
-                Err(err.report_as_error(ecx.tcx.at(ecx.cur_span()), &msg))
+                Err(err.report_as_error(ecx.tcx.at(err.span), &msg))
             } else {
                 let hir_id = tcx.hir().local_def_id_to_hir_id(def.as_local().unwrap().did);
                 Err(err.report_as_lint(
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 1c1bbd370bd..66c73624501 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -428,11 +428,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
     #[inline(always)]
     pub fn cur_span(&self) -> Span {
-        self.stack()
-            .iter()
-            .rev()
-            .find(|frame| !frame.instance.def.requires_caller_location(*self.tcx))
-            .map_or(self.tcx.span, |f| f.current_span())
+        // This deliberately does *not* honor `requires_caller_location` since it is used for much
+        // more than just panics.
+        self.stack().last().map_or(self.tcx.span, |f| f.current_span())
     }
 
     #[inline(always)]
@@ -939,12 +937,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     #[must_use]
     pub fn generate_stacktrace(&self) -> Vec<FrameInfo<'tcx>> {
         let mut frames = Vec::new();
-        for frame in self
-            .stack()
-            .iter()
-            .rev()
-            .skip_while(|frame| frame.instance.def.requires_caller_location(*self.tcx))
-        {
+        // This deliberately does *not* honor `requires_caller_location` since it is used for much
+        // more than just panics.
+        for frame in self.stack().iter().rev() {
             let lint_root = frame.current_source_info().and_then(|source_info| {
                 match &frame.body.source_scopes[source_info.scope].local_data {
                     mir::ClearCrossCrate::Set(data) => Some(data.lint_root),
diff --git a/compiler/rustc_error_codes/src/error_codes/E0093.md b/compiler/rustc_error_codes/src/error_codes/E0093.md
index 6d58e50ec88..b1683cf4fc4 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0093.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0093.md
@@ -24,12 +24,12 @@ functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in
 #![feature(intrinsics)]
 
 extern "rust-intrinsic" {
-    fn atomic_fence(); // ok!
+    fn atomic_fence_seqcst(); // ok!
 }
 
 fn main() {
     unsafe {
-        atomic_fence();
+        atomic_fence_seqcst();
     }
 }
 ```
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index c1ded99a25a..3280fd5c310 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -42,7 +42,7 @@ use std::io;
 use std::iter::TrustedLen;
 use std::mem;
 use std::num::NonZeroUsize;
-use std::path::Path;
+use std::path::PathBuf;
 use tracing::debug;
 
 pub(super) use cstore_impl::provide;
@@ -1473,20 +1473,26 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         //
         // NOTE: if you update this, you might need to also update bootstrap's code for generating
         // the `rust-src` component in `Src::run` in `src/bootstrap/dist.rs`.
-        let virtual_rust_source_base_dir = option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR")
-            .map(Path::new)
-            .filter(|_| {
-                // Only spend time on further checks if we have what to translate *to*.
-                sess.opts.real_rust_source_base_dir.is_some()
-                    // Some tests need the translation to be always skipped.
-                    && sess.opts.debugging_opts.translate_remapped_path_to_local_path
-            })
-            .filter(|virtual_dir| {
-                // Don't translate away `/rustc/$hash` if we're still remapping to it,
-                // since that means we're still building `std`/`rustc` that need it,
-                // and we don't want the real path to leak into codegen/debuginfo.
-                !sess.opts.remap_path_prefix.iter().any(|(_from, to)| to == virtual_dir)
-            });
+        let virtual_rust_source_base_dir = [
+            option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from),
+            sess.opts.debugging_opts.simulate_remapped_rust_src_base.clone(),
+        ]
+        .into_iter()
+        .filter(|_| {
+            // Only spend time on further checks if we have what to translate *to*.
+            sess.opts.real_rust_source_base_dir.is_some()
+                // Some tests need the translation to be always skipped.
+                && sess.opts.debugging_opts.translate_remapped_path_to_local_path
+        })
+        .flatten()
+        .filter(|virtual_dir| {
+            // Don't translate away `/rustc/$hash` if we're still remapping to it,
+            // since that means we're still building `std`/`rustc` that need it,
+            // and we don't want the real path to leak into codegen/debuginfo.
+            !sess.opts.remap_path_prefix.iter().any(|(_from, to)| to == virtual_dir)
+        })
+        .collect::<Vec<_>>();
+
         let try_to_translate_virtual_to_real = |name: &mut rustc_span::FileName| {
             debug!(
                 "try_to_translate_virtual_to_real(name={:?}): \
@@ -1494,7 +1500,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                 name, virtual_rust_source_base_dir, sess.opts.real_rust_source_base_dir,
             );
 
-            if let Some(virtual_dir) = virtual_rust_source_base_dir {
+            for virtual_dir in &virtual_rust_source_base_dir {
                 if let Some(real_dir) = &sess.opts.real_rust_source_base_dir {
                     if let rustc_span::FileName::Real(old_name) = name {
                         if let rustc_span::RealFileName::Remapped { local_path: _, virtual_name } =
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index ed8de24a65e..7f913faf860 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -253,7 +253,7 @@ pub enum ObligationCauseCode<'tcx> {
     ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>),
 
     /// Obligation incurred due to an object cast.
-    ObjectCastObligation(/* Object type */ Ty<'tcx>),
+    ObjectCastObligation(/* Concrete type */ Ty<'tcx>, /* Object type */ Ty<'tcx>),
 
     /// Obligation incurred due to a coercion.
     Coercion {
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index e2399818929..cdacf3ad892 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -162,7 +162,11 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
                 let opt_ty_info;
                 let self_arg;
                 if let Some(ref fn_decl) = tcx.hir().fn_decl_by_hir_id(owner_id) {
-                    opt_ty_info = fn_decl.inputs.get(index).map(|ty| ty.span);
+                    opt_ty_info = fn_decl
+                        .inputs
+                        .get(index)
+                        // Make sure that inferred closure args have no type span
+                        .and_then(|ty| if arg.pat.span != ty.span { Some(ty.span) } else { None });
                     self_arg = if index == 0 && fn_decl.implicit_self.has_implicit_self() {
                         match fn_decl.implicit_self {
                             hir::ImplicitSelfKind::Imm => Some(ImplicitSelfKind::Imm),
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index af0803fbd54..debb9e82951 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -484,10 +484,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                             err.span_label(span, explanation);
                         }
 
-                        if let ObligationCauseCode::ObjectCastObligation(obj_ty) = obligation.cause.code().peel_derives() &&
-                           let Some(self_ty) = trait_predicate.self_ty().no_bound_vars() &&
+                        if let ObligationCauseCode::ObjectCastObligation(concrete_ty, obj_ty) = obligation.cause.code().peel_derives() &&
                            Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
-                            self.suggest_borrowing_for_object_cast(&mut err, &obligation, self_ty, *obj_ty);
+                            self.suggest_borrowing_for_object_cast(&mut err, &root_obligation, *concrete_ty, *obj_ty);
                         }
 
                         if trait_predicate.is_const_if_const() && obligation.param_env.is_const() {
@@ -1560,7 +1559,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                     obligation.cause.code().peel_derives(),
                     ObligationCauseCode::ItemObligation(_)
                         | ObligationCauseCode::BindingObligation(_, _)
-                        | ObligationCauseCode::ObjectCastObligation(_)
+                        | ObligationCauseCode::ObjectCastObligation(..)
                         | ObligationCauseCode::OpaqueType
                 );
                 if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp(
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index fbe66d7dcdd..12858172ee5 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2217,9 +2217,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     err.span_note(tcx.def_span(item_def_id), &descr);
                 }
             }
-            ObligationCauseCode::ObjectCastObligation(object_ty) => {
+            ObligationCauseCode::ObjectCastObligation(concrete_ty, object_ty) => {
                 err.note(&format!(
-                    "required for the cast to the object type `{}`",
+                    "required for the cast from `{}` to the object type `{}`",
+                    self.ty_to_string(concrete_ty),
                     self.ty_to_string(object_ty)
                 ));
             }
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 5942bb79d69..e1131140c39 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -813,7 +813,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 let cause = ObligationCause::new(
                     obligation.cause.span,
                     obligation.cause.body_id,
-                    ObjectCastObligation(target),
+                    ObjectCastObligation(source, target),
                 );
                 let outlives = ty::OutlivesPredicate(r_a, r_b);
                 nested.push(Obligation::with_depth(
@@ -910,7 +910,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 let cause = ObligationCause::new(
                     obligation.cause.span,
                     obligation.cause.body_id,
-                    ObjectCastObligation(target),
+                    ObjectCastObligation(source, target),
                 );
                 let outlives = ty::OutlivesPredicate(r_a, r_b);
                 nested.push(Obligation::with_depth(
@@ -931,7 +931,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 let cause = ObligationCause::new(
                     obligation.cause.span,
                     obligation.cause.body_id,
-                    ObjectCastObligation(target),
+                    ObjectCastObligation(source, target),
                 );
 
                 let predicate_to_obligation = |predicate| {
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs b/compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs
index b7ba9d97878..7602f2550e8 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs
@@ -1,7 +1,26 @@
 use std::cmp;
 
+use rustc_index::vec::IndexVec;
 use rustc_middle::ty::error::TypeError;
 
+rustc_index::newtype_index! {
+    pub(crate) struct ExpectedIdx {
+        DEBUG_FORMAT = "ExpectedIdx({})",
+    }
+}
+
+rustc_index::newtype_index! {
+    pub(crate) struct ProvidedIdx {
+        DEBUG_FORMAT = "ProvidedIdx({})",
+    }
+}
+
+impl ExpectedIdx {
+    pub fn to_provided_idx(self) -> ProvidedIdx {
+        ProvidedIdx::from_usize(self.as_usize())
+    }
+}
+
 // An issue that might be found in the compatibility matrix
 #[derive(Debug)]
 enum Issue {
@@ -27,24 +46,24 @@ pub(crate) enum Compatibility<'tcx> {
 #[derive(Debug)]
 pub(crate) enum Error<'tcx> {
     /// The provided argument is the invalid type for the expected input
-    Invalid(usize, usize, Compatibility<'tcx>), // provided, expected
+    Invalid(ProvidedIdx, ExpectedIdx, Compatibility<'tcx>),
     /// There is a missing input
-    Missing(usize),
+    Missing(ExpectedIdx),
     /// There's a superfluous argument
-    Extra(usize),
+    Extra(ProvidedIdx),
     /// Two arguments should be swapped
-    Swap(usize, usize, usize, usize),
+    Swap(ProvidedIdx, ProvidedIdx, ExpectedIdx, ExpectedIdx),
     /// Several arguments should be reordered
-    Permutation(Vec<(usize, usize)>), // dest_arg, dest_input
+    Permutation(Vec<(ExpectedIdx, ProvidedIdx)>),
 }
 
 pub(crate) struct ArgMatrix<'tcx> {
     /// Maps the indices in the `compatibility_matrix` rows to the indices of
     /// the *user provided* inputs
-    input_indexes: Vec<usize>,
+    provided_indices: Vec<ProvidedIdx>,
     /// Maps the indices in the `compatibility_matrix` columns to the indices
     /// of the *expected* args
-    arg_indexes: Vec<usize>,
+    expected_indices: Vec<ExpectedIdx>,
     /// The first dimension (rows) are the remaining user provided inputs to
     /// match and the second dimension (cols) are the remaining expected args
     /// to match
@@ -52,62 +71,64 @@ pub(crate) struct ArgMatrix<'tcx> {
 }
 
 impl<'tcx> ArgMatrix<'tcx> {
-    pub(crate) fn new<F: FnMut(usize, usize) -> Compatibility<'tcx>>(
-        minimum_input_count: usize,
-        provided_arg_count: usize,
+    pub(crate) fn new<F: FnMut(ProvidedIdx, ExpectedIdx) -> Compatibility<'tcx>>(
+        provided_count: usize,
+        expected_input_count: usize,
         mut is_compatible: F,
     ) -> Self {
-        let compatibility_matrix = (0..provided_arg_count)
-            .map(|i| (0..minimum_input_count).map(|j| is_compatible(i, j)).collect())
+        let compatibility_matrix = (0..provided_count)
+            .map(|i| {
+                (0..expected_input_count)
+                    .map(|j| is_compatible(ProvidedIdx::from_usize(i), ExpectedIdx::from_usize(j)))
+                    .collect()
+            })
             .collect();
         ArgMatrix {
-            input_indexes: (0..provided_arg_count).collect(),
-            arg_indexes: (0..minimum_input_count).collect(),
+            provided_indices: (0..provided_count).map(ProvidedIdx::from_usize).collect(),
+            expected_indices: (0..expected_input_count).map(ExpectedIdx::from_usize).collect(),
             compatibility_matrix,
         }
     }
 
     /// Remove a given input from consideration
-    fn eliminate_input(&mut self, idx: usize) {
-        self.input_indexes.remove(idx);
+    fn eliminate_provided(&mut self, idx: usize) {
+        self.provided_indices.remove(idx);
         self.compatibility_matrix.remove(idx);
     }
 
     /// Remove a given argument from consideration
-    fn eliminate_arg(&mut self, idx: usize) {
-        self.arg_indexes.remove(idx);
+    fn eliminate_expected(&mut self, idx: usize) {
+        self.expected_indices.remove(idx);
         for row in &mut self.compatibility_matrix {
             row.remove(idx);
         }
     }
 
     /// "satisfy" an input with a given arg, removing both from consideration
-    fn satisfy_input(&mut self, input_idx: usize, arg_idx: usize) {
-        self.eliminate_input(input_idx);
-        self.eliminate_arg(arg_idx);
+    fn satisfy_input(&mut self, provided_idx: usize, expected_idx: usize) {
+        self.eliminate_provided(provided_idx);
+        self.eliminate_expected(expected_idx);
     }
 
     // Returns a `Vec` of (user input, expected arg) of matched arguments. These
     // are inputs on the remaining diagonal that match.
-    fn eliminate_satisfied(&mut self) -> Vec<(usize, usize)> {
-        let mut i = cmp::min(self.input_indexes.len(), self.arg_indexes.len());
+    fn eliminate_satisfied(&mut self) -> Vec<(ProvidedIdx, ExpectedIdx)> {
+        let num_args = cmp::min(self.provided_indices.len(), self.expected_indices.len());
         let mut eliminated = vec![];
-        while i > 0 {
-            let idx = i - 1;
-            if matches!(self.compatibility_matrix[idx][idx], Compatibility::Compatible) {
-                eliminated.push((self.input_indexes[idx], self.arg_indexes[idx]));
-                self.satisfy_input(idx, idx);
+        for i in (0..num_args).rev() {
+            if matches!(self.compatibility_matrix[i][i], Compatibility::Compatible) {
+                eliminated.push((self.provided_indices[i], self.expected_indices[i]));
+                self.satisfy_input(i, i);
             }
-            i -= 1;
         }
-        return eliminated;
+        eliminated
     }
 
     // Find some issue in the compatibility matrix
     fn find_issue(&self) -> Option<Issue> {
         let mat = &self.compatibility_matrix;
-        let ai = &self.arg_indexes;
-        let ii = &self.input_indexes;
+        let ai = &self.expected_indices;
+        let ii = &self.provided_indices;
 
         for i in 0..cmp::max(ai.len(), ii.len()) {
             // If we eliminate the last row, any left-over inputs are considered missing
@@ -264,12 +285,15 @@ impl<'tcx> ArgMatrix<'tcx> {
     //
     // We'll want to know which arguments and inputs these rows and columns correspond to
     // even after we delete them.
-    pub(crate) fn find_errors(mut self) -> (Vec<Error<'tcx>>, Vec<Option<usize>>) {
-        let provided_arg_count = self.input_indexes.len();
+    pub(crate) fn find_errors(
+        mut self,
+    ) -> (Vec<Error<'tcx>>, IndexVec<ExpectedIdx, Option<ProvidedIdx>>) {
+        let provided_arg_count = self.provided_indices.len();
 
         let mut errors: Vec<Error<'tcx>> = vec![];
         // For each expected argument, the matched *actual* input
-        let mut matched_inputs: Vec<Option<usize>> = vec![None; self.arg_indexes.len()];
+        let mut matched_inputs: IndexVec<ExpectedIdx, Option<ProvidedIdx>> =
+            IndexVec::from_elem_n(None, self.expected_indices.len());
 
         // Before we start looking for issues, eliminate any arguments that are already satisfied,
         // so that an argument which is already spoken for by the input it's in doesn't
@@ -280,34 +304,34 @@ impl<'tcx> ArgMatrix<'tcx> {
         // Without this elimination, the first argument causes the second argument
         // to show up as both a missing input and extra argument, rather than
         // just an invalid type.
-        for (inp, arg) in self.eliminate_satisfied() {
-            matched_inputs[arg] = Some(inp);
+        for (provided, expected) in self.eliminate_satisfied() {
+            matched_inputs[expected] = Some(provided);
         }
 
-        while self.input_indexes.len() > 0 || self.arg_indexes.len() > 0 {
+        while !self.provided_indices.is_empty() || !self.expected_indices.is_empty() {
             match self.find_issue() {
                 Some(Issue::Invalid(idx)) => {
                     let compatibility = self.compatibility_matrix[idx][idx].clone();
-                    let input_idx = self.input_indexes[idx];
-                    let arg_idx = self.arg_indexes[idx];
+                    let input_idx = self.provided_indices[idx];
+                    let arg_idx = self.expected_indices[idx];
                     self.satisfy_input(idx, idx);
                     errors.push(Error::Invalid(input_idx, arg_idx, compatibility));
                 }
                 Some(Issue::Extra(idx)) => {
-                    let input_idx = self.input_indexes[idx];
-                    self.eliminate_input(idx);
+                    let input_idx = self.provided_indices[idx];
+                    self.eliminate_provided(idx);
                     errors.push(Error::Extra(input_idx));
                 }
                 Some(Issue::Missing(idx)) => {
-                    let arg_idx = self.arg_indexes[idx];
-                    self.eliminate_arg(idx);
+                    let arg_idx = self.expected_indices[idx];
+                    self.eliminate_expected(idx);
                     errors.push(Error::Missing(arg_idx));
                 }
                 Some(Issue::Swap(idx, other)) => {
-                    let input_idx = self.input_indexes[idx];
-                    let other_input_idx = self.input_indexes[other];
-                    let arg_idx = self.arg_indexes[idx];
-                    let other_arg_idx = self.arg_indexes[other];
+                    let input_idx = self.provided_indices[idx];
+                    let other_input_idx = self.provided_indices[other];
+                    let arg_idx = self.expected_indices[idx];
+                    let other_arg_idx = self.expected_indices[other];
                     let (min, max) = (cmp::min(idx, other), cmp::max(idx, other));
                     self.satisfy_input(min, max);
                     // Subtract 1 because we already removed the "min" row
@@ -319,13 +343,14 @@ impl<'tcx> ArgMatrix<'tcx> {
                 Some(Issue::Permutation(args)) => {
                     let mut idxs: Vec<usize> = args.iter().filter_map(|&a| a).collect();
 
-                    let mut real_idxs = vec![None; provided_arg_count];
+                    let mut real_idxs: IndexVec<ProvidedIdx, Option<(ExpectedIdx, ProvidedIdx)>> =
+                        IndexVec::from_elem_n(None, provided_arg_count);
                     for (src, dst) in
                         args.iter().enumerate().filter_map(|(src, dst)| dst.map(|dst| (src, dst)))
                     {
-                        let src_input_idx = self.input_indexes[src];
-                        let dst_input_idx = self.input_indexes[dst];
-                        let dest_arg_idx = self.arg_indexes[dst];
+                        let src_input_idx = self.provided_indices[src];
+                        let dst_input_idx = self.provided_indices[dst];
+                        let dest_arg_idx = self.expected_indices[dst];
                         real_idxs[src_input_idx] = Some((dest_arg_idx, dst_input_idx));
                         matched_inputs[dest_arg_idx] = Some(src_input_idx);
                     }
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
index 2326c4069e4..08df01c0c1a 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
@@ -1,6 +1,8 @@
 use crate::astconv::AstConv;
 use crate::check::coercion::CoerceMany;
-use crate::check::fn_ctxt::arg_matrix::{ArgMatrix, Compatibility, Error};
+use crate::check::fn_ctxt::arg_matrix::{
+    ArgMatrix, Compatibility, Error, ExpectedIdx, ProvidedIdx,
+};
 use crate::check::gather_locals::Declaration;
 use crate::check::method::MethodCallee;
 use crate::check::Expectation::*;
@@ -17,13 +19,14 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{ExprKind, Node, QPath};
+use rustc_index::vec::IndexVec;
 use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
 use rustc_infer::infer::InferOk;
 use rustc_infer::infer::TypeTrace;
 use rustc_middle::ty::adjustment::AllowTwoPhase;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::fold::TypeFoldable;
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt};
 use rustc_session::Session;
 use rustc_span::symbol::Ident;
 use rustc_span::{self, Span};
@@ -214,6 +217,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let provided_arg_count = provided_args.len();
 
         // We'll also want to keep track of the fully coerced argument types, for an awkward hack near the end
+        // FIXME(compiler-errors): Get rid of this, actually.
         let mut final_arg_types: Vec<Option<(Ty<'_>, Ty<'_>)>> = vec![None; provided_arg_count];
 
         // We introduce a helper function to demand that a given argument satisfy a given input
@@ -287,54 +291,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         };
 
-        // A "softer" version of the helper above, which checks types without persisting them,
-        // and treats error types differently
-        // This will allow us to "probe" for other argument orders that would likely have been correct
-        let check_compatible = |input_idx, arg_idx| {
-            let formal_input_ty: Ty<'tcx> = formal_input_tys[arg_idx];
-            let expected_input_ty: Ty<'tcx> = expected_input_tys[arg_idx];
-
-            // If either is an error type, we defy the usual convention and consider them to *not* be
-            // coercible.  This prevents our error message heuristic from trying to pass errors into
-            // every argument.
-            if formal_input_ty.references_error() || expected_input_ty.references_error() {
-                return Compatibility::Incompatible(None);
-            }
-
-            let provided_arg: &hir::Expr<'tcx> = &provided_args[input_idx];
-            let expectation = Expectation::rvalue_hint(self, expected_input_ty);
-            // FIXME: check that this is safe; I don't believe this commits any of the obligations, but I can't be sure.
-            //
-            //   I had another method of "soft" type checking before,
-            //   but it was failing to find the type of some expressions (like "")
-            //   so I prodded this method and made it pub(super) so I could call it, and it seems to work well.
-            let checked_ty = self.check_expr_kind(provided_arg, expectation);
-
-            let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty);
-            let can_coerce = self.can_coerce(checked_ty, coerced_ty);
-
-            if !can_coerce {
-                return Compatibility::Incompatible(None);
-            }
-
-            let subtyping_result = self
-                .at(&self.misc(provided_arg.span), self.param_env)
-                .sup(formal_input_ty, coerced_ty);
-
-            // Same as above: if either the coerce type or the checked type is an error type,
-            // consider them *not* compatible.
-            let coercible =
-                !coerced_ty.references_error() && !checked_ty.references_error() && can_coerce;
-
-            match (coercible, &subtyping_result) {
-                (true, Ok(_)) => Compatibility::Compatible,
-                _ => Compatibility::Incompatible(subtyping_result.err()),
-            }
-        };
-
         // To start, we only care "along the diagonal", where we expect every
         // provided arg to be in the right spot
-        let mut compatibility = vec![Compatibility::Incompatible(None); provided_args.len()];
+        let mut compatibility_diagonal =
+            vec![Compatibility::Incompatible(None); provided_args.len()];
 
         // Keep track of whether we *could possibly* be satisfied, i.e. whether we're on the happy path
         // if the wrong number of arguments were supplied, we CAN'T be satisfied,
@@ -394,7 +354,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 let compatible = demand_compatible(idx, &mut final_arg_types);
                 let is_compatible = matches!(compatible, Compatibility::Compatible);
-                compatibility[idx] = compatible;
+                compatibility_diagonal[idx] = compatible;
 
                 if !is_compatible {
                     call_appears_satisfied = false;
@@ -402,70 +362,54 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        // Logic here is a bit hairy
-        'errors: {
-            // If something above didn't typecheck, we've fallen off the happy path
-            // and we should make some effort to provide better error messages
-            if call_appears_satisfied {
-                break 'errors;
-            }
-
-            self.set_tainted_by_errors();
+        if c_variadic && provided_arg_count < minimum_input_count {
+            err_code = "E0060";
+        }
 
-            // The algorithm here is inspired by levenshtein distance and longest common subsequence.
-            // We'll try to detect 4 different types of mistakes:
-            // - An extra parameter has been provided that doesn't satisfy *any* of the other inputs
-            // - An input is missing, which isn't satisfied by *any* of the other arguments
-            // - Some number of arguments have been provided in the wrong order
-            // - A type is straight up invalid
+        for arg in provided_args.iter().skip(minimum_input_count) {
+            // Make sure we've checked this expr at least once.
+            let arg_ty = self.check_expr(&arg);
 
-            // First, let's find the errors
-            let mut compatibility: Vec<_> = compatibility.into_iter().map(Some).collect();
-            let (mut errors, matched_inputs) =
-                ArgMatrix::new(minimum_input_count, provided_arg_count, |i, j| {
-                    if i == j { compatibility[i].take().unwrap() } else { check_compatible(i, j) }
-                })
-                .find_errors();
+            // If the function is c-style variadic, we skipped a bunch of arguments
+            // so we need to check those, and write out the types
+            // Ideally this would be folded into the above, for uniform style
+            // but c-variadic is already a corner case
+            if c_variadic {
+                fn variadic_error<'tcx>(
+                    sess: &'tcx Session,
+                    span: Span,
+                    ty: Ty<'tcx>,
+                    cast_ty: &str,
+                ) {
+                    use crate::structured_errors::MissingCastForVariadicArg;
 
-            // Okay, so here's where it gets complicated in regards to what errors
-            // we emit and how.
-            // There are 3 different "types" of errors we might encounter.
-            //   1) Missing/extra/swapped arguments
-            //   2) Valid but incorrect arguments
-            //   3) Invalid arguments
-            //      - Currently I think this only comes up with `CyclicTy`
-            //
-            // We first need to go through, remove those from (3) and emit those
-            // as their own error, particularly since they're error code and
-            // message is special. From what I can tell, we *must* emit these
-            // here (vs somewhere prior to this function) since the arguments
-            // become invalid *because* of how they get used in the function.
-            // It is what it is.
-
-            let found_errors = !errors.is_empty();
-
-            errors.drain_filter(|error| {
-                let Error::Invalid(input_idx, arg_idx, Compatibility::Incompatible(Some(e))) = error else { return false };
-                let expected_ty = expected_input_tys[*arg_idx];
-                let provided_ty = final_arg_types[*input_idx].map(|ty| ty.0).unwrap_or_else(|| tcx.ty_error());
-                let cause = &self.misc(provided_args[*input_idx].span);
-                let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
-                if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) {
-                    self.report_and_explain_type_error(trace, e).emit();
-                    return true;
+                    MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit();
                 }
-                false
-            });
 
-            // We're done if we found errors, but we already emitted them.
-            // I don't think we *should* be able to enter this bit of code
-            // (`!call_appears_satisfied`) without *also* finding errors, but we
-            // don't want to accidentally not emit an error if there is some
-            // logic bug in the `ArgMatrix` code.
-            if found_errors && errors.is_empty() {
-                break 'errors;
+                // There are a few types which get autopromoted when passed via varargs
+                // in C but we just error out instead and require explicit casts.
+                let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
+                match arg_ty.kind() {
+                    ty::Float(ty::FloatTy::F32) => {
+                        variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
+                    }
+                    ty::Int(ty::IntTy::I8 | ty::IntTy::I16) | ty::Bool => {
+                        variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
+                    }
+                    ty::Uint(ty::UintTy::U8 | ty::UintTy::U16) => {
+                        variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
+                    }
+                    ty::FnDef(..) => {
+                        let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
+                        let ptr_ty = self.resolve_vars_if_possible(ptr_ty);
+                        variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
+                    }
+                    _ => {}
+                }
             }
+        }
 
+        if !call_appears_satisfied {
             // Next, let's construct the error
             let (error_span, full_call_span, ctor_of) = match &call_expr.kind {
                 hir::ExprKind::Call(
@@ -500,524 +444,633 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 Some(CtorOf::Variant) => "enum variant",
                 None => "function",
             };
-            if c_variadic && provided_arg_count < minimum_input_count {
-                err_code = "E0060";
-            }
 
-            // Next special case: The case where we expect a single tuple and
-            // wrapping all the args in parentheses (or adding a comma to
-            // already existing parentheses) will result in a tuple that
-            // satisfies the call.
-            // This isn't super ideal code, because we copy code from elsewhere
-            // and somewhat duplicate this. We also delegate to the general type
-            // mismatch suggestions for the single arg case.
-            let sugg_tuple_wrap_args =
-                self.suggested_tuple_wrap(&expected_input_tys, provided_args);
-            match sugg_tuple_wrap_args {
-                TupleMatchFound::None => {}
-                TupleMatchFound::Single => {
-                    let expected_ty = expected_input_tys[0];
-                    let provided_ty = final_arg_types[0].map(|ty| ty.0).unwrap();
-                    let expected_ty = self.resolve_vars_if_possible(expected_ty);
-                    let provided_ty = self.resolve_vars_if_possible(provided_ty);
-                    let cause = &self.misc(provided_args[0].span);
-                    let compatibility = demand_compatible(0, &mut final_arg_types);
-                    let type_error = match compatibility {
-                        Compatibility::Incompatible(Some(error)) => error,
-                        _ => TypeError::Mismatch,
-                    };
-                    let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
-                    let mut err = self.report_and_explain_type_error(trace, &type_error);
-                    self.emit_coerce_suggestions(
-                        &mut err,
-                        &provided_args[0],
-                        final_arg_types[0].map(|ty| ty.0).unwrap(),
-                        final_arg_types[0].map(|ty| ty.1).unwrap(),
-                        None,
-                        None,
-                    );
-                    err.span_label(
-                        full_call_span,
-                        format!("arguments to this {} are incorrect", call_name),
-                    );
-                    // Call out where the function is defined
-                    label_fn_like(tcx, &mut err, fn_def_id);
-                    err.emit();
-                    break 'errors;
-                }
-                TupleMatchFound::Multiple(start, end) => {
-                    let mut err = tcx.sess.struct_span_err_with_code(
-                        full_call_span,
-                        &format!(
-                            "this {} takes {}{} but {} {} supplied",
-                            call_name,
-                            if c_variadic { "at least " } else { "" },
-                            potentially_plural_count(minimum_input_count, "argument"),
-                            potentially_plural_count(provided_arg_count, "argument"),
-                            if provided_arg_count == 1 { "was" } else { "were" }
-                        ),
-                        DiagnosticId::Error(err_code.to_owned()),
-                    );
-                    // Call out where the function is defined
-                    label_fn_like(tcx, &mut err, fn_def_id);
-                    err.multipart_suggestion(
-                        "use parentheses to construct a tuple",
-                        vec![(start, '('.to_string()), (end, ')'.to_string())],
-                        Applicability::MachineApplicable,
-                    );
-                    err.emit();
-                    break 'errors;
+            let try_tuple_wrap_args = || {
+                // The case where we expect a single tuple and wrapping all the args
+                // in parentheses (or adding a comma to already existing parentheses)
+                // will result in a tuple that satisfies the call.
+                // This isn't super ideal code, because we copy code from elsewhere
+                // and somewhat duplicate this. We also delegate to the general type
+                // mismatch suggestions for the single arg case.
+                match self.suggested_tuple_wrap(&expected_input_tys, provided_args) {
+                    TupleMatchFound::Single => {
+                        let expected_ty = expected_input_tys[0];
+                        let provided_ty = final_arg_types[0].map(|ty| ty.0).unwrap();
+                        let expected_ty = self.resolve_vars_if_possible(expected_ty);
+                        let provided_ty = self.resolve_vars_if_possible(provided_ty);
+                        let cause = &self.misc(provided_args[0].span);
+                        let compatibility = demand_compatible(0, &mut final_arg_types);
+                        let type_error = match compatibility {
+                            Compatibility::Incompatible(Some(error)) => error,
+                            _ => TypeError::Mismatch,
+                        };
+                        let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
+                        let mut err = self.report_and_explain_type_error(trace, &type_error);
+                        self.emit_coerce_suggestions(
+                            &mut err,
+                            &provided_args[0],
+                            final_arg_types[0].map(|ty| ty.0).unwrap(),
+                            final_arg_types[0].map(|ty| ty.1).unwrap(),
+                            None,
+                            None,
+                        );
+                        err.span_label(
+                            full_call_span,
+                            format!("arguments to this {} are incorrect", call_name),
+                        );
+                        // Call out where the function is defined
+                        label_fn_like(tcx, &mut err, fn_def_id);
+                        err.emit();
+                        return true;
+                    }
+                    TupleMatchFound::Multiple(start, end) => {
+                        let mut err = tcx.sess.struct_span_err_with_code(
+                            full_call_span,
+                            &format!(
+                                "this {} takes {}{} but {} {} supplied",
+                                call_name,
+                                if c_variadic { "at least " } else { "" },
+                                potentially_plural_count(minimum_input_count, "argument"),
+                                potentially_plural_count(provided_arg_count, "argument"),
+                                if provided_arg_count == 1 { "was" } else { "were" }
+                            ),
+                            DiagnosticId::Error(err_code.to_owned()),
+                        );
+                        // Call out where the function is defined
+                        label_fn_like(tcx, &mut err, fn_def_id);
+                        err.multipart_suggestion(
+                            "use parentheses to construct a tuple",
+                            vec![(start, '('.to_string()), (end, ')'.to_string())],
+                            Applicability::MachineApplicable,
+                        );
+                        err.emit();
+                        return true;
+                    }
+                    TupleMatchFound::None => {}
                 }
+                false
+            };
+
+            let compatibility_diagonal = IndexVec::from_raw(compatibility_diagonal);
+            let provided_args = IndexVec::from_iter(provided_args.iter().take(if c_variadic {
+                minimum_input_count
+            } else {
+                provided_arg_count
+            }));
+            debug_assert_eq!(
+                formal_input_tys.len(),
+                expected_input_tys.len(),
+                "expected formal_input_tys to be the same size as expected_input_tys"
+            );
+            let formal_and_expected_inputs = IndexVec::from_iter(
+                formal_input_tys
+                    .iter()
+                    .copied()
+                    .zip(expected_input_tys.iter().copied())
+                    .map(|vars| self.resolve_vars_if_possible(vars)),
+            );
+
+            self.report_arg_errors(
+                compatibility_diagonal,
+                formal_and_expected_inputs,
+                provided_args,
+                full_call_span,
+                error_span,
+                args_span,
+                call_name,
+                c_variadic,
+                err_code,
+                fn_def_id,
+                try_tuple_wrap_args,
+            );
+        }
+    }
+
+    fn report_arg_errors(
+        &self,
+        compatibility_diagonal: IndexVec<ProvidedIdx, Compatibility<'tcx>>,
+        formal_and_expected_inputs: IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
+        provided_args: IndexVec<ProvidedIdx, &'tcx hir::Expr<'tcx>>,
+        full_call_span: Span,
+        error_span: Span,
+        args_span: Span,
+        call_name: &str,
+        c_variadic: bool,
+        err_code: &str,
+        fn_def_id: Option<DefId>,
+        try_tuple_wrap_args: impl FnOnce() -> bool,
+    ) {
+        // Don't print if it has error types or is just plain `_`
+        fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
+            tys.into_iter().any(|ty| ty.references_error() || ty.is_ty_var())
+        }
+
+        self.set_tainted_by_errors();
+        let tcx = self.tcx;
+
+        // A "softer" version of the `demand_compatible`, which checks types without persisting them,
+        // and treats error types differently
+        // This will allow us to "probe" for other argument orders that would likely have been correct
+        let check_compatible = |provided_idx: ProvidedIdx, expected_idx: ExpectedIdx| {
+            if provided_idx.as_usize() == expected_idx.as_usize() {
+                return compatibility_diagonal[provided_idx].clone();
+            }
+
+            let (formal_input_ty, expected_input_ty) = formal_and_expected_inputs[expected_idx];
+            // If either is an error type, we defy the usual convention and consider them to *not* be
+            // coercible.  This prevents our error message heuristic from trying to pass errors into
+            // every argument.
+            if (formal_input_ty, expected_input_ty).references_error() {
+                return Compatibility::Incompatible(None);
+            }
+
+            let provided_arg: &hir::Expr<'tcx> = &provided_args[provided_idx];
+            let expectation = Expectation::rvalue_hint(self, expected_input_ty);
+            // FIXME: check that this is safe; I don't believe this commits any of the obligations, but I can't be sure.
+            //
+            //   I had another method of "soft" type checking before,
+            //   but it was failing to find the type of some expressions (like "")
+            //   so I prodded this method and made it pub(super) so I could call it, and it seems to work well.
+            let checked_ty = self.check_expr_kind(provided_arg, expectation);
+
+            let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty);
+            let can_coerce = self.can_coerce(checked_ty, coerced_ty);
+            if !can_coerce {
+                return Compatibility::Incompatible(None);
+            }
+
+            let subtyping_result = self
+                .at(&self.misc(provided_arg.span), self.param_env)
+                .sup(formal_input_ty, coerced_ty);
+
+            // Same as above: if either the coerce type or the checked type is an error type,
+            // consider them *not* compatible.
+            let references_error = (coerced_ty, checked_ty).references_error();
+            match (references_error, &subtyping_result) {
+                (false, Ok(_)) => Compatibility::Compatible,
+                _ => Compatibility::Incompatible(subtyping_result.err()),
             }
+        };
+
+        // The algorithm here is inspired by levenshtein distance and longest common subsequence.
+        // We'll try to detect 4 different types of mistakes:
+        // - An extra parameter has been provided that doesn't satisfy *any* of the other inputs
+        // - An input is missing, which isn't satisfied by *any* of the other arguments
+        // - Some number of arguments have been provided in the wrong order
+        // - A type is straight up invalid
+
+        // First, let's find the errors
+        let (mut errors, matched_inputs) =
+            ArgMatrix::new(provided_args.len(), formal_and_expected_inputs.len(), check_compatible)
+                .find_errors();
+
+        // Precompute the provided types and spans, since that's all we typically need for below
+        let provided_arg_tys: IndexVec<ProvidedIdx, (Ty<'tcx>, Span)> = provided_args
+            .iter()
+            .map(|expr| {
+                let ty = self
+                    .in_progress_typeck_results
+                    .as_ref()
+                    .unwrap()
+                    .borrow()
+                    .expr_ty_adjusted_opt(*expr)
+                    .unwrap_or_else(|| tcx.ty_error());
+                (self.resolve_vars_if_possible(ty), expr.span)
+            })
+            .collect();
+
+        // Okay, so here's where it gets complicated in regards to what errors
+        // we emit and how.
+        // There are 3 different "types" of errors we might encounter.
+        //   1) Missing/extra/swapped arguments
+        //   2) Valid but incorrect arguments
+        //   3) Invalid arguments
+        //      - Currently I think this only comes up with `CyclicTy`
+        //
+        // We first need to go through, remove those from (3) and emit those
+        // as their own error, particularly since they're error code and
+        // message is special. From what I can tell, we *must* emit these
+        // here (vs somewhere prior to this function) since the arguments
+        // become invalid *because* of how they get used in the function.
+        // It is what it is.
+
+        if errors.is_empty() {
+            if cfg!(debug_assertions) {
+                span_bug!(error_span, "expected errors from argument matrix");
+            } else {
+                tcx.sess
+                    .struct_span_err(
+                        error_span,
+                        "argument type mismatch was detected, \
+                        but rustc had trouble determining where",
+                    )
+                    .note(
+                        "we would appreciate a bug report: \
+                        https://github.com/rust-lang/rust-clippy/issues/new",
+                    )
+                    .emit();
+            }
+            return;
+        }
+
+        errors.drain_filter(|error| {
+                let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(error)) = error else { return false };
+                let (provided_ty, provided_span) = provided_arg_tys[*provided_idx];
+                let (expected_ty, _) = formal_and_expected_inputs[*expected_idx];
+                let cause = &self.misc(provided_span);
+                let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
+                if let Some(e) = error {
+                    if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) {
+                        self.report_and_explain_type_error(trace, e).emit();
+                        return true;
+                    }
+                }
+                false
+            });
+
+        // We're done if we found errors, but we already emitted them.
+        if errors.is_empty() {
+            return;
+        }
+
+        // Okay, now that we've emitted the special errors separately, we
+        // are only left missing/extra/swapped and mismatched arguments, both
+        // can be collated pretty easily if needed.
+
+        // Next special case: if there is only one "Incompatible" error, just emit that
+        if let [
+            Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(err))),
+        ] = &errors[..]
+        {
+            let (formal_ty, expected_ty) = formal_and_expected_inputs[*expected_idx];
+            let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_idx];
+            let cause = &self.misc(provided_arg_span);
+            let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
+            let mut err = self.report_and_explain_type_error(trace, err);
+            self.emit_coerce_suggestions(
+                &mut err,
+                &provided_args[*provided_idx],
+                provided_ty,
+                Expectation::rvalue_hint(self, expected_ty)
+                    .only_has_type(self)
+                    .unwrap_or(formal_ty),
+                None,
+                None,
+            );
+            err.span_label(
+                full_call_span,
+                format!("arguments to this {} are incorrect", call_name),
+            );
+            // Call out where the function is defined
+            label_fn_like(tcx, &mut err, fn_def_id);
+            err.emit();
+            return;
+        }
+
+        // Second, let's try tuple wrapping the args.
+        // FIXME(compiler-errors): This is currently in its own closure because
+        // I didn't want to factor it out.
+        if try_tuple_wrap_args() {
+            return;
+        }
+
+        let mut err = if formal_and_expected_inputs.len() == provided_args.len() {
+            struct_span_err!(
+                tcx.sess,
+                full_call_span,
+                E0308,
+                "arguments to this {} are incorrect",
+                call_name,
+            )
+        } else {
+            tcx.sess.struct_span_err_with_code(
+                full_call_span,
+                &format!(
+                    "this {} takes {}{} but {} {} supplied",
+                    call_name,
+                    if c_variadic { "at least " } else { "" },
+                    potentially_plural_count(formal_and_expected_inputs.len(), "argument"),
+                    potentially_plural_count(provided_args.len(), "argument"),
+                    if provided_args.len() == 1 { "was" } else { "were" }
+                ),
+                DiagnosticId::Error(err_code.to_owned()),
+            )
+        };
+
+        // As we encounter issues, keep track of what we want to provide for the suggestion
+        let mut labels = vec![];
+        // If there is a single error, we give a specific suggestion; otherwise, we change to
+        // "did you mean" with the suggested function call
+        enum SuggestionText {
+            None,
+            Provide(bool),
+            Remove(bool),
+            Swap,
+            Reorder,
+            DidYouMean,
+        }
+        let mut suggestion_text = SuggestionText::None;
+
+        let mut errors = errors.into_iter().peekable();
+        while let Some(error) = errors.next() {
+            match error {
+                Error::Invalid(provided_idx, expected_idx, compatibility) => {
+                    let (formal_ty, expected_ty) = formal_and_expected_inputs[expected_idx];
+                    let (provided_ty, provided_span) = provided_arg_tys[provided_idx];
+                    if let Compatibility::Incompatible(error) = &compatibility {
+                        let cause = &self.misc(provided_span);
+                        let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
+                        if let Some(e) = error {
+                            self.note_type_err(
+                                &mut err,
+                                &trace.cause,
+                                None,
+                                Some(trace.values),
+                                e,
+                                false,
+                                true,
+                            );
+                        }
+                    }
 
-            // Okay, now that we've emitted the special errors separately, we
-            // are only left missing/extra/swapped and mismatched arguments, both
-            // can be collated pretty easily if needed.
-
-            // Next special case: if there is only one "Incompatible" error, just emit that
-            if errors.len() == 1 {
-                if let Some(Error::Invalid(
-                    input_idx,
-                    arg_idx,
-                    Compatibility::Incompatible(Some(error)),
-                )) = errors.iter().next()
-                {
-                    let expected_ty = expected_input_tys[*arg_idx];
-                    let provided_ty = final_arg_types[*input_idx]
-                        .map(|ty| ty.0)
-                        .unwrap_or_else(|| tcx.ty_error());
-                    let expected_ty = self.resolve_vars_if_possible(expected_ty);
-                    let provided_ty = self.resolve_vars_if_possible(provided_ty);
-                    let cause = &self.misc(provided_args[*input_idx].span);
-                    let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
-                    let mut err = self.report_and_explain_type_error(trace, error);
                     self.emit_coerce_suggestions(
                         &mut err,
-                        &provided_args[*input_idx],
+                        &provided_args[provided_idx],
                         provided_ty,
-                        final_arg_types[*input_idx]
-                            .map(|ty| ty.1)
-                            .unwrap_or_else(|| tcx.ty_error()),
+                        Expectation::rvalue_hint(self, expected_ty)
+                            .only_has_type(self)
+                            .unwrap_or(formal_ty),
                         None,
                         None,
                     );
-                    err.span_label(
-                        full_call_span,
-                        format!("arguments to this {} are incorrect", call_name),
-                    );
-                    // Call out where the function is defined
-                    label_fn_like(tcx, &mut err, fn_def_id);
-                    err.emit();
-                    break 'errors;
                 }
-            }
-
-            let mut err = if minimum_input_count == provided_arg_count {
-                struct_span_err!(
-                    tcx.sess,
-                    full_call_span,
-                    E0308,
-                    "arguments to this {} are incorrect",
-                    call_name,
-                )
-            } else {
-                tcx.sess.struct_span_err_with_code(
-                    full_call_span,
-                    &format!(
-                        "this {} takes {}{} but {} {} supplied",
-                        call_name,
-                        if c_variadic { "at least " } else { "" },
-                        potentially_plural_count(minimum_input_count, "argument"),
-                        potentially_plural_count(provided_arg_count, "argument"),
-                        if provided_arg_count == 1 { "was" } else { "were" }
-                    ),
-                    DiagnosticId::Error(err_code.to_owned()),
-                )
-            };
-
-            // As we encounter issues, keep track of what we want to provide for the suggestion
-            let mut labels = vec![];
-            // If there is a single error, we give a specific suggestion; otherwise, we change to
-            // "did you mean" with the suggested function call
-            enum SuggestionText {
-                None,
-                Provide(bool),
-                Remove(bool),
-                Swap,
-                Reorder,
-                DidYouMean,
-            }
-            let mut suggestion_text = SuggestionText::None;
-
-            let mut errors = errors.into_iter().peekable();
-            while let Some(error) = errors.next() {
-                match error {
-                    Error::Invalid(input_idx, arg_idx, compatibility) => {
-                        let expected_ty = expected_input_tys[arg_idx];
-                        let provided_ty = final_arg_types[input_idx]
-                            .map(|ty| ty.0)
-                            .unwrap_or_else(|| tcx.ty_error());
-                        let expected_ty = self.resolve_vars_if_possible(expected_ty);
-                        let provided_ty = self.resolve_vars_if_possible(provided_ty);
-                        if let Compatibility::Incompatible(error) = &compatibility {
-                            let cause = &self.misc(provided_args[input_idx].span);
-                            let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
-                            if let Some(e) = error {
-                                self.note_type_err(
-                                    &mut err,
-                                    &trace.cause,
-                                    None,
-                                    Some(trace.values),
-                                    e,
-                                    false,
-                                    true,
-                                );
-                            }
+                Error::Extra(arg_idx) => {
+                    let (provided_ty, provided_span) = provided_arg_tys[arg_idx];
+                    let provided_ty_name = if !has_error_or_infer([provided_ty]) {
+                        // FIXME: not suggestable, use something else
+                        format!(" of type `{}`", provided_ty)
+                    } else {
+                        "".to_string()
+                    };
+                    labels
+                        .push((provided_span, format!("argument{} unexpected", provided_ty_name)));
+                    suggestion_text = match suggestion_text {
+                        SuggestionText::None => SuggestionText::Remove(false),
+                        SuggestionText::Remove(_) => SuggestionText::Remove(true),
+                        _ => SuggestionText::DidYouMean,
+                    };
+                }
+                Error::Missing(expected_idx) => {
+                    // If there are multiple missing arguments adjacent to each other,
+                    // then we can provide a single error.
+
+                    let mut missing_idxs = vec![expected_idx];
+                    while let Some(e) = errors.next_if(|e| {
+                        matches!(e, Error::Missing(next_expected_idx)
+                            if *next_expected_idx == *missing_idxs.last().unwrap() + 1)
+                    }) {
+                        match e {
+                            Error::Missing(expected_idx) => missing_idxs.push(expected_idx),
+                            _ => unreachable!(),
                         }
-
-                        self.emit_coerce_suggestions(
-                            &mut err,
-                            &provided_args[input_idx],
-                            provided_ty,
-                            // FIXME(compiler-errors): expected_ty?
-                            final_arg_types[input_idx]
-                                .map(|ty| ty.1)
-                                .unwrap_or_else(|| tcx.ty_error()),
-                            None,
-                            None,
-                        );
                     }
-                    Error::Extra(arg_idx) => {
-                        let arg_type = if let Some((_, ty)) = final_arg_types[arg_idx] {
-                            if ty.references_error() || ty.has_infer_types() {
-                                "".into()
+
+                    // NOTE: Because we might be re-arranging arguments, might have extra
+                    // arguments, etc. it's hard to *really* know where we should provide
+                    // this error label, so as a heuristic, we point to the provided arg, or
+                    // to the call if the missing inputs pass the provided args.
+                    match &missing_idxs[..] {
+                        &[expected_idx] => {
+                            let (_, input_ty) = formal_and_expected_inputs[expected_idx];
+                            let span = if let Some((_, arg_span)) =
+                                provided_arg_tys.get(expected_idx.to_provided_idx())
+                            {
+                                *arg_span
                             } else {
-                                format!(" of type `{}`", ty)
-                            }
-                        } else {
-                            "".into()
-                        };
-                        labels.push((
-                            provided_args[arg_idx].span,
-                            format!("argument{} unexpected", arg_type),
-                        ));
-                        suggestion_text = match suggestion_text {
-                            SuggestionText::None => SuggestionText::Remove(false),
-                            SuggestionText::Remove(_) => SuggestionText::Remove(true),
-                            _ => SuggestionText::DidYouMean,
-                        };
-                    }
-                    Error::Missing(input_idx) => {
-                        // If there are multiple missing arguments adjacent to each other,
-                        // then we can provide a single error.
-
-                        let mut missing_idxs = vec![input_idx];
-                        while let Some(e) = errors.next_if(|e| matches!(e, Error::Missing(input_idx) if *input_idx == (missing_idxs.last().unwrap() + 1))) {
-                            match e {
-                                Error::Missing(input_idx) => missing_idxs.push(input_idx),
-                                _ => unreachable!(),
-                            }
+                                args_span
+                            };
+                            let rendered = if !has_error_or_infer([input_ty]) {
+                                format!(" of type `{}`", input_ty)
+                            } else {
+                                "".to_string()
+                            };
+                            labels.push((span, format!("an argument{} is missing", rendered)));
+                            suggestion_text = match suggestion_text {
+                                SuggestionText::None => SuggestionText::Provide(false),
+                                SuggestionText::Provide(_) => SuggestionText::Provide(true),
+                                _ => SuggestionText::DidYouMean,
+                            };
                         }
-
-                        // NOTE: Because we might be re-arranging arguments, might have extra
-                        // arguments, etc. it's hard to *really* know where we should provide
-                        // this error label, so as a heuristic, we point to the provided arg, or
-                        // to the call if the missing inputs pass the provided args.
-                        match &missing_idxs[..] {
-                            &[input_idx] => {
-                                let expected_ty = expected_input_tys[input_idx];
-                                let input_ty = self.resolve_vars_if_possible(expected_ty);
-                                let span = if input_idx < provided_arg_count {
-                                    let arg_span = provided_args[input_idx].span;
-                                    Span::new(arg_span.lo(), arg_span.hi(), arg_span.ctxt(), None)
-                                } else {
-                                    args_span
-                                };
-                                let arg_type =
-                                    if input_ty.references_error() || input_ty.has_infer_types() {
-                                        "".into()
-                                    } else {
-                                        format!(" of type `{}`", input_ty)
-                                    };
-                                labels.push((span, format!("an argument{} is missing", arg_type)));
-                                suggestion_text = match suggestion_text {
-                                    SuggestionText::None => SuggestionText::Provide(false),
-                                    SuggestionText::Provide(_) => SuggestionText::Provide(true),
-                                    _ => SuggestionText::DidYouMean,
-                                };
-                            }
-                            &[first_idx, second_idx] => {
-                                let first_input_ty =
-                                    self.resolve_vars_if_possible(expected_input_tys[first_idx]);
-                                let second_input_ty =
-                                    self.resolve_vars_if_possible(expected_input_tys[second_idx]);
-
-                                let span = if second_idx < provided_arg_count {
-                                    let first_arg_span = provided_args[first_idx].span;
-                                    let second_arg_span = provided_args[second_idx].span;
-                                    Span::new(
-                                        first_arg_span.lo(),
-                                        second_arg_span.hi(),
-                                        first_arg_span.ctxt(),
-                                        None,
-                                    )
-                                } else {
-                                    args_span
-                                };
-                                let any_unnameable = false
-                                    || first_input_ty.references_error()
-                                    || first_input_ty.has_infer_types()
-                                    || second_input_ty.references_error()
-                                    || second_input_ty.has_infer_types();
-                                let arg_type = if any_unnameable {
-                                    "".into()
-                                } else {
+                        &[first_idx, second_idx] => {
+                            let (_, first_expected_ty) = formal_and_expected_inputs[first_idx];
+                            let (_, second_expected_ty) = formal_and_expected_inputs[second_idx];
+                            let span = if let (Some((_, first_span)), Some((_, second_span))) = (
+                                provided_arg_tys.get(first_idx.to_provided_idx()),
+                                provided_arg_tys.get(second_idx.to_provided_idx()),
+                            ) {
+                                first_span.to(*second_span)
+                            } else {
+                                args_span
+                            };
+                            let rendered =
+                                if !has_error_or_infer([first_expected_ty, second_expected_ty]) {
                                     format!(
                                         " of type `{}` and `{}`",
-                                        first_input_ty, second_input_ty
-                                    )
-                                };
-                                labels
-                                    .push((span, format!("two arguments{} are missing", arg_type)));
-                                suggestion_text = match suggestion_text {
-                                    SuggestionText::None | SuggestionText::Provide(_) => {
-                                        SuggestionText::Provide(true)
-                                    }
-                                    _ => SuggestionText::DidYouMean,
-                                };
-                            }
-                            &[first_idx, second_idx, third_idx] => {
-                                let first_input_ty =
-                                    self.resolve_vars_if_possible(expected_input_tys[first_idx]);
-                                let second_input_ty =
-                                    self.resolve_vars_if_possible(expected_input_tys[second_idx]);
-                                let third_input_ty =
-                                    self.resolve_vars_if_possible(expected_input_tys[third_idx]);
-                                let span = if third_idx < provided_arg_count {
-                                    let first_arg_span = provided_args[first_idx].span;
-                                    let third_arg_span = provided_args[third_idx].span;
-                                    Span::new(
-                                        first_arg_span.lo(),
-                                        third_arg_span.hi(),
-                                        first_arg_span.ctxt(),
-                                        None,
-                                    )
-                                } else {
-                                    args_span
-                                };
-                                let any_unnameable = false
-                                    || first_input_ty.references_error()
-                                    || first_input_ty.has_infer_types()
-                                    || second_input_ty.references_error()
-                                    || second_input_ty.has_infer_types()
-                                    || third_input_ty.references_error()
-                                    || third_input_ty.has_infer_types();
-                                let arg_type = if any_unnameable {
-                                    "".into()
-                                } else {
-                                    format!(
-                                        " of type `{}`, `{}`, and `{}`",
-                                        first_input_ty, second_input_ty, third_input_ty
-                                    )
-                                };
-                                labels.push((
-                                    span,
-                                    format!("three arguments{} are missing", arg_type),
-                                ));
-                                suggestion_text = match suggestion_text {
-                                    SuggestionText::None | SuggestionText::Provide(_) => {
-                                        SuggestionText::Provide(true)
-                                    }
-                                    _ => SuggestionText::DidYouMean,
-                                };
-                            }
-                            missing_idxs => {
-                                let first_idx = *missing_idxs.first().unwrap();
-                                let last_idx = *missing_idxs.last().unwrap();
-                                // NOTE: Because we might be re-arranging arguments, might have extra arguments, etc.
-                                // It's hard to *really* know where we should provide this error label, so this is a
-                                // decent heuristic
-                                let span = if last_idx < provided_arg_count {
-                                    let first_arg_span = provided_args[first_idx].span;
-                                    let last_arg_span = provided_args[last_idx].span;
-                                    Span::new(
-                                        first_arg_span.lo(),
-                                        last_arg_span.hi(),
-                                        first_arg_span.ctxt(),
-                                        None,
+                                        first_expected_ty, second_expected_ty
                                     )
                                 } else {
-                                    // Otherwise just label the whole function
-                                    args_span
-                                };
-                                labels.push((span, format!("multiple arguments are missing")));
-                                suggestion_text = match suggestion_text {
-                                    SuggestionText::None | SuggestionText::Provide(_) => {
-                                        SuggestionText::Provide(true)
-                                    }
-                                    _ => SuggestionText::DidYouMean,
+                                    "".to_string()
                                 };
-                            }
+                            labels.push((span, format!("two arguments{} are missing", rendered)));
+                            suggestion_text = match suggestion_text {
+                                SuggestionText::None | SuggestionText::Provide(_) => {
+                                    SuggestionText::Provide(true)
+                                }
+                                _ => SuggestionText::DidYouMean,
+                            };
                         }
-                    }
-                    Error::Swap(input_idx, other_input_idx, arg_idx, other_arg_idx) => {
-                        let first_span = provided_args[input_idx].span;
-                        let second_span = provided_args[other_input_idx].span;
-
-                        let first_expected_ty =
-                            self.resolve_vars_if_possible(expected_input_tys[arg_idx]);
-                        let first_provided_ty = if let Some((ty, _)) = final_arg_types[input_idx] {
-                            format!(", found `{}`", ty)
-                        } else {
-                            String::new()
-                        };
-                        labels.push((
-                            first_span,
-                            format!("expected `{}`{}", first_expected_ty, first_provided_ty),
-                        ));
-                        let other_expected_ty =
-                            self.resolve_vars_if_possible(expected_input_tys[other_arg_idx]);
-                        let other_provided_ty =
-                            if let Some((ty, _)) = final_arg_types[other_input_idx] {
-                                format!(", found `{}`", ty)
+                        &[first_idx, second_idx, third_idx] => {
+                            let (_, first_expected_ty) = formal_and_expected_inputs[first_idx];
+                            let (_, second_expected_ty) = formal_and_expected_inputs[second_idx];
+                            let (_, third_expected_ty) = formal_and_expected_inputs[third_idx];
+                            let span = if let (Some((_, first_span)), Some((_, third_span))) = (
+                                provided_arg_tys.get(first_idx.to_provided_idx()),
+                                provided_arg_tys.get(third_idx.to_provided_idx()),
+                            ) {
+                                first_span.to(*third_span)
                             } else {
-                                String::new()
+                                args_span
                             };
-                        labels.push((
-                            second_span,
-                            format!("expected `{}`{}", other_expected_ty, other_provided_ty),
-                        ));
-                        suggestion_text = match suggestion_text {
-                            SuggestionText::None => SuggestionText::Swap,
-                            _ => SuggestionText::DidYouMean,
-                        };
-                    }
-                    Error::Permutation(args) => {
-                        for (dst_arg, dest_input) in args {
-                            let expected_ty =
-                                self.resolve_vars_if_possible(expected_input_tys[dst_arg]);
-                            let provided_ty = if let Some((ty, _)) = final_arg_types[dest_input] {
-                                format!(", found `{}`", ty)
+                            let rendered = if !has_error_or_infer([
+                                first_expected_ty,
+                                second_expected_ty,
+                                third_expected_ty,
+                            ]) {
+                                format!(
+                                    " of type `{}`, `{}`, and `{}`",
+                                    first_expected_ty, second_expected_ty, third_expected_ty
+                                )
                             } else {
-                                String::new()
+                                "".to_string()
+                            };
+                            labels.push((span, format!("three arguments{} are missing", rendered)));
+                            suggestion_text = match suggestion_text {
+                                SuggestionText::None | SuggestionText::Provide(_) => {
+                                    SuggestionText::Provide(true)
+                                }
+                                _ => SuggestionText::DidYouMean,
+                            };
+                        }
+                        missing_idxs => {
+                            let first_idx = *missing_idxs.first().unwrap();
+                            let last_idx = *missing_idxs.last().unwrap();
+                            // NOTE: Because we might be re-arranging arguments, might have extra arguments, etc.
+                            // It's hard to *really* know where we should provide this error label, so this is a
+                            // decent heuristic
+                            let span = if let (Some((_, first_span)), Some((_, last_span))) = (
+                                provided_arg_tys.get(first_idx.to_provided_idx()),
+                                provided_arg_tys.get(last_idx.to_provided_idx()),
+                            ) {
+                                first_span.to(*last_span)
+                            } else {
+                                args_span
+                            };
+                            labels.push((span, format!("multiple arguments are missing")));
+                            suggestion_text = match suggestion_text {
+                                SuggestionText::None | SuggestionText::Provide(_) => {
+                                    SuggestionText::Provide(true)
+                                }
+                                _ => SuggestionText::DidYouMean,
                             };
-                            labels.push((
-                                provided_args[dest_input].span,
-                                format!("expected `{}`{}", expected_ty, provided_ty),
-                            ));
                         }
-
-                        suggestion_text = match suggestion_text {
-                            SuggestionText::None => SuggestionText::Reorder,
-                            _ => SuggestionText::DidYouMean,
-                        };
                     }
                 }
-            }
-
-            // If we have less than 5 things to say, it would be useful to call out exactly what's wrong
-            if labels.len() <= 5 {
-                for (span, label) in labels {
-                    err.span_label(span, label);
-                }
-            }
-
-            // Call out where the function is defined
-            label_fn_like(tcx, &mut err, fn_def_id);
-
-            // And add a suggestion block for all of the parameters
-            let suggestion_text = match suggestion_text {
-                SuggestionText::None => None,
-                SuggestionText::Provide(plural) => {
-                    Some(format!("provide the argument{}", if plural { "s" } else { "" }))
-                }
-                SuggestionText::Remove(plural) => {
-                    Some(format!("remove the extra argument{}", if plural { "s" } else { "" }))
-                }
-                SuggestionText::Swap => Some("swap these arguments".to_string()),
-                SuggestionText::Reorder => Some("reorder these arguments".to_string()),
-                SuggestionText::DidYouMean => Some("did you mean".to_string()),
-            };
-            if let Some(suggestion_text) = suggestion_text {
-                let source_map = self.sess().source_map();
-                let mut suggestion = format!(
-                    "{}(",
-                    source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| String::new())
-                );
-                for (arg_index, input_idx) in matched_inputs.iter().enumerate() {
-                    let suggestion_text = if let Some(input_idx) = input_idx {
-                        let arg_span = provided_args[*input_idx].span.source_callsite();
-                        let arg_text = source_map.span_to_snippet(arg_span).unwrap();
-                        arg_text
+                Error::Swap(
+                    first_provided_idx,
+                    second_provided_idx,
+                    first_expected_idx,
+                    second_expected_idx,
+                ) => {
+                    let (first_provided_ty, first_span) = provided_arg_tys[first_provided_idx];
+                    let (_, first_expected_ty) = formal_and_expected_inputs[first_expected_idx];
+                    let first_provided_ty_name = if !has_error_or_infer([first_provided_ty]) {
+                        format!(", found `{}`", first_provided_ty)
                     } else {
-                        // Propose a placeholder of the correct type
-                        let expected_ty = expected_input_tys[arg_index];
-                        let input_ty = self.resolve_vars_if_possible(expected_ty);
-                        if input_ty.is_unit() {
-                            "()".to_string()
-                        } else if !input_ty.is_ty_var() {
-                            format!("/* {} */", input_ty)
+                        String::new()
+                    };
+                    labels.push((
+                        first_span,
+                        format!("expected `{}`{}", first_expected_ty, first_provided_ty_name),
+                    ));
+
+                    let (second_provided_ty, second_span) = provided_arg_tys[second_provided_idx];
+                    let (_, second_expected_ty) = formal_and_expected_inputs[second_expected_idx];
+                    let second_provided_ty_name = if !has_error_or_infer([second_provided_ty]) {
+                        format!(", found `{}`", second_provided_ty)
+                    } else {
+                        String::new()
+                    };
+                    labels.push((
+                        second_span,
+                        format!("expected `{}`{}", second_expected_ty, second_provided_ty_name),
+                    ));
+
+                    suggestion_text = match suggestion_text {
+                        SuggestionText::None => SuggestionText::Swap,
+                        _ => SuggestionText::DidYouMean,
+                    };
+                }
+                Error::Permutation(args) => {
+                    for (dst_arg, dest_input) in args {
+                        let (_, expected_ty) = formal_and_expected_inputs[dst_arg];
+                        let (provided_ty, provided_span) = provided_arg_tys[dest_input];
+                        let provided_ty_name = if !has_error_or_infer([provided_ty]) {
+                            format!(", found `{}`", provided_ty)
                         } else {
-                            "/* value */".to_string()
+                            String::new()
+                        };
+                        // FIXME(compiler-errors): Why do we get permutations with the same type?
+                        if expected_ty != provided_ty {
+                            labels.push((
+                                provided_span,
+                                format!("expected `{}`{}", expected_ty, provided_ty_name),
+                            ));
                         }
-                    };
-                    suggestion += &suggestion_text;
-                    if arg_index < minimum_input_count - 1 {
-                        suggestion += ", ";
                     }
+
+                    suggestion_text = match suggestion_text {
+                        SuggestionText::None => SuggestionText::Reorder,
+                        _ => SuggestionText::DidYouMean,
+                    };
                 }
-                suggestion += ")";
-                err.span_suggestion_verbose(
-                    error_span,
-                    &suggestion_text,
-                    suggestion,
-                    Applicability::HasPlaceholders,
-                );
             }
-            err.emit();
         }
 
-        for arg in provided_args.iter().skip(minimum_input_count) {
-            let arg_ty = self.check_expr(&arg);
+        // If we have less than 5 things to say, it would be useful to call out exactly what's wrong
+        if labels.len() <= 5 {
+            for (span, label) in labels {
+                err.span_label(span, label);
+            }
+        }
 
-            // If the function is c-style variadic, we skipped a bunch of arguments
-            // so we need to check those, and write out the types
-            // Ideally this would be folded into the above, for uniform style
-            // but c-variadic is already a corner case
-            if c_variadic {
-                fn variadic_error<'tcx>(
-                    sess: &'tcx Session,
-                    span: Span,
-                    ty: Ty<'tcx>,
-                    cast_ty: &str,
-                ) {
-                    use crate::structured_errors::MissingCastForVariadicArg;
+        // Call out where the function is defined
+        label_fn_like(tcx, &mut err, fn_def_id);
 
-                    MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit();
+        // And add a suggestion block for all of the parameters
+        let suggestion_text = match suggestion_text {
+            SuggestionText::None => None,
+            SuggestionText::Provide(plural) => {
+                Some(format!("provide the argument{}", if plural { "s" } else { "" }))
+            }
+            SuggestionText::Remove(plural) => {
+                Some(format!("remove the extra argument{}", if plural { "s" } else { "" }))
+            }
+            SuggestionText::Swap => Some("swap these arguments".to_string()),
+            SuggestionText::Reorder => Some("reorder these arguments".to_string()),
+            SuggestionText::DidYouMean => Some("did you mean".to_string()),
+        };
+        if let Some(suggestion_text) = suggestion_text {
+            let source_map = self.sess().source_map();
+            let mut suggestion = format!(
+                "{}(",
+                source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| fn_def_id
+                    .map_or("".to_string(), |fn_def_id| tcx.item_name(fn_def_id).to_string()))
+            );
+            let mut needs_comma = false;
+            for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() {
+                if needs_comma {
+                    suggestion += ", ";
+                } else {
+                    needs_comma = true;
                 }
-
-                // There are a few types which get autopromoted when passed via varargs
-                // in C but we just error out instead and require explicit casts.
-                let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
-                match arg_ty.kind() {
-                    ty::Float(ty::FloatTy::F32) => {
-                        variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
-                    }
-                    ty::Int(ty::IntTy::I8 | ty::IntTy::I16) | ty::Bool => {
-                        variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
-                    }
-                    ty::Uint(ty::UintTy::U8 | ty::UintTy::U16) => {
-                        variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
-                    }
-                    ty::FnDef(..) => {
-                        let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
-                        let ptr_ty = self.resolve_vars_if_possible(ptr_ty);
-                        variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
+                let suggestion_text =
+                    if let Some(provided_idx) = provided_idx
+                    && let (_, provided_span) = provided_arg_tys[*provided_idx]
+                    && let Ok(arg_text) = source_map.span_to_snippet(provided_span.source_callsite()) {
+                    arg_text
+                } else {
+                    // Propose a placeholder of the correct type
+                    let (_, expected_ty) = formal_and_expected_inputs[expected_idx];
+                    if expected_ty.is_unit() {
+                        "()".to_string()
+                    } else if expected_ty.is_suggestable(tcx) {
+                        format!("/* {} */", expected_ty)
+                    } else {
+                        "/* value */".to_string()
                     }
-                    _ => {}
-                }
+                };
+                suggestion += &suggestion_text;
             }
+            suggestion += ")";
+            err.span_suggestion_verbose(
+                error_span,
+                &suggestion_text,
+                suggestion,
+                Applicability::HasPlaceholders,
+            );
         }
+
+        err.emit();
     }
 
     fn suggested_tuple_wrap(
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 2f9afbec91e..d230c06a211 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -70,6 +70,214 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     unsafe { crate::ptr::drop_in_place(to_drop) }
 }
 
+// These have been renamed.
+#[cfg(bootstrap)]
+extern "rust-intrinsic" {
+    pub fn atomic_cxchg<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_acq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_rel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_acqrel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_failacq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_acq_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_acqrel_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_acq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_rel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_acqrel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_failacq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_acq_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_acqrel_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_load<T: Copy>(src: *const T) -> T;
+    pub fn atomic_load_acq<T: Copy>(src: *const T) -> T;
+    pub fn atomic_load_relaxed<T: Copy>(src: *const T) -> T;
+    pub fn atomic_load_unordered<T: Copy>(src: *const T) -> T;
+    pub fn atomic_store<T: Copy>(dst: *mut T, val: T);
+    pub fn atomic_store_rel<T: Copy>(dst: *mut T, val: T);
+    pub fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
+    pub fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
+    pub fn atomic_xchg<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xchg_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xchg_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xchg_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xchg_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xadd<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xadd_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xadd_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xadd_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xadd_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xsub<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xsub_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xsub_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xsub_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xsub_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_and<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_and_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_and_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_and_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_and_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_nand<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_nand_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_nand_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_nand_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_nand_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_or<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_or_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_or_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_or_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_or_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xor<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xor_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xor_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xor_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xor_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_max<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_max_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_max_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_max_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_max_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_min<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_min_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_min_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_min_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_min_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umin<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umin_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umin_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umin_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umin_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umax<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umax_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umax_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umax_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umax_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_fence();
+    pub fn atomic_fence_acq();
+    pub fn atomic_fence_rel();
+    pub fn atomic_fence_acqrel();
+    pub fn atomic_singlethreadfence();
+    pub fn atomic_singlethreadfence_acq();
+    pub fn atomic_singlethreadfence_rel();
+    pub fn atomic_singlethreadfence_acqrel();
+}
+
+// These have been renamed.
+#[cfg(bootstrap)]
+mod atomics {
+    pub use super::atomic_cxchg as atomic_cxchg_seqcst_seqcst;
+    pub use super::atomic_cxchg_acq as atomic_cxchg_acquire_acquire;
+    pub use super::atomic_cxchg_acq_failrelaxed as atomic_cxchg_acquire_relaxed;
+    pub use super::atomic_cxchg_acqrel as atomic_cxchg_acqrel_acquire;
+    pub use super::atomic_cxchg_acqrel_failrelaxed as atomic_cxchg_acqrel_relaxed;
+    pub use super::atomic_cxchg_failacq as atomic_cxchg_seqcst_acquire;
+    pub use super::atomic_cxchg_failrelaxed as atomic_cxchg_seqcst_relaxed;
+    pub use super::atomic_cxchg_rel as atomic_cxchg_release_relaxed;
+    pub use super::atomic_cxchg_relaxed as atomic_cxchg_relaxed_relaxed;
+
+    pub use super::atomic_cxchgweak as atomic_cxchgweak_seqcst_seqcst;
+    pub use super::atomic_cxchgweak_acq as atomic_cxchgweak_acquire_acquire;
+    pub use super::atomic_cxchgweak_acq_failrelaxed as atomic_cxchgweak_acquire_relaxed;
+    pub use super::atomic_cxchgweak_acqrel as atomic_cxchgweak_acqrel_acquire;
+    pub use super::atomic_cxchgweak_acqrel_failrelaxed as atomic_cxchgweak_acqrel_relaxed;
+    pub use super::atomic_cxchgweak_failacq as atomic_cxchgweak_seqcst_acquire;
+    pub use super::atomic_cxchgweak_failrelaxed as atomic_cxchgweak_seqcst_relaxed;
+    pub use super::atomic_cxchgweak_rel as atomic_cxchgweak_release_relaxed;
+    pub use super::atomic_cxchgweak_relaxed as atomic_cxchgweak_relaxed_relaxed;
+
+    pub use super::atomic_load as atomic_load_seqcst;
+    pub use super::atomic_load_acq as atomic_load_acquire;
+    pub use super::atomic_load_relaxed;
+    pub use super::atomic_load_unordered;
+
+    pub use super::atomic_store as atomic_store_seqcst;
+    pub use super::atomic_store_rel as atomic_store_release;
+    pub use super::atomic_store_relaxed;
+    pub use super::atomic_store_unordered;
+
+    pub use super::atomic_xchg as atomic_xchg_seqcst;
+    pub use super::atomic_xchg_acq as atomic_xchg_acquire;
+    pub use super::atomic_xchg_acqrel;
+    pub use super::atomic_xchg_rel as atomic_xchg_release;
+    pub use super::atomic_xchg_relaxed;
+
+    pub use super::atomic_xadd as atomic_xadd_seqcst;
+    pub use super::atomic_xadd_acq as atomic_xadd_acquire;
+    pub use super::atomic_xadd_acqrel;
+    pub use super::atomic_xadd_rel as atomic_xadd_release;
+    pub use super::atomic_xadd_relaxed;
+
+    pub use super::atomic_xsub as atomic_xsub_seqcst;
+    pub use super::atomic_xsub_acq as atomic_xsub_acquire;
+    pub use super::atomic_xsub_acqrel;
+    pub use super::atomic_xsub_rel as atomic_xsub_release;
+    pub use super::atomic_xsub_relaxed;
+
+    pub use super::atomic_and as atomic_and_seqcst;
+    pub use super::atomic_and_acq as atomic_and_acquire;
+    pub use super::atomic_and_acqrel;
+    pub use super::atomic_and_rel as atomic_and_release;
+    pub use super::atomic_and_relaxed;
+
+    pub use super::atomic_nand as atomic_nand_seqcst;
+    pub use super::atomic_nand_acq as atomic_nand_acquire;
+    pub use super::atomic_nand_acqrel;
+    pub use super::atomic_nand_rel as atomic_nand_release;
+    pub use super::atomic_nand_relaxed;
+
+    pub use super::atomic_or as atomic_or_seqcst;
+    pub use super::atomic_or_acq as atomic_or_acquire;
+    pub use super::atomic_or_acqrel;
+    pub use super::atomic_or_rel as atomic_or_release;
+    pub use super::atomic_or_relaxed;
+
+    pub use super::atomic_xor as atomic_xor_seqcst;
+    pub use super::atomic_xor_acq as atomic_xor_acquire;
+    pub use super::atomic_xor_acqrel;
+    pub use super::atomic_xor_rel as atomic_xor_release;
+    pub use super::atomic_xor_relaxed;
+
+    pub use super::atomic_max as atomic_max_seqcst;
+    pub use super::atomic_max_acq as atomic_max_acquire;
+    pub use super::atomic_max_acqrel;
+    pub use super::atomic_max_rel as atomic_max_release;
+    pub use super::atomic_max_relaxed;
+
+    pub use super::atomic_min as atomic_min_seqcst;
+    pub use super::atomic_min_acq as atomic_min_acquire;
+    pub use super::atomic_min_acqrel;
+    pub use super::atomic_min_rel as atomic_min_release;
+    pub use super::atomic_min_relaxed;
+
+    pub use super::atomic_umin as atomic_umin_seqcst;
+    pub use super::atomic_umin_acq as atomic_umin_acquire;
+    pub use super::atomic_umin_acqrel;
+    pub use super::atomic_umin_rel as atomic_umin_release;
+    pub use super::atomic_umin_relaxed;
+
+    pub use super::atomic_umax as atomic_umax_seqcst;
+    pub use super::atomic_umax_acq as atomic_umax_acquire;
+    pub use super::atomic_umax_acqrel;
+    pub use super::atomic_umax_rel as atomic_umax_release;
+    pub use super::atomic_umax_relaxed;
+
+    pub use super::atomic_fence as atomic_fence_seqcst;
+    pub use super::atomic_fence_acq as atomic_fence_acquire;
+    pub use super::atomic_fence_acqrel;
+    pub use super::atomic_fence_rel as atomic_fence_release;
+
+    pub use super::atomic_singlethreadfence as atomic_singlethreadfence_seqcst;
+    pub use super::atomic_singlethreadfence_acq as atomic_singlethreadfence_acquire;
+    pub use super::atomic_singlethreadfence_acqrel;
+    pub use super::atomic_singlethreadfence_rel as atomic_singlethreadfence_release;
+}
+
+#[cfg(bootstrap)]
+pub use atomics::*;
+
+#[cfg(not(bootstrap))]
 extern "rust-intrinsic" {
     // N.B., these intrinsics take raw pointers because they mutate aliased
     // memory, which is not valid for either `&` or `&mut`.
@@ -78,142 +286,226 @@ extern "rust-intrinsic" {
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::SeqCst`] as both the `success` and `failure` parameters.
+    /// [`Ordering::Relaxed`] as both the success and failure parameters.
     /// For example, [`AtomicBool::compare_exchange`].
-    pub fn atomic_cxchg<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_relaxed_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::Acquire`] as both the `success` and `failure` parameters.
+    /// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters.
     /// For example, [`AtomicBool::compare_exchange`].
-    pub fn atomic_cxchg_acq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_relaxed_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::Release`] as the `success` and [`Ordering::Relaxed`] as the
-    /// `failure` parameters. For example, [`AtomicBool::compare_exchange`].
-    pub fn atomic_cxchg_rel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange`].
+    pub fn atomic_cxchg_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::AcqRel`] as the `success` and [`Ordering::Acquire`] as the
-    /// `failure` parameters. For example, [`AtomicBool::compare_exchange`].
-    pub fn atomic_cxchg_acqrel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange`].
+    pub fn atomic_cxchg_acquire_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::Relaxed`] as both the `success` and `failure` parameters.
+    /// [`Ordering::Acquire`] as both the success and failure parameters.
     /// For example, [`AtomicBool::compare_exchange`].
-    pub fn atomic_cxchg_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchg_acquire_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::SeqCst`] as the `success` and [`Ordering::Relaxed`] as the
-    /// `failure` parameters. For example, [`AtomicBool::compare_exchange`].
-    pub fn atomic_cxchg_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange`].
+    pub fn atomic_cxchg_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::SeqCst`] as the `success` and [`Ordering::Acquire`] as the
-    /// `failure` parameters. For example, [`AtomicBool::compare_exchange`].
-    pub fn atomic_cxchg_failacq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange`].
+    pub fn atomic_cxchg_release_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::Acquire`] as the `success` and [`Ordering::Relaxed`] as the
-    /// `failure` parameters. For example, [`AtomicBool::compare_exchange`].
-    pub fn atomic_cxchg_acq_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange`].
+    pub fn atomic_cxchg_release_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::AcqRel`] as the `success` and [`Ordering::Relaxed`] as the
-    /// `failure` parameters. For example, [`AtomicBool::compare_exchange`].
-    pub fn atomic_cxchg_acqrel_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange`].
+    pub fn atomic_cxchg_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// Stores a value if the current value is the same as the `old` value.
+    ///
+    /// The stabilized version of this intrinsic is available on the
+    /// [`atomic`] types via the `compare_exchange` method by passing
+    /// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange`].
+    pub fn atomic_cxchg_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// Stores a value if the current value is the same as the `old` value.
+    ///
+    /// The stabilized version of this intrinsic is available on the
+    /// [`atomic`] types via the `compare_exchange` method by passing
+    /// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange`].
+    pub fn atomic_cxchg_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// Stores a value if the current value is the same as the `old` value.
+    ///
+    /// The stabilized version of this intrinsic is available on the
+    /// [`atomic`] types via the `compare_exchange` method by passing
+    /// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange`].
+    pub fn atomic_cxchg_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// Stores a value if the current value is the same as the `old` value.
+    ///
+    /// The stabilized version of this intrinsic is available on the
+    /// [`atomic`] types via the `compare_exchange` method by passing
+    /// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange`].
+    pub fn atomic_cxchg_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// Stores a value if the current value is the same as the `old` value.
+    ///
+    /// The stabilized version of this intrinsic is available on the
+    /// [`atomic`] types via the `compare_exchange` method by passing
+    /// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange`].
+    pub fn atomic_cxchg_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// Stores a value if the current value is the same as the `old` value.
+    ///
+    /// The stabilized version of this intrinsic is available on the
+    /// [`atomic`] types via the `compare_exchange` method by passing
+    /// [`Ordering::SeqCst`] as both the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange`].
+    pub fn atomic_cxchg_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::SeqCst`] as both the `success` and `failure` parameters.
+    /// [`Ordering::Relaxed`] as both the success and failure parameters.
     /// For example, [`AtomicBool::compare_exchange_weak`].
-    pub fn atomic_cxchgweak<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_relaxed_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::Acquire`] as both the `success` and `failure` parameters.
+    /// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters.
     /// For example, [`AtomicBool::compare_exchange_weak`].
-    pub fn atomic_cxchgweak_acq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_relaxed_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::Release`] as the `success` and [`Ordering::Relaxed`] as the
-    /// `failure` parameters. For example, [`AtomicBool::compare_exchange_weak`].
-    pub fn atomic_cxchgweak_rel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange_weak`].
+    pub fn atomic_cxchgweak_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::AcqRel`] as the `success` and [`Ordering::Acquire`] as the
-    /// `failure` parameters. For example, [`AtomicBool::compare_exchange_weak`].
-    pub fn atomic_cxchgweak_acqrel<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange_weak`].
+    pub fn atomic_cxchgweak_acquire_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::Relaxed`] as both the `success` and `failure` parameters.
+    /// [`Ordering::Acquire`] as both the success and failure parameters.
     /// For example, [`AtomicBool::compare_exchange_weak`].
-    pub fn atomic_cxchgweak_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    pub fn atomic_cxchgweak_acquire_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::SeqCst`] as the `success` and [`Ordering::Relaxed`] as the
-    /// `failure` parameters. For example, [`AtomicBool::compare_exchange_weak`].
-    pub fn atomic_cxchgweak_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange_weak`].
+    pub fn atomic_cxchgweak_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::SeqCst`] as the `success` and [`Ordering::Acquire`] as the
-    /// `failure` parameters. For example, [`AtomicBool::compare_exchange_weak`].
-    pub fn atomic_cxchgweak_failacq<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange_weak`].
+    pub fn atomic_cxchgweak_release_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::Acquire`] as the `success` and [`Ordering::Relaxed`] as the
-    /// `failure` parameters. For example, [`AtomicBool::compare_exchange_weak`].
-    pub fn atomic_cxchgweak_acq_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange_weak`].
+    pub fn atomic_cxchgweak_release_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::AcqRel`] as the `success` and [`Ordering::Relaxed`] as the
-    /// `failure` parameters. For example, [`AtomicBool::compare_exchange_weak`].
-    pub fn atomic_cxchgweak_acqrel_failrelaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange_weak`].
+    pub fn atomic_cxchgweak_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// Stores a value if the current value is the same as the `old` value.
+    ///
+    /// The stabilized version of this intrinsic is available on the
+    /// [`atomic`] types via the `compare_exchange_weak` method by passing
+    /// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange_weak`].
+    pub fn atomic_cxchgweak_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// Stores a value if the current value is the same as the `old` value.
+    ///
+    /// The stabilized version of this intrinsic is available on the
+    /// [`atomic`] types via the `compare_exchange_weak` method by passing
+    /// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange_weak`].
+    pub fn atomic_cxchgweak_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// Stores a value if the current value is the same as the `old` value.
+    ///
+    /// The stabilized version of this intrinsic is available on the
+    /// [`atomic`] types via the `compare_exchange_weak` method by passing
+    /// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange_weak`].
+    pub fn atomic_cxchgweak_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// Stores a value if the current value is the same as the `old` value.
+    ///
+    /// The stabilized version of this intrinsic is available on the
+    /// [`atomic`] types via the `compare_exchange_weak` method by passing
+    /// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange_weak`].
+    pub fn atomic_cxchgweak_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// Stores a value if the current value is the same as the `old` value.
+    ///
+    /// The stabilized version of this intrinsic is available on the
+    /// [`atomic`] types via the `compare_exchange_weak` method by passing
+    /// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange_weak`].
+    pub fn atomic_cxchgweak_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+    /// Stores a value if the current value is the same as the `old` value.
+    ///
+    /// The stabilized version of this intrinsic is available on the
+    /// [`atomic`] types via the `compare_exchange_weak` method by passing
+    /// [`Ordering::SeqCst`] as both the success and failure parameters.
+    /// For example, [`AtomicBool::compare_exchange_weak`].
+    pub fn atomic_cxchgweak_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
 
     /// Loads the current value of the pointer.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `load` method by passing
     /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::load`].
-    pub fn atomic_load<T: Copy>(src: *const T) -> T;
+    pub fn atomic_load_seqcst<T: Copy>(src: *const T) -> T;
     /// Loads the current value of the pointer.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `load` method by passing
     /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::load`].
-    pub fn atomic_load_acq<T: Copy>(src: *const T) -> T;
+    pub fn atomic_load_acquire<T: Copy>(src: *const T) -> T;
     /// Loads the current value of the pointer.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -227,13 +519,13 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `store` method by passing
     /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::store`].
-    pub fn atomic_store<T: Copy>(dst: *mut T, val: T);
+    pub fn atomic_store_seqcst<T: Copy>(dst: *mut T, val: T);
     /// Stores the value at the specified memory location.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `store` method by passing
     /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::store`].
-    pub fn atomic_store_rel<T: Copy>(dst: *mut T, val: T);
+    pub fn atomic_store_release<T: Copy>(dst: *mut T, val: T);
     /// Stores the value at the specified memory location.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -247,19 +539,19 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `swap` method by passing
     /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::swap`].
-    pub fn atomic_xchg<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xchg_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
     /// Stores the value at the specified memory location, returning the old value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `swap` method by passing
     /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::swap`].
-    pub fn atomic_xchg_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xchg_acquire<T: Copy>(dst: *mut T, src: T) -> T;
     /// Stores the value at the specified memory location, returning the old value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `swap` method by passing
     /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::swap`].
-    pub fn atomic_xchg_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xchg_release<T: Copy>(dst: *mut T, src: T) -> T;
     /// Stores the value at the specified memory location, returning the old value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -278,19 +570,19 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_add` method by passing
     /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_add`].
-    pub fn atomic_xadd<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xadd_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
     /// Adds to the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_add` method by passing
     /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_add`].
-    pub fn atomic_xadd_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xadd_acquire<T: Copy>(dst: *mut T, src: T) -> T;
     /// Adds to the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_add` method by passing
     /// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_add`].
-    pub fn atomic_xadd_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xadd_release<T: Copy>(dst: *mut T, src: T) -> T;
     /// Adds to the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -309,19 +601,19 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_sub` method by passing
     /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
-    pub fn atomic_xsub<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xsub_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
     /// Subtract from the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_sub` method by passing
     /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
-    pub fn atomic_xsub_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xsub_acquire<T: Copy>(dst: *mut T, src: T) -> T;
     /// Subtract from the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_sub` method by passing
     /// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
-    pub fn atomic_xsub_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xsub_release<T: Copy>(dst: *mut T, src: T) -> T;
     /// Subtract from the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -340,19 +632,19 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_and` method by passing
     /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_and`].
-    pub fn atomic_and<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_and_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise and with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_and` method by passing
     /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_and`].
-    pub fn atomic_and_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_and_acquire<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise and with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_and` method by passing
     /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_and`].
-    pub fn atomic_and_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_and_release<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise and with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -371,19 +663,19 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available on the
     /// [`AtomicBool`] type via the `fetch_nand` method by passing
     /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_nand`].
-    pub fn atomic_nand<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_nand_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise nand with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`AtomicBool`] type via the `fetch_nand` method by passing
     /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_nand`].
-    pub fn atomic_nand_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_nand_acquire<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise nand with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`AtomicBool`] type via the `fetch_nand` method by passing
     /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_nand`].
-    pub fn atomic_nand_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_nand_release<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise nand with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -402,19 +694,19 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_or` method by passing
     /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_or`].
-    pub fn atomic_or<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_or_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise or with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_or` method by passing
     /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_or`].
-    pub fn atomic_or_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_or_acquire<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise or with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_or` method by passing
     /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_or`].
-    pub fn atomic_or_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_or_release<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise or with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -433,19 +725,19 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_xor` method by passing
     /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_xor`].
-    pub fn atomic_xor<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xor_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise xor with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_xor` method by passing
     /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_xor`].
-    pub fn atomic_xor_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xor_acquire<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise xor with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] types via the `fetch_xor` method by passing
     /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_xor`].
-    pub fn atomic_xor_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_xor_release<T: Copy>(dst: *mut T, src: T) -> T;
     /// Bitwise xor with the current value, returning the previous value.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -464,19 +756,19 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] signed integer types via the `fetch_max` method by passing
     /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_max`].
-    pub fn atomic_max<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_max_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
     /// Maximum with the current value using a signed comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] signed integer types via the `fetch_max` method by passing
     /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_max`].
-    pub fn atomic_max_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_max_acquire<T: Copy>(dst: *mut T, src: T) -> T;
     /// Maximum with the current value using a signed comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] signed integer types via the `fetch_max` method by passing
     /// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_max`].
-    pub fn atomic_max_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_max_release<T: Copy>(dst: *mut T, src: T) -> T;
     /// Maximum with the current value using a signed comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -495,19 +787,19 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] signed integer types via the `fetch_min` method by passing
     /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_min`].
-    pub fn atomic_min<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_min_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
     /// Minimum with the current value using a signed comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] signed integer types via the `fetch_min` method by passing
     /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_min`].
-    pub fn atomic_min_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_min_acquire<T: Copy>(dst: *mut T, src: T) -> T;
     /// Minimum with the current value using a signed comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] signed integer types via the `fetch_min` method by passing
     /// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_min`].
-    pub fn atomic_min_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_min_release<T: Copy>(dst: *mut T, src: T) -> T;
     /// Minimum with the current value using a signed comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -526,19 +818,19 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
     /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_min`].
-    pub fn atomic_umin<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umin_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
     /// Minimum with the current value using an unsigned comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
     /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_min`].
-    pub fn atomic_umin_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umin_acquire<T: Copy>(dst: *mut T, src: T) -> T;
     /// Minimum with the current value using an unsigned comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
     /// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_min`].
-    pub fn atomic_umin_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umin_release<T: Copy>(dst: *mut T, src: T) -> T;
     /// Minimum with the current value using an unsigned comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -557,19 +849,19 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
     /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_max`].
-    pub fn atomic_umax<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umax_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
     /// Maximum with the current value using an unsigned comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
     /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_max`].
-    pub fn atomic_umax_acq<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umax_acquire<T: Copy>(dst: *mut T, src: T) -> T;
     /// Maximum with the current value using an unsigned comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
     /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
     /// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_max`].
-    pub fn atomic_umax_rel<T: Copy>(dst: *mut T, src: T) -> T;
+    pub fn atomic_umax_release<T: Copy>(dst: *mut T, src: T) -> T;
     /// Maximum with the current value using an unsigned comparison.
     ///
     /// The stabilized version of this intrinsic is available on the
@@ -583,67 +875,24 @@ extern "rust-intrinsic" {
     /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_max`].
     pub fn atomic_umax_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
 
-    /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
-    /// if supported; otherwise, it is a no-op.
-    /// Prefetches have no effect on the behavior of the program but can change its performance
-    /// characteristics.
-    ///
-    /// The `locality` argument must be a constant integer and is a temporal locality specifier
-    /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    pub fn prefetch_read_data<T>(data: *const T, locality: i32);
-    /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
-    /// if supported; otherwise, it is a no-op.
-    /// Prefetches have no effect on the behavior of the program but can change its performance
-    /// characteristics.
-    ///
-    /// The `locality` argument must be a constant integer and is a temporal locality specifier
-    /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    pub fn prefetch_write_data<T>(data: *const T, locality: i32);
-    /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
-    /// if supported; otherwise, it is a no-op.
-    /// Prefetches have no effect on the behavior of the program but can change its performance
-    /// characteristics.
-    ///
-    /// The `locality` argument must be a constant integer and is a temporal locality specifier
-    /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    pub fn prefetch_read_instruction<T>(data: *const T, locality: i32);
-    /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
-    /// if supported; otherwise, it is a no-op.
-    /// Prefetches have no effect on the behavior of the program but can change its performance
-    /// characteristics.
-    ///
-    /// The `locality` argument must be a constant integer and is a temporal locality specifier
-    /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    pub fn prefetch_write_instruction<T>(data: *const T, locality: i32);
-}
-
-extern "rust-intrinsic" {
     /// An atomic fence.
     ///
     /// The stabilized version of this intrinsic is available in
     /// [`atomic::fence`] by passing [`Ordering::SeqCst`]
     /// as the `order`.
-    pub fn atomic_fence();
+    pub fn atomic_fence_seqcst();
     /// An atomic fence.
     ///
     /// The stabilized version of this intrinsic is available in
     /// [`atomic::fence`] by passing [`Ordering::Acquire`]
     /// as the `order`.
-    pub fn atomic_fence_acq();
+    pub fn atomic_fence_acquire();
     /// An atomic fence.
     ///
     /// The stabilized version of this intrinsic is available in
     /// [`atomic::fence`] by passing [`Ordering::Release`]
     /// as the `order`.
-    pub fn atomic_fence_rel();
+    pub fn atomic_fence_release();
     /// An atomic fence.
     ///
     /// The stabilized version of this intrinsic is available in
@@ -661,7 +910,7 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available in
     /// [`atomic::compiler_fence`] by passing [`Ordering::SeqCst`]
     /// as the `order`.
-    pub fn atomic_singlethreadfence();
+    pub fn atomic_singlethreadfence_seqcst();
     /// A compiler-only memory barrier.
     ///
     /// Memory accesses will never be reordered across this barrier by the
@@ -672,7 +921,7 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available in
     /// [`atomic::compiler_fence`] by passing [`Ordering::Acquire`]
     /// as the `order`.
-    pub fn atomic_singlethreadfence_acq();
+    pub fn atomic_singlethreadfence_acquire();
     /// A compiler-only memory barrier.
     ///
     /// Memory accesses will never be reordered across this barrier by the
@@ -683,7 +932,7 @@ extern "rust-intrinsic" {
     /// The stabilized version of this intrinsic is available in
     /// [`atomic::compiler_fence`] by passing [`Ordering::Release`]
     /// as the `order`.
-    pub fn atomic_singlethreadfence_rel();
+    pub fn atomic_singlethreadfence_release();
     /// A compiler-only memory barrier.
     ///
     /// Memory accesses will never be reordered across this barrier by the
@@ -695,6 +944,70 @@ extern "rust-intrinsic" {
     /// [`atomic::compiler_fence`] by passing [`Ordering::AcqRel`]
     /// as the `order`.
     pub fn atomic_singlethreadfence_acqrel();
+}
+
+// These have been renamed.
+//
+// These are the aliases for the old names.
+// To be removed when stdarch and panic_unwind have been updated.
+#[cfg(not(bootstrap))]
+mod atomics {
+    pub use super::atomic_cxchg_acqrel_acquire as atomic_cxchg_acqrel;
+    pub use super::atomic_cxchg_acqrel_relaxed as atomic_cxchg_acqrel_failrelaxed;
+    pub use super::atomic_cxchg_acquire_acquire as atomic_cxchg_acq;
+    pub use super::atomic_cxchg_acquire_relaxed as atomic_cxchg_acq_failrelaxed;
+    pub use super::atomic_cxchg_relaxed_relaxed as atomic_cxchg_relaxed;
+    pub use super::atomic_cxchg_release_relaxed as atomic_cxchg_rel;
+    pub use super::atomic_cxchg_seqcst_acquire as atomic_cxchg_failacq;
+    pub use super::atomic_cxchg_seqcst_relaxed as atomic_cxchg_failrelaxed;
+    pub use super::atomic_cxchg_seqcst_seqcst as atomic_cxchg;
+    pub use super::atomic_store_seqcst as atomic_store;
+}
+
+#[cfg(not(bootstrap))]
+pub use atomics::*;
+
+extern "rust-intrinsic" {
+    /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
+    /// if supported; otherwise, it is a no-op.
+    /// Prefetches have no effect on the behavior of the program but can change its performance
+    /// characteristics.
+    ///
+    /// The `locality` argument must be a constant integer and is a temporal locality specifier
+    /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
+    ///
+    /// This intrinsic does not have a stable counterpart.
+    pub fn prefetch_read_data<T>(data: *const T, locality: i32);
+    /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
+    /// if supported; otherwise, it is a no-op.
+    /// Prefetches have no effect on the behavior of the program but can change its performance
+    /// characteristics.
+    ///
+    /// The `locality` argument must be a constant integer and is a temporal locality specifier
+    /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
+    ///
+    /// This intrinsic does not have a stable counterpart.
+    pub fn prefetch_write_data<T>(data: *const T, locality: i32);
+    /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
+    /// if supported; otherwise, it is a no-op.
+    /// Prefetches have no effect on the behavior of the program but can change its performance
+    /// characteristics.
+    ///
+    /// The `locality` argument must be a constant integer and is a temporal locality specifier
+    /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
+    ///
+    /// This intrinsic does not have a stable counterpart.
+    pub fn prefetch_read_instruction<T>(data: *const T, locality: i32);
+    /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
+    /// if supported; otherwise, it is a no-op.
+    /// Prefetches have no effect on the behavior of the program but can change its performance
+    /// characteristics.
+    ///
+    /// The `locality` argument must be a constant integer and is a temporal locality specifier
+    /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
+    ///
+    /// This intrinsic does not have a stable counterpart.
+    pub fn prefetch_write_instruction<T>(data: *const T, locality: i32);
 
     /// Magic intrinsic that derives its meaning from attributes
     /// attached to the function.
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index a66ecc35bbd..a68c6080e3a 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -2575,11 +2575,11 @@ unsafe fn atomic_store<T: Copy>(dst: *mut T, val: T, order: Ordering) {
     // SAFETY: the caller must uphold the safety contract for `atomic_store`.
     unsafe {
         match order {
-            Release => intrinsics::atomic_store_rel(dst, val),
             Relaxed => intrinsics::atomic_store_relaxed(dst, val),
-            SeqCst => intrinsics::atomic_store(dst, val),
+            Release => intrinsics::atomic_store_release(dst, val),
+            SeqCst => intrinsics::atomic_store_seqcst(dst, val),
             Acquire => panic!("there is no such thing as an acquire store"),
-            AcqRel => panic!("there is no such thing as an acquire/release store"),
+            AcqRel => panic!("there is no such thing as an acquire-release store"),
         }
     }
 }
@@ -2589,11 +2589,11 @@ unsafe fn atomic_load<T: Copy>(dst: *const T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_load`.
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_load_acq(dst),
             Relaxed => intrinsics::atomic_load_relaxed(dst),
-            SeqCst => intrinsics::atomic_load(dst),
+            Acquire => intrinsics::atomic_load_acquire(dst),
+            SeqCst => intrinsics::atomic_load_seqcst(dst),
             Release => panic!("there is no such thing as a release load"),
-            AcqRel => panic!("there is no such thing as an acquire/release load"),
+            AcqRel => panic!("there is no such thing as an acquire-release load"),
         }
     }
 }
@@ -2604,11 +2604,11 @@ unsafe fn atomic_swap<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_swap`.
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_xchg_acq(dst, val),
-            Release => intrinsics::atomic_xchg_rel(dst, val),
-            AcqRel => intrinsics::atomic_xchg_acqrel(dst, val),
             Relaxed => intrinsics::atomic_xchg_relaxed(dst, val),
-            SeqCst => intrinsics::atomic_xchg(dst, val),
+            Acquire => intrinsics::atomic_xchg_acquire(dst, val),
+            Release => intrinsics::atomic_xchg_release(dst, val),
+            AcqRel => intrinsics::atomic_xchg_acqrel(dst, val),
+            SeqCst => intrinsics::atomic_xchg_seqcst(dst, val),
         }
     }
 }
@@ -2620,11 +2620,11 @@ unsafe fn atomic_add<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_add`.
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_xadd_acq(dst, val),
-            Release => intrinsics::atomic_xadd_rel(dst, val),
-            AcqRel => intrinsics::atomic_xadd_acqrel(dst, val),
             Relaxed => intrinsics::atomic_xadd_relaxed(dst, val),
-            SeqCst => intrinsics::atomic_xadd(dst, val),
+            Acquire => intrinsics::atomic_xadd_acquire(dst, val),
+            Release => intrinsics::atomic_xadd_release(dst, val),
+            AcqRel => intrinsics::atomic_xadd_acqrel(dst, val),
+            SeqCst => intrinsics::atomic_xadd_seqcst(dst, val),
         }
     }
 }
@@ -2636,11 +2636,11 @@ unsafe fn atomic_sub<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_sub`.
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_xsub_acq(dst, val),
-            Release => intrinsics::atomic_xsub_rel(dst, val),
-            AcqRel => intrinsics::atomic_xsub_acqrel(dst, val),
             Relaxed => intrinsics::atomic_xsub_relaxed(dst, val),
-            SeqCst => intrinsics::atomic_xsub(dst, val),
+            Acquire => intrinsics::atomic_xsub_acquire(dst, val),
+            Release => intrinsics::atomic_xsub_release(dst, val),
+            AcqRel => intrinsics::atomic_xsub_acqrel(dst, val),
+            SeqCst => intrinsics::atomic_xsub_seqcst(dst, val),
         }
     }
 }
@@ -2657,16 +2657,22 @@ unsafe fn atomic_compare_exchange<T: Copy>(
     // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange`.
     let (val, ok) = unsafe {
         match (success, failure) {
-            (Acquire, Acquire) => intrinsics::atomic_cxchg_acq(dst, old, new),
-            (Release, Relaxed) => intrinsics::atomic_cxchg_rel(dst, old, new),
-            (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel(dst, old, new),
-            (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed(dst, old, new),
-            (SeqCst, SeqCst) => intrinsics::atomic_cxchg(dst, old, new),
-            (Acquire, Relaxed) => intrinsics::atomic_cxchg_acq_failrelaxed(dst, old, new),
-            (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_failrelaxed(dst, old, new),
-            (SeqCst, Relaxed) => intrinsics::atomic_cxchg_failrelaxed(dst, old, new),
-            (SeqCst, Acquire) => intrinsics::atomic_cxchg_failacq(dst, old, new),
-            (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"),
+            (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed_relaxed(dst, old, new),
+            //(Relaxed, Acquire) => intrinsics::atomic_cxchg_relaxed_acquire(dst, old, new),
+            //(Relaxed, SeqCst) => intrinsics::atomic_cxchg_relaxed_seqcst(dst, old, new),
+            (Acquire, Relaxed) => intrinsics::atomic_cxchg_acquire_relaxed(dst, old, new),
+            (Acquire, Acquire) => intrinsics::atomic_cxchg_acquire_acquire(dst, old, new),
+            //(Acquire, SeqCst) => intrinsics::atomic_cxchg_acquire_seqcst(dst, old, new),
+            (Release, Relaxed) => intrinsics::atomic_cxchg_release_relaxed(dst, old, new),
+            //(Release, Acquire) => intrinsics::atomic_cxchg_release_acquire(dst, old, new),
+            //(Release, SeqCst) => intrinsics::atomic_cxchg_release_seqcst(dst, old, new),
+            (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_relaxed(dst, old, new),
+            (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel_acquire(dst, old, new),
+            //(AcqRel, SeqCst) => intrinsics::atomic_cxchg_acqrel_seqcst(dst, old, new),
+            (SeqCst, Relaxed) => intrinsics::atomic_cxchg_seqcst_relaxed(dst, old, new),
+            (SeqCst, Acquire) => intrinsics::atomic_cxchg_seqcst_acquire(dst, old, new),
+            (SeqCst, SeqCst) => intrinsics::atomic_cxchg_seqcst_seqcst(dst, old, new),
+            (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
             (_, Release) => panic!("there is no such thing as a release failure ordering"),
             _ => panic!("a failure ordering can't be stronger than a success ordering"),
         }
@@ -2686,16 +2692,22 @@ unsafe fn atomic_compare_exchange_weak<T: Copy>(
     // SAFETY: the caller must uphold the safety contract for `atomic_compare_exchange_weak`.
     let (val, ok) = unsafe {
         match (success, failure) {
-            (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acq(dst, old, new),
-            (Release, Relaxed) => intrinsics::atomic_cxchgweak_rel(dst, old, new),
-            (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel(dst, old, new),
-            (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed(dst, old, new),
-            (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak(dst, old, new),
-            (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acq_failrelaxed(dst, old, new),
-            (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_failrelaxed(dst, old, new),
-            (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_failrelaxed(dst, old, new),
-            (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_failacq(dst, old, new),
-            (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"),
+            (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed_relaxed(dst, old, new),
+            //(Relaxed, Acquire) => intrinsics::atomic_cxchgweak_relaxed_acquire(dst, old, new),
+            //(Relaxed, SeqCst) => intrinsics::atomic_cxchgweak_relaxed_seqcst(dst, old, new),
+            (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acquire_relaxed(dst, old, new),
+            (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acquire_acquire(dst, old, new),
+            //(Acquire, SeqCst) => intrinsics::atomic_cxchgweak_acquire_seqcst(dst, old, new),
+            (Release, Relaxed) => intrinsics::atomic_cxchgweak_release_relaxed(dst, old, new),
+            //(Release, Acquire) => intrinsics::atomic_cxchgweak_release_acquire(dst, old, new),
+            //(Release, SeqCst) => intrinsics::atomic_cxchgweak_release_seqcst(dst, old, new),
+            (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_relaxed(dst, old, new),
+            (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel_acquire(dst, old, new),
+            //(AcqRel, SeqCst) => intrinsics::atomic_cxchgweak_acqrel_seqcst(dst, old, new),
+            (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_seqcst_relaxed(dst, old, new),
+            (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_seqcst_acquire(dst, old, new),
+            (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak_seqcst_seqcst(dst, old, new),
+            (_, AcqRel) => panic!("there is no such thing as an acquire-release failure ordering"),
             (_, Release) => panic!("there is no such thing as a release failure ordering"),
             _ => panic!("a failure ordering can't be stronger than a success ordering"),
         }
@@ -2709,11 +2721,11 @@ unsafe fn atomic_and<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_and`
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_and_acq(dst, val),
-            Release => intrinsics::atomic_and_rel(dst, val),
-            AcqRel => intrinsics::atomic_and_acqrel(dst, val),
             Relaxed => intrinsics::atomic_and_relaxed(dst, val),
-            SeqCst => intrinsics::atomic_and(dst, val),
+            Acquire => intrinsics::atomic_and_acquire(dst, val),
+            Release => intrinsics::atomic_and_release(dst, val),
+            AcqRel => intrinsics::atomic_and_acqrel(dst, val),
+            SeqCst => intrinsics::atomic_and_seqcst(dst, val),
         }
     }
 }
@@ -2724,11 +2736,11 @@ unsafe fn atomic_nand<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_nand`
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_nand_acq(dst, val),
-            Release => intrinsics::atomic_nand_rel(dst, val),
-            AcqRel => intrinsics::atomic_nand_acqrel(dst, val),
             Relaxed => intrinsics::atomic_nand_relaxed(dst, val),
-            SeqCst => intrinsics::atomic_nand(dst, val),
+            Acquire => intrinsics::atomic_nand_acquire(dst, val),
+            Release => intrinsics::atomic_nand_release(dst, val),
+            AcqRel => intrinsics::atomic_nand_acqrel(dst, val),
+            SeqCst => intrinsics::atomic_nand_seqcst(dst, val),
         }
     }
 }
@@ -2739,11 +2751,11 @@ unsafe fn atomic_or<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_or`
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_or_acq(dst, val),
-            Release => intrinsics::atomic_or_rel(dst, val),
+            SeqCst => intrinsics::atomic_or_seqcst(dst, val),
+            Acquire => intrinsics::atomic_or_acquire(dst, val),
+            Release => intrinsics::atomic_or_release(dst, val),
             AcqRel => intrinsics::atomic_or_acqrel(dst, val),
             Relaxed => intrinsics::atomic_or_relaxed(dst, val),
-            SeqCst => intrinsics::atomic_or(dst, val),
         }
     }
 }
@@ -2754,11 +2766,11 @@ unsafe fn atomic_xor<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_xor`
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_xor_acq(dst, val),
-            Release => intrinsics::atomic_xor_rel(dst, val),
+            SeqCst => intrinsics::atomic_xor_seqcst(dst, val),
+            Acquire => intrinsics::atomic_xor_acquire(dst, val),
+            Release => intrinsics::atomic_xor_release(dst, val),
             AcqRel => intrinsics::atomic_xor_acqrel(dst, val),
             Relaxed => intrinsics::atomic_xor_relaxed(dst, val),
-            SeqCst => intrinsics::atomic_xor(dst, val),
         }
     }
 }
@@ -2770,11 +2782,11 @@ unsafe fn atomic_max<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_max`
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_max_acq(dst, val),
-            Release => intrinsics::atomic_max_rel(dst, val),
-            AcqRel => intrinsics::atomic_max_acqrel(dst, val),
             Relaxed => intrinsics::atomic_max_relaxed(dst, val),
-            SeqCst => intrinsics::atomic_max(dst, val),
+            Acquire => intrinsics::atomic_max_acquire(dst, val),
+            Release => intrinsics::atomic_max_release(dst, val),
+            AcqRel => intrinsics::atomic_max_acqrel(dst, val),
+            SeqCst => intrinsics::atomic_max_seqcst(dst, val),
         }
     }
 }
@@ -2786,11 +2798,11 @@ unsafe fn atomic_min<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_min`
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_min_acq(dst, val),
-            Release => intrinsics::atomic_min_rel(dst, val),
-            AcqRel => intrinsics::atomic_min_acqrel(dst, val),
             Relaxed => intrinsics::atomic_min_relaxed(dst, val),
-            SeqCst => intrinsics::atomic_min(dst, val),
+            Acquire => intrinsics::atomic_min_acquire(dst, val),
+            Release => intrinsics::atomic_min_release(dst, val),
+            AcqRel => intrinsics::atomic_min_acqrel(dst, val),
+            SeqCst => intrinsics::atomic_min_seqcst(dst, val),
         }
     }
 }
@@ -2802,11 +2814,11 @@ unsafe fn atomic_umax<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_umax`
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_umax_acq(dst, val),
-            Release => intrinsics::atomic_umax_rel(dst, val),
-            AcqRel => intrinsics::atomic_umax_acqrel(dst, val),
             Relaxed => intrinsics::atomic_umax_relaxed(dst, val),
-            SeqCst => intrinsics::atomic_umax(dst, val),
+            Acquire => intrinsics::atomic_umax_acquire(dst, val),
+            Release => intrinsics::atomic_umax_release(dst, val),
+            AcqRel => intrinsics::atomic_umax_acqrel(dst, val),
+            SeqCst => intrinsics::atomic_umax_seqcst(dst, val),
         }
     }
 }
@@ -2818,11 +2830,11 @@ unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
     // SAFETY: the caller must uphold the safety contract for `atomic_umin`
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_umin_acq(dst, val),
-            Release => intrinsics::atomic_umin_rel(dst, val),
-            AcqRel => intrinsics::atomic_umin_acqrel(dst, val),
             Relaxed => intrinsics::atomic_umin_relaxed(dst, val),
-            SeqCst => intrinsics::atomic_umin(dst, val),
+            Acquire => intrinsics::atomic_umin_acquire(dst, val),
+            Release => intrinsics::atomic_umin_release(dst, val),
+            AcqRel => intrinsics::atomic_umin_acqrel(dst, val),
+            SeqCst => intrinsics::atomic_umin_seqcst(dst, val),
         }
     }
 }
@@ -2908,10 +2920,10 @@ pub fn fence(order: Ordering) {
     // SAFETY: using an atomic fence is safe.
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_fence_acq(),
-            Release => intrinsics::atomic_fence_rel(),
+            Acquire => intrinsics::atomic_fence_acquire(),
+            Release => intrinsics::atomic_fence_release(),
             AcqRel => intrinsics::atomic_fence_acqrel(),
-            SeqCst => intrinsics::atomic_fence(),
+            SeqCst => intrinsics::atomic_fence_seqcst(),
             Relaxed => panic!("there is no such thing as a relaxed fence"),
         }
     }
@@ -2990,10 +3002,10 @@ pub fn compiler_fence(order: Ordering) {
     // SAFETY: using an atomic fence is safe.
     unsafe {
         match order {
-            Acquire => intrinsics::atomic_singlethreadfence_acq(),
-            Release => intrinsics::atomic_singlethreadfence_rel(),
+            Acquire => intrinsics::atomic_singlethreadfence_acquire(),
+            Release => intrinsics::atomic_singlethreadfence_release(),
             AcqRel => intrinsics::atomic_singlethreadfence_acqrel(),
-            SeqCst => intrinsics::atomic_singlethreadfence(),
+            SeqCst => intrinsics::atomic_singlethreadfence_seqcst(),
             Relaxed => panic!("there is no such thing as a relaxed compiler fence"),
         }
     }
diff --git a/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs b/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs
index e9b28504a90..47d90b1856b 100644
--- a/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs
+++ b/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs
@@ -3,7 +3,7 @@
 #![no_core]
 
 extern "rust-intrinsic" {
-    fn atomic_xadd<T>(dst: *mut T, src: T) -> T;
+    fn atomic_xadd_seqcst<T>(dst: *mut T, src: T) -> T;
 }
 
 #[lang = "sized"]
@@ -17,50 +17,50 @@ impl<T: ?Sized> Copy for *mut T {}
 
 #[cfg(target_has_atomic = "8")]
 pub unsafe fn atomic_u8(x: *mut u8) {
-    atomic_xadd(x, 1);
-    atomic_xadd(x, 1);
+    atomic_xadd_seqcst(x, 1);
+    atomic_xadd_seqcst(x, 1);
 }
 #[cfg(target_has_atomic = "8")]
 pub unsafe fn atomic_i8(x: *mut i8) {
-    atomic_xadd(x, 1);
+    atomic_xadd_seqcst(x, 1);
 }
 #[cfg(target_has_atomic = "16")]
 pub unsafe fn atomic_u16(x: *mut u16) {
-    atomic_xadd(x, 1);
+    atomic_xadd_seqcst(x, 1);
 }
 #[cfg(target_has_atomic = "16")]
 pub unsafe fn atomic_i16(x: *mut i16) {
-    atomic_xadd(x, 1);
+    atomic_xadd_seqcst(x, 1);
 }
 #[cfg(target_has_atomic = "32")]
 pub unsafe fn atomic_u32(x: *mut u32) {
-    atomic_xadd(x, 1);
+    atomic_xadd_seqcst(x, 1);
 }
 #[cfg(target_has_atomic = "32")]
 pub unsafe fn atomic_i32(x: *mut i32) {
-    atomic_xadd(x, 1);
+    atomic_xadd_seqcst(x, 1);
 }
 #[cfg(target_has_atomic = "64")]
 pub unsafe fn atomic_u64(x: *mut u64) {
-    atomic_xadd(x, 1);
+    atomic_xadd_seqcst(x, 1);
 }
 #[cfg(target_has_atomic = "64")]
 pub unsafe fn atomic_i64(x: *mut i64) {
-    atomic_xadd(x, 1);
+    atomic_xadd_seqcst(x, 1);
 }
 #[cfg(target_has_atomic = "128")]
 pub unsafe fn atomic_u128(x: *mut u128) {
-    atomic_xadd(x, 1);
+    atomic_xadd_seqcst(x, 1);
 }
 #[cfg(target_has_atomic = "128")]
 pub unsafe fn atomic_i128(x: *mut i128) {
-    atomic_xadd(x, 1);
+    atomic_xadd_seqcst(x, 1);
 }
 #[cfg(target_has_atomic = "ptr")]
 pub unsafe fn atomic_usize(x: *mut usize) {
-    atomic_xadd(x, 1);
+    atomic_xadd_seqcst(x, 1);
 }
 #[cfg(target_has_atomic = "ptr")]
 pub unsafe fn atomic_isize(x: *mut isize) {
-    atomic_xadd(x, 1);
+    atomic_xadd_seqcst(x, 1);
 }
diff --git a/src/test/ui/argument-suggestions/basic.stderr b/src/test/ui/argument-suggestions/basic.stderr
index dd4812b5b25..c495ad6b842 100644
--- a/src/test/ui/argument-suggestions/basic.stderr
+++ b/src/test/ui/argument-suggestions/basic.stderr
@@ -16,7 +16,7 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/basic.rs:21:5
    |
 LL |     extra("");
-   |     ^^^^^ -- argument unexpected
+   |     ^^^^^ -- argument of type `&'static str` unexpected
    |
 note: function defined here
   --> $DIR/basic.rs:14:4
diff --git a/src/test/ui/argument-suggestions/extra_arguments.stderr b/src/test/ui/argument-suggestions/extra_arguments.stderr
index 9b63f9bcbfa..32b1e15737a 100644
--- a/src/test/ui/argument-suggestions/extra_arguments.stderr
+++ b/src/test/ui/argument-suggestions/extra_arguments.stderr
@@ -2,7 +2,7 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/extra_arguments.rs:7:3
    |
 LL |   empty("");
-   |   ^^^^^ -- argument unexpected
+   |   ^^^^^ -- argument of type `&'static str` unexpected
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:1:4
@@ -18,7 +18,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:9:3
    |
 LL |   one_arg(1, 1);
-   |   ^^^^^^^    - argument unexpected
+   |   ^^^^^^^    - argument of type `{integer}` unexpected
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
@@ -34,7 +34,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/extra_arguments.rs:10:3
    |
 LL |   one_arg(1, "");
-   |   ^^^^^^^    -- argument unexpected
+   |   ^^^^^^^    -- argument of type `&'static str` unexpected
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
@@ -50,9 +50,9 @@ error[E0061]: this function takes 1 argument but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:11:3
    |
 LL |   one_arg(1, "", 1.0);
-   |   ^^^^^^^    --  --- argument unexpected
+   |   ^^^^^^^    --  --- argument of type `{float}` unexpected
    |              |
-   |              argument unexpected
+   |              argument of type `&'static str` unexpected
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:2:4
@@ -68,7 +68,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:13:3
    |
 LL |   two_arg_same(1, 1, 1);
-   |   ^^^^^^^^^^^^       - argument unexpected
+   |   ^^^^^^^^^^^^       - argument of type `{integer}` unexpected
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:3:4
@@ -84,7 +84,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:14:3
    |
 LL |   two_arg_same(1, 1, 1.0);
-   |   ^^^^^^^^^^^^       --- argument unexpected
+   |   ^^^^^^^^^^^^       --- argument of type `{float}` unexpected
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:3:4
@@ -100,7 +100,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:16:3
    |
 LL |   two_arg_diff(1, 1, "");
-   |   ^^^^^^^^^^^^    - argument of type `&str` unexpected
+   |   ^^^^^^^^^^^^    - argument of type `{integer}` unexpected
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:4:4
@@ -116,7 +116,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:17:3
    |
 LL |   two_arg_diff(1, "", "");
-   |   ^^^^^^^^^^^^        -- argument unexpected
+   |   ^^^^^^^^^^^^        -- argument of type `&'static str` unexpected
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:4:4
@@ -132,9 +132,9 @@ error[E0061]: this function takes 2 arguments but 4 arguments were supplied
   --> $DIR/extra_arguments.rs:18:3
    |
 LL |   two_arg_diff(1, 1, "", "");
-   |   ^^^^^^^^^^^^    -      -- argument unexpected
+   |   ^^^^^^^^^^^^    -      -- argument of type `&'static str` unexpected
    |                   |
-   |                   argument of type `&str` unexpected
+   |                   argument of type `{integer}` unexpected
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:4:4
@@ -150,9 +150,9 @@ error[E0061]: this function takes 2 arguments but 4 arguments were supplied
   --> $DIR/extra_arguments.rs:19:3
    |
 LL |   two_arg_diff(1, "", 1, "");
-   |   ^^^^^^^^^^^^        -  -- argument unexpected
+   |   ^^^^^^^^^^^^        -  -- argument of type `&'static str` unexpected
    |                       |
-   |                       argument unexpected
+   |                       argument of type `{integer}` unexpected
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:4:4
@@ -168,7 +168,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:22:3
    |
 LL |   two_arg_same(1, 1,     "");
-   |   ^^^^^^^^^^^^           -- argument unexpected
+   |   ^^^^^^^^^^^^           -- argument of type `&'static str` unexpected
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:3:4
@@ -184,7 +184,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/extra_arguments.rs:23:3
    |
 LL |   two_arg_diff(1, 1,     "");
-   |   ^^^^^^^^^^^^    - argument of type `&str` unexpected
+   |   ^^^^^^^^^^^^    - argument of type `{integer}` unexpected
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:4:4
@@ -203,7 +203,7 @@ LL |   two_arg_same(
    |   ^^^^^^^^^^^^
 ...
 LL |     ""
-   |     -- argument unexpected
+   |     -- argument of type `&'static str` unexpected
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:3:4
@@ -222,7 +222,7 @@ LL |   two_arg_diff(
    |   ^^^^^^^^^^^^
 LL |     1,
 LL |     1,
-   |     - argument of type `&str` unexpected
+   |     - argument of type `{integer}` unexpected
    |
 note: function defined here
   --> $DIR/extra_arguments.rs:4:4
diff --git a/src/test/ui/argument-suggestions/issue-97484.stderr b/src/test/ui/argument-suggestions/issue-97484.stderr
index 2af24d521f3..9589e919c0a 100644
--- a/src/test/ui/argument-suggestions/issue-97484.stderr
+++ b/src/test/ui/argument-suggestions/issue-97484.stderr
@@ -2,21 +2,20 @@ error[E0061]: this function takes 4 arguments but 7 arguments were supplied
   --> $DIR/issue-97484.rs:12:5
    |
 LL |     foo(&&A, B, C, D, E, F, G);
-   |     ^^^      -  -        - argument unexpected
+   |     ^^^      -  -        - argument of type `F` unexpected
    |              |  |
-   |              |  argument of type `&E` unexpected
-   |              argument of type `D` unexpected
+   |              |  argument of type `C` unexpected
+   |              argument of type `B` unexpected
    |
 note: function defined here
   --> $DIR/issue-97484.rs:9:4
    |
 LL | fn foo(a: &A, d: D, e: &E, g: G) {}
    |    ^^^ -----  ----  -----  ----
-help: consider removing the ``
-   |
-LL -     foo(&&A, B, C, D, E, F, G);
-LL +     foo(&&A, B, C, D, E, F, G);
+help: consider borrowing here
    |
+LL |     foo(&&A, B, C, D, &E, F, G);
+   |                       ~~
 help: remove the extra arguments
    |
 LL |     foo(&&A, D, /* &E */, G);
diff --git a/src/test/ui/argument-suggestions/mixed_cases.stderr b/src/test/ui/argument-suggestions/mixed_cases.stderr
index 3fe4473a594..a52a30d7884 100644
--- a/src/test/ui/argument-suggestions/mixed_cases.stderr
+++ b/src/test/ui/argument-suggestions/mixed_cases.stderr
@@ -2,7 +2,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/mixed_cases.rs:10:3
    |
 LL |   two_args(1, "", X {});
-   |   ^^^^^^^^    --  ---- argument unexpected
+   |   ^^^^^^^^    --  ---- argument of type `X` unexpected
    |               |
    |               expected `f32`, found `&str`
    |
@@ -20,9 +20,9 @@ error[E0061]: this function takes 3 arguments but 4 arguments were supplied
   --> $DIR/mixed_cases.rs:11:3
    |
 LL |   three_args(1, "", X {}, "");
-   |   ^^^^^^^^^^    --  ----  -- argument unexpected
+   |   ^^^^^^^^^^    --  ----  -- argument of type `&'static str` unexpected
    |                 |   |
-   |                 |   argument of type `&str` unexpected
+   |                 |   argument of type `X` unexpected
    |                 an argument of type `f32` is missing
    |
 note: function defined here
@@ -58,7 +58,7 @@ error[E0308]: arguments to this function are incorrect
   --> $DIR/mixed_cases.rs:17:3
    |
 LL |   three_args(1, "", X {});
-   |   ^^^^^^^^^^    --  ---- argument of type `&str` unexpected
+   |   ^^^^^^^^^^    --  ---- argument of type `X` unexpected
    |                 |
    |                 an argument of type `f32` is missing
    |
diff --git a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
index f1dcd34066d..f40e6585b38 100644
--- a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
+++ b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `String: Copy` is not satisfied
 LL |         Box::new(AssocNoCopy)
    |         ^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
    |
-   = note: required for the cast to the object type `dyn Bar<Assoc = <AssocNoCopy as Thing>::Out::{opaque#0}>`
+   = note: required for the cast from `AssocNoCopy` to the object type `dyn Bar<Assoc = <AssocNoCopy as Thing>::Out::{opaque#0}>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr
index 521907a6044..bed63a5e6df 100644
--- a/src/test/ui/associated-types/associated-types-eq-3.stderr
+++ b/src/test/ui/associated-types/associated-types-eq-3.stderr
@@ -41,7 +41,7 @@ note: expected this to be `Bar`
    |
 LL |     type A = usize;
    |              ^^^^^
-   = note: required for the cast to the object type `dyn Foo<A = Bar>`
+   = note: required for the cast from `isize` to the object type `dyn Foo<A = Bar>`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr
index 9f1abf2a6c4..dbd9a44ed97 100644
--- a/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr
+++ b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr
@@ -4,7 +4,7 @@ error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::It
 LL |     let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
    |                                           ^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32`
    |
-   = note: required for the cast to the object type `dyn Iterator<Item = u32, Item = i32>`
+   = note: required for the cast from `std::vec::IntoIter<u32>` to the object type `dyn Iterator<Item = u32, Item = i32>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/issue-65774-1.stderr b/src/test/ui/associated-types/issue-65774-1.stderr
index e468a1b3ba4..419de689c52 100644
--- a/src/test/ui/associated-types/issue-65774-1.stderr
+++ b/src/test/ui/associated-types/issue-65774-1.stderr
@@ -23,7 +23,7 @@ note: required because of the requirements on the impl of `MyDisplay` for `&mut
    |
 LL | impl<'a, T: MyDisplay> MyDisplay for &'a mut T { }
    |                        ^^^^^^^^^     ^^^^^^^^^
-   = note: required for the cast to the object type `dyn MyDisplay`
+   = note: required for the cast from `&mut T` to the object type `dyn MyDisplay`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/associated-types/issue-65774-2.stderr b/src/test/ui/associated-types/issue-65774-2.stderr
index 4cef4db4698..c22302cdc26 100644
--- a/src/test/ui/associated-types/issue-65774-2.stderr
+++ b/src/test/ui/associated-types/issue-65774-2.stderr
@@ -18,7 +18,7 @@ LL |         writer.my_write(valref)
    |                         ^^^^^^ the trait `MyDisplay` is not implemented for `T`
    |
    = help: the trait `MyDisplay` is implemented for `&'a mut T`
-   = note: required for the cast to the object type `dyn MyDisplay`
+   = note: required for the cast from `T` to the object type `dyn MyDisplay`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
index e0818337d20..e5887689690 100644
--- a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
+++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
@@ -37,7 +37,7 @@ error[E0271]: type mismatch resolving `<impl Future<Output = u8> as Future>::Out
 LL |     let _: &dyn Future<Output = ()> = &block;
    |                                       ^^^^^^ expected `()`, found `u8`
    |
-   = note: required for the cast to the object type `dyn Future<Output = ()>`
+   = note: required for the cast from `impl Future<Output = u8>` to the object type `dyn Future<Output = ()>`
 
 error[E0308]: mismatched types
   --> $DIR/async-block-control-flow-static-semantics.rs:12:43
@@ -53,7 +53,7 @@ error[E0271]: type mismatch resolving `<impl Future<Output = u8> as Future>::Out
 LL |     let _: &dyn Future<Output = ()> = &block;
    |                                       ^^^^^^ expected `()`, found `u8`
    |
-   = note: required for the cast to the object type `dyn Future<Output = ()>`
+   = note: required for the cast from `impl Future<Output = u8>` to the object type `dyn Future<Output = ()>`
 
 error[E0308]: mismatched types
   --> $DIR/async-block-control-flow-static-semantics.rs:47:44
diff --git a/src/test/ui/async-await/issue-86507.stderr b/src/test/ui/async-await/issue-86507.stderr
index 5bbc20359c6..0e21dba980d 100644
--- a/src/test/ui/async-await/issue-86507.stderr
+++ b/src/test/ui/async-await/issue-86507.stderr
@@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
    |
 LL |                     let x = x;
    |                             ^ has type `&T` which is not `Send`, because `T` is not `Sync`
-   = note: required for the cast to the object type `dyn Future<Output = ()> + Send`
+   = note: required for the cast from `impl Future<Output = ()>` to the object type `dyn Future<Output = ()> + Send`
 help: consider further restricting this bound
    |
 LL |     fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
diff --git a/src/test/ui/binop/binop-move-semantics.stderr b/src/test/ui/binop/binop-move-semantics.stderr
index 2cd6d1abfdc..695b01d5ee3 100644
--- a/src/test/ui/binop/binop-move-semantics.stderr
+++ b/src/test/ui/binop/binop-move-semantics.stderr
@@ -63,8 +63,20 @@ LL |     use_mut(n); use_imm(m);
 error[E0507]: cannot move out of `*m` which is behind a mutable reference
   --> $DIR/binop-move-semantics.rs:30:5
    |
-LL |     *m
-   |     ^^ move occurs because `*m` has type `T`, which does not implement the `Copy` trait
+LL |       *m
+   |       -^
+   |       |
+   |  _____move occurs because `*m` has type `T`, which does not implement the `Copy` trait
+   | |
+LL | |     +
+LL | |     *n;
+   | |______- `*m` moved due to usage in operator
+   |
+note: calling this operator moves the left-hand side
+  --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+   |
+LL |     fn add(self, rhs: Rhs) -> Self::Output;
+   |            ^^^^
 
 error[E0507]: cannot move out of `*n` which is behind a shared reference
   --> $DIR/binop-move-semantics.rs:32:5
diff --git a/src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr b/src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr
index 0866f54b9fa..c99c0f77982 100644
--- a/src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr
+++ b/src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr
@@ -2,7 +2,7 @@ error[E0594]: cannot assign to `**t1`, which is behind a `&` reference
   --> $DIR/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs:9:5
    |
 LL |     let t1 = t0;
-   |         -- help: consider changing this to be a mutable reference: `&mut &mut isize`
+   |         -- consider changing this binding's type to be: `&mut &mut isize`
 LL |     let p: &isize = &**t0;
 LL |     **t1 = 22;
    |     ^^^^^^^^^ `t1` is a `&` reference, so the data it refers to cannot be written
diff --git a/src/test/ui/borrowck/issue-85765.rs b/src/test/ui/borrowck/issue-85765.rs
index 2b1ab2f7050..1598cd5d3c8 100644
--- a/src/test/ui/borrowck/issue-85765.rs
+++ b/src/test/ui/borrowck/issue-85765.rs
@@ -1,7 +1,7 @@
 fn main() {
     let mut test = Vec::new();
     let rofl: &Vec<Vec<i32>> = &mut test;
-    //~^ HELP consider changing this to be a mutable reference
+    //~^ NOTE consider changing this binding's type to be
     rofl.push(Vec::new());
     //~^ ERROR cannot borrow `*rofl` as mutable, as it is behind a `&` reference
     //~| NOTE `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
@@ -15,14 +15,14 @@ fn main() {
 
     #[rustfmt::skip]
     let x: &usize = &mut{0};
-    //~^ HELP consider changing this to be a mutable reference
+    //~^ NOTE consider changing this binding's type to be
     *x = 1;
     //~^ ERROR cannot assign to `*x`, which is behind a `&` reference
     //~| NOTE `x` is a `&` reference, so the data it refers to cannot be written
 
     #[rustfmt::skip]
     let y: &usize = &mut(0);
-    //~^ HELP consider changing this to be a mutable reference
+    //~^ NOTE consider changing this binding's type to be
     *y = 1;
     //~^ ERROR cannot assign to `*y`, which is behind a `&` reference
     //~| NOTE `y` is a `&` reference, so the data it refers to cannot be written
diff --git a/src/test/ui/borrowck/issue-85765.stderr b/src/test/ui/borrowck/issue-85765.stderr
index 80acaa7d21c..13033962142 100644
--- a/src/test/ui/borrowck/issue-85765.stderr
+++ b/src/test/ui/borrowck/issue-85765.stderr
@@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*rofl` as mutable, as it is behind a `&` reference
   --> $DIR/issue-85765.rs:5:5
    |
 LL |     let rofl: &Vec<Vec<i32>> = &mut test;
-   |         ---- help: consider changing this to be a mutable reference: `&mut Vec<Vec<i32>>`
+   |         ---- consider changing this binding's type to be: `&mut Vec<Vec<i32>>`
 LL |
 LL |     rofl.push(Vec::new());
    |     ^^^^^^^^^^^^^^^^^^^^^ `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
@@ -20,7 +20,7 @@ error[E0594]: cannot assign to `*x`, which is behind a `&` reference
   --> $DIR/issue-85765.rs:19:5
    |
 LL |     let x: &usize = &mut{0};
-   |         - help: consider changing this to be a mutable reference: `&mut usize`
+   |         - consider changing this binding's type to be: `&mut usize`
 LL |
 LL |     *x = 1;
    |     ^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written
@@ -29,7 +29,7 @@ error[E0594]: cannot assign to `*y`, which is behind a `&` reference
   --> $DIR/issue-85765.rs:26:5
    |
 LL |     let y: &usize = &mut(0);
-   |         - help: consider changing this to be a mutable reference: `&mut usize`
+   |         - consider changing this binding's type to be: `&mut usize`
 LL |
 LL |     *y = 1;
    |     ^^^^^^ `y` is a `&` reference, so the data it refers to cannot be written
diff --git a/src/test/ui/borrowck/issue-91206.rs b/src/test/ui/borrowck/issue-91206.rs
index 3b1fbf4b699..67407c1eae3 100644
--- a/src/test/ui/borrowck/issue-91206.rs
+++ b/src/test/ui/borrowck/issue-91206.rs
@@ -9,7 +9,8 @@ impl TestClient {
 fn main() {
     let client = TestClient;
     let inner = client.get_inner_ref();
-    //~^ HELP consider changing this to be a mutable reference
+    //~^ NOTE consider changing this binding's type to be
     inner.clear();
     //~^ ERROR cannot borrow `*inner` as mutable, as it is behind a `&` reference [E0596]
+    //~| NOTE `inner` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 }
diff --git a/src/test/ui/borrowck/issue-91206.stderr b/src/test/ui/borrowck/issue-91206.stderr
index 535d247452a..12d8d27c5f0 100644
--- a/src/test/ui/borrowck/issue-91206.stderr
+++ b/src/test/ui/borrowck/issue-91206.stderr
@@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*inner` as mutable, as it is behind a `&` reference
   --> $DIR/issue-91206.rs:13:5
    |
 LL |     let inner = client.get_inner_ref();
-   |         ----- help: consider changing this to be a mutable reference: `&mut Vec<usize>`
+   |         ----- consider changing this binding's type to be: `&mut Vec<usize>`
 LL |
 LL |     inner.clear();
    |     ^^^^^^^^^^^^^ `inner` is a `&` reference, so the data it refers to cannot be borrowed as mutable
diff --git a/src/test/ui/borrowck/issue-92015.stderr b/src/test/ui/borrowck/issue-92015.stderr
index 32a65d3b5bb..62b1183e71b 100644
--- a/src/test/ui/borrowck/issue-92015.stderr
+++ b/src/test/ui/borrowck/issue-92015.stderr
@@ -2,7 +2,7 @@ error[E0594]: cannot assign to `*foo`, which is behind a `&` reference
   --> $DIR/issue-92015.rs:6:5
    |
 LL |     let foo = Some(&0).unwrap();
-   |         --- help: consider changing this to be a mutable reference: `&mut i32`
+   |         --- consider changing this binding's type to be: `&mut i32`
 LL |     *foo = 1;
    |     ^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
 
diff --git a/src/test/ui/borrowck/suggest-as-ref-on-mut-closure.rs b/src/test/ui/borrowck/suggest-as-ref-on-mut-closure.rs
new file mode 100644
index 00000000000..1dcf0461879
--- /dev/null
+++ b/src/test/ui/borrowck/suggest-as-ref-on-mut-closure.rs
@@ -0,0 +1,16 @@
+// This is not exactly right, yet.
+
+// Ideally we should be suggesting `as_mut` for the first case,
+// and suggesting to change `as_ref` to `as_mut` in the second.
+
+fn x(cb: &mut Option<&mut dyn FnMut()>) {
+    cb.map(|cb| cb());
+    //~^ ERROR cannot move out of `*cb` which is behind a mutable reference
+}
+
+fn x2(cb: &mut Option<&mut dyn FnMut()>) {
+    cb.as_ref().map(|cb| cb());
+    //~^ ERROR cannot borrow `*cb` as mutable, as it is behind a `&` reference
+}
+
+fn main() {}
diff --git a/src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr b/src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr
new file mode 100644
index 00000000000..af26169c806
--- /dev/null
+++ b/src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr
@@ -0,0 +1,31 @@
+error[E0507]: cannot move out of `*cb` which is behind a mutable reference
+  --> $DIR/suggest-as-ref-on-mut-closure.rs:7:5
+   |
+LL |     cb.map(|cb| cb());
+   |     ^^^--------------
+   |     |  |
+   |     |  `*cb` moved due to this method call
+   |     move occurs because `*cb` has type `Option<&mut dyn FnMut()>`, which does not implement the `Copy` trait
+   |
+note: this function takes ownership of the receiver `self`, which moves `*cb`
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+   |
+LL |     pub const fn map<U, F>(self, f: F) -> Option<U>
+   |                            ^^^^
+help: consider calling `.as_ref()` to borrow the type's contents
+   |
+LL |     cb.as_ref().map(|cb| cb());
+   |        +++++++++
+
+error[E0596]: cannot borrow `*cb` as mutable, as it is behind a `&` reference
+  --> $DIR/suggest-as-ref-on-mut-closure.rs:12:26
+   |
+LL |     cb.as_ref().map(|cb| cb());
+   |                      --  ^^ `cb` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+   |                      |
+   |                      consider changing this binding's type to be: `&mut &mut dyn FnMut()`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0507, E0596.
+For more information about an error, try `rustc --explain E0507`.
diff --git a/src/test/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr b/src/test/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr
index 3350d1efb53..980da536034 100644
--- a/src/test/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr
+++ b/src/test/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied
 LL |     /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
    |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
    |
-   = note: required for the cast to the object type `dyn std::error::Error`
+   = note: required for the cast from `()` to the object type `dyn std::error::Error`
 
 error[E0277]: the trait bound `(): std::error::Error` is not satisfied
   --> $DIR/coerce-issue-49593-box-never-windows.rs:23:49
@@ -12,7 +12,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied
 LL |     /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
    |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
    |
-   = note: required for the cast to the object type `(dyn std::error::Error + 'static)`
+   = note: required for the cast from `()` to the object type `(dyn std::error::Error + 'static)`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr b/src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr
index fcd2d7f78ff..322681b97bc 100644
--- a/src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr
+++ b/src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied
 LL |     /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
    |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
    |
-   = note: required for the cast to the object type `dyn std::error::Error`
+   = note: required for the cast from `()` to the object type `dyn std::error::Error`
 
 error[E0277]: the trait bound `(): std::error::Error` is not satisfied
   --> $DIR/coerce-issue-49593-box-never.rs:23:49
@@ -12,7 +12,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied
 LL |     /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
    |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
    |
-   = note: required for the cast to the object type `(dyn std::error::Error + 'static)`
+   = note: required for the cast from `()` to the object type `(dyn std::error::Error + 'static)`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr
index 60dc96f675a..da85b2059f0 100644
--- a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr
+++ b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr
@@ -7,7 +7,7 @@ LL |     foo(&10_u32);
    |     required by a bound introduced by this call
    |
    = help: the trait `Trait<2_u8>` is implemented for `u32`
-   = note: required for the cast to the object type `dyn Trait`
+   = note: required for the cast from `u32` to the object type `dyn Trait`
 
 error[E0277]: the trait bound `bool: Traitor<{_: u8}>` is not satisfied
   --> $DIR/trait_objects_fail.rs:28:9
@@ -18,7 +18,7 @@ LL |     bar(&true);
    |     required by a bound introduced by this call
    |
    = help: the trait `Traitor<2_u8, 3_u8>` is implemented for `bool`
-   = note: required for the cast to the object type `dyn Traitor<{_: u8}>`
+   = note: required for the cast from `bool` to the object type `dyn Traitor<{_: u8}>`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/custom_test_frameworks/mismatch.stderr b/src/test/ui/custom_test_frameworks/mismatch.stderr
index e848ddc55b7..61061ae529d 100644
--- a/src/test/ui/custom_test_frameworks/mismatch.stderr
+++ b/src/test/ui/custom_test_frameworks/mismatch.stderr
@@ -6,7 +6,7 @@ LL | #[test]
 LL | fn wrong_kind(){}
    | ^^^^^^^^^^^^^^^^^ the trait `Testable` is not implemented for `TestDescAndFn`
    |
-   = note: required for the cast to the object type `dyn Testable`
+   = note: required for the cast from `TestDescAndFn` to the object type `dyn Testable`
    = note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
diff --git a/src/test/ui/dst/dst-bad-coerce1.stderr b/src/test/ui/dst/dst-bad-coerce1.stderr
index 121c76a01a5..594acff853a 100644
--- a/src/test/ui/dst/dst-bad-coerce1.stderr
+++ b/src/test/ui/dst/dst-bad-coerce1.stderr
@@ -15,7 +15,7 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied
 LL |     let f3: &Fat<dyn Bar> = f2;
    |                             ^^ the trait `Bar` is not implemented for `Foo`
    |
-   = note: required for the cast to the object type `dyn Bar`
+   = note: required for the cast from `Foo` to the object type `dyn Bar`
 
 error[E0308]: mismatched types
   --> $DIR/dst-bad-coerce1.rs:28:27
@@ -34,7 +34,7 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied
 LL |     let f3: &(dyn Bar,) = f2;
    |                           ^^ the trait `Bar` is not implemented for `Foo`
    |
-   = note: required for the cast to the object type `dyn Bar`
+   = note: required for the cast from `Foo` to the object type `dyn Bar`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/dst/dst-object-from-unsized-type.stderr b/src/test/ui/dst/dst-object-from-unsized-type.stderr
index 5bd47736626..e24c96ebed6 100644
--- a/src/test/ui/dst/dst-object-from-unsized-type.stderr
+++ b/src/test/ui/dst/dst-object-from-unsized-type.stderr
@@ -6,7 +6,7 @@ LL | fn test1<T: ?Sized + Foo>(t: &T) {
 LL |     let u: &dyn Foo = t;
    |                       ^ doesn't have a size known at compile-time
    |
-   = note: required for the cast to the object type `dyn Foo`
+   = note: required for the cast from `T` to the object type `dyn Foo`
 help: consider removing the `?Sized` bound to make the type parameter `Sized`
    |
 LL - fn test1<T: ?Sized + Foo>(t: &T) {
@@ -21,7 +21,7 @@ LL | fn test2<T: ?Sized + Foo>(t: &T) {
 LL |     let v: &dyn Foo = t as &dyn Foo;
    |                       ^ doesn't have a size known at compile-time
    |
-   = note: required for the cast to the object type `dyn Foo`
+   = note: required for the cast from `T` to the object type `dyn Foo`
 help: consider removing the `?Sized` bound to make the type parameter `Sized`
    |
 LL - fn test2<T: ?Sized + Foo>(t: &T) {
@@ -35,7 +35,7 @@ LL |     let _: &[&dyn Foo] = &["hi"];
    |                            ^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
-   = note: required for the cast to the object type `dyn Foo`
+   = note: required for the cast from `str` to the object type `dyn Foo`
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
   --> $DIR/dst-object-from-unsized-type.rs:23:23
@@ -44,7 +44,7 @@ LL |     let _: &dyn Foo = x as &dyn Foo;
    |                       ^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `[u8]`
-   = note: required for the cast to the object type `dyn Foo`
+   = note: required for the cast from `[u8]` to the object type `dyn Foo`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/error-codes/E0057.stderr b/src/test/ui/error-codes/E0057.stderr
index 3697b5fcf15..2307f52c93b 100644
--- a/src/test/ui/error-codes/E0057.stderr
+++ b/src/test/ui/error-codes/E0057.stderr
@@ -18,7 +18,7 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/E0057.rs:5:13
    |
 LL |     let c = f(2, 3);
-   |             ^    - argument unexpected
+   |             ^    - argument of type `{integer}` unexpected
    |
 note: closure defined here
   --> $DIR/E0057.rs:2:13
diff --git a/src/test/ui/generic-associated-types/issue-79422.extended.stderr b/src/test/ui/generic-associated-types/issue-79422.extended.stderr
index 9478fc89792..9bcbd747168 100644
--- a/src/test/ui/generic-associated-types/issue-79422.extended.stderr
+++ b/src/test/ui/generic-associated-types/issue-79422.extended.stderr
@@ -27,7 +27,7 @@ LL |     type VRefCont<'a> = &'a V where Self: 'a;
    |                         ^^^^^
    = note: expected trait object `(dyn RefCont<'_, u8> + 'static)`
                  found reference `&u8`
-   = note: required for the cast to the object type `dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>`
+   = note: required for the cast from `BTreeMap<u8, u8>` to the object type `dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/intrinsics/auxiliary/cci_intrinsic.rs b/src/test/ui/intrinsics/auxiliary/cci_intrinsic.rs
index f65f359875b..f3b9d569ce3 100644
--- a/src/test/ui/intrinsics/auxiliary/cci_intrinsic.rs
+++ b/src/test/ui/intrinsics/auxiliary/cci_intrinsic.rs
@@ -2,13 +2,13 @@
 
 pub mod rusti {
     extern "rust-intrinsic" {
-        pub fn atomic_xchg<T>(dst: *mut T, src: T) -> T;
+        pub fn atomic_xchg_seqcst<T>(dst: *mut T, src: T) -> T;
     }
 }
 
 #[inline(always)]
-pub fn atomic_xchg(dst: *mut isize, src: isize) -> isize {
+pub fn atomic_xchg_seqcst(dst: *mut isize, src: isize) -> isize {
     unsafe {
-        rusti::atomic_xchg(dst, src)
+        rusti::atomic_xchg_seqcst(dst, src)
     }
 }
diff --git a/src/test/ui/intrinsics/intrinsic-atomics-cc.rs b/src/test/ui/intrinsics/intrinsic-atomics-cc.rs
index 52e891da9ba..ce3fa7b0c05 100644
--- a/src/test/ui/intrinsics/intrinsic-atomics-cc.rs
+++ b/src/test/ui/intrinsics/intrinsic-atomics-cc.rs
@@ -3,10 +3,10 @@
 
 
 extern crate cci_intrinsic;
-use cci_intrinsic::atomic_xchg;
+use cci_intrinsic::atomic_xchg_seqcst;
 
 pub fn main() {
     let mut x = 1;
-    atomic_xchg(&mut x, 5);
+    atomic_xchg_seqcst(&mut x, 5);
     assert_eq!(x, 5);
 }
diff --git a/src/test/ui/intrinsics/intrinsic-atomics.rs b/src/test/ui/intrinsics/intrinsic-atomics.rs
index c6e48e8b5af..b17f4347be3 100644
--- a/src/test/ui/intrinsics/intrinsic-atomics.rs
+++ b/src/test/ui/intrinsics/intrinsic-atomics.rs
@@ -3,31 +3,31 @@
 
 mod rusti {
     extern "rust-intrinsic" {
-        pub fn atomic_cxchg<T>(dst: *mut T, old: T, src: T) -> (T, bool);
-        pub fn atomic_cxchg_acq<T>(dst: *mut T, old: T, src: T) -> (T, bool);
-        pub fn atomic_cxchg_rel<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+        pub fn atomic_cxchg_seqcst_seqcst<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+        pub fn atomic_cxchg_acquire_acquire<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+        pub fn atomic_cxchg_release_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
 
-        pub fn atomic_cxchgweak<T>(dst: *mut T, old: T, src: T) -> (T, bool);
-        pub fn atomic_cxchgweak_acq<T>(dst: *mut T, old: T, src: T) -> (T, bool);
-        pub fn atomic_cxchgweak_rel<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+        pub fn atomic_cxchgweak_seqcst_seqcst<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+        pub fn atomic_cxchgweak_acquire_acquire<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+        pub fn atomic_cxchgweak_release_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
 
-        pub fn atomic_load<T>(src: *const T) -> T;
-        pub fn atomic_load_acq<T>(src: *const T) -> T;
+        pub fn atomic_load_seqcst<T>(src: *const T) -> T;
+        pub fn atomic_load_acquire<T>(src: *const T) -> T;
 
-        pub fn atomic_store<T>(dst: *mut T, val: T);
-        pub fn atomic_store_rel<T>(dst: *mut T, val: T);
+        pub fn atomic_store_seqcst<T>(dst: *mut T, val: T);
+        pub fn atomic_store_release<T>(dst: *mut T, val: T);
 
-        pub fn atomic_xchg<T>(dst: *mut T, src: T) -> T;
-        pub fn atomic_xchg_acq<T>(dst: *mut T, src: T) -> T;
-        pub fn atomic_xchg_rel<T>(dst: *mut T, src: T) -> T;
+        pub fn atomic_xchg_seqcst<T>(dst: *mut T, src: T) -> T;
+        pub fn atomic_xchg_acquire<T>(dst: *mut T, src: T) -> T;
+        pub fn atomic_xchg_release<T>(dst: *mut T, src: T) -> T;
 
-        pub fn atomic_xadd<T>(dst: *mut T, src: T) -> T;
-        pub fn atomic_xadd_acq<T>(dst: *mut T, src: T) -> T;
-        pub fn atomic_xadd_rel<T>(dst: *mut T, src: T) -> T;
+        pub fn atomic_xadd_seqcst<T>(dst: *mut T, src: T) -> T;
+        pub fn atomic_xadd_acquire<T>(dst: *mut T, src: T) -> T;
+        pub fn atomic_xadd_release<T>(dst: *mut T, src: T) -> T;
 
-        pub fn atomic_xsub<T>(dst: *mut T, src: T) -> T;
-        pub fn atomic_xsub_acq<T>(dst: *mut T, src: T) -> T;
-        pub fn atomic_xsub_rel<T>(dst: *mut T, src: T) -> T;
+        pub fn atomic_xsub_seqcst<T>(dst: *mut T, src: T) -> T;
+        pub fn atomic_xsub_acquire<T>(dst: *mut T, src: T) -> T;
+        pub fn atomic_xsub_release<T>(dst: *mut T, src: T) -> T;
     }
 }
 
@@ -35,45 +35,45 @@ pub fn main() {
     unsafe {
         let mut x: Box<_> = Box::new(1);
 
-        assert_eq!(rusti::atomic_load(&*x), 1);
+        assert_eq!(rusti::atomic_load_seqcst(&*x), 1);
         *x = 5;
-        assert_eq!(rusti::atomic_load_acq(&*x), 5);
+        assert_eq!(rusti::atomic_load_acquire(&*x), 5);
 
-        rusti::atomic_store(&mut *x,3);
+        rusti::atomic_store_seqcst(&mut *x,3);
         assert_eq!(*x, 3);
-        rusti::atomic_store_rel(&mut *x,1);
+        rusti::atomic_store_release(&mut *x,1);
         assert_eq!(*x, 1);
 
-        assert_eq!(rusti::atomic_cxchg(&mut *x, 1, 2), (1, true));
+        assert_eq!(rusti::atomic_cxchg_seqcst_seqcst(&mut *x, 1, 2), (1, true));
         assert_eq!(*x, 2);
 
-        assert_eq!(rusti::atomic_cxchg_acq(&mut *x, 1, 3), (2, false));
+        assert_eq!(rusti::atomic_cxchg_acquire_acquire(&mut *x, 1, 3), (2, false));
         assert_eq!(*x, 2);
 
-        assert_eq!(rusti::atomic_cxchg_rel(&mut *x, 2, 1), (2, true));
+        assert_eq!(rusti::atomic_cxchg_release_relaxed(&mut *x, 2, 1), (2, true));
         assert_eq!(*x, 1);
 
-        assert_eq!(rusti::atomic_xchg(&mut *x, 0), 1);
+        assert_eq!(rusti::atomic_xchg_seqcst(&mut *x, 0), 1);
         assert_eq!(*x, 0);
 
-        assert_eq!(rusti::atomic_xchg_acq(&mut *x, 1), 0);
+        assert_eq!(rusti::atomic_xchg_acquire(&mut *x, 1), 0);
         assert_eq!(*x, 1);
 
-        assert_eq!(rusti::atomic_xchg_rel(&mut *x, 0), 1);
+        assert_eq!(rusti::atomic_xchg_release(&mut *x, 0), 1);
         assert_eq!(*x, 0);
 
-        assert_eq!(rusti::atomic_xadd(&mut *x, 1), 0);
-        assert_eq!(rusti::atomic_xadd_acq(&mut *x, 1), 1);
-        assert_eq!(rusti::atomic_xadd_rel(&mut *x, 1), 2);
+        assert_eq!(rusti::atomic_xadd_seqcst(&mut *x, 1), 0);
+        assert_eq!(rusti::atomic_xadd_acquire(&mut *x, 1), 1);
+        assert_eq!(rusti::atomic_xadd_release(&mut *x, 1), 2);
         assert_eq!(*x, 3);
 
-        assert_eq!(rusti::atomic_xsub(&mut *x, 1), 3);
-        assert_eq!(rusti::atomic_xsub_acq(&mut *x, 1), 2);
-        assert_eq!(rusti::atomic_xsub_rel(&mut *x, 1), 1);
+        assert_eq!(rusti::atomic_xsub_seqcst(&mut *x, 1), 3);
+        assert_eq!(rusti::atomic_xsub_acquire(&mut *x, 1), 2);
+        assert_eq!(rusti::atomic_xsub_release(&mut *x, 1), 1);
         assert_eq!(*x, 0);
 
         loop {
-            let res = rusti::atomic_cxchgweak(&mut *x, 0, 1);
+            let res = rusti::atomic_cxchgweak_seqcst_seqcst(&mut *x, 0, 1);
             assert_eq!(res.0, 0);
             if res.1 {
                 break;
@@ -82,7 +82,7 @@ pub fn main() {
         assert_eq!(*x, 1);
 
         loop {
-            let res = rusti::atomic_cxchgweak_acq(&mut *x, 1, 2);
+            let res = rusti::atomic_cxchgweak_acquire_acquire(&mut *x, 1, 2);
             assert_eq!(res.0, 1);
             if res.1 {
                 break;
@@ -91,7 +91,7 @@ pub fn main() {
         assert_eq!(*x, 2);
 
         loop {
-            let res = rusti::atomic_cxchgweak_rel(&mut *x, 2, 3);
+            let res = rusti::atomic_cxchgweak_release_relaxed(&mut *x, 2, 3);
             assert_eq!(res.0, 2);
             if res.1 {
                 break;
diff --git a/src/test/ui/intrinsics/non-integer-atomic.rs b/src/test/ui/intrinsics/non-integer-atomic.rs
index 00a7f368a0f..85ea81ba679 100644
--- a/src/test/ui/intrinsics/non-integer-atomic.rs
+++ b/src/test/ui/intrinsics/non-integer-atomic.rs
@@ -12,81 +12,81 @@ pub type Bar = &'static Fn();
 pub type Quux = [u8; 100];
 
 pub unsafe fn test_bool_load(p: &mut bool, v: bool) {
-    intrinsics::atomic_load(p);
-    //~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `bool`
+    intrinsics::atomic_load_seqcst(p);
+    //~^ ERROR `atomic_load_seqcst` intrinsic: expected basic integer type, found `bool`
 }
 
 pub unsafe fn test_bool_store(p: &mut bool, v: bool) {
-    intrinsics::atomic_store(p, v);
-    //~^ ERROR `atomic_store` intrinsic: expected basic integer type, found `bool`
+    intrinsics::atomic_store_seqcst(p, v);
+    //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `bool`
 }
 
 pub unsafe fn test_bool_xchg(p: &mut bool, v: bool) {
-    intrinsics::atomic_xchg(p, v);
-    //~^ ERROR `atomic_xchg` intrinsic: expected basic integer type, found `bool`
+    intrinsics::atomic_xchg_seqcst(p, v);
+    //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `bool`
 }
 
 pub unsafe fn test_bool_cxchg(p: &mut bool, v: bool) {
-    intrinsics::atomic_cxchg(p, v, v);
-    //~^ ERROR `atomic_cxchg` intrinsic: expected basic integer type, found `bool`
+    intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+    //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `bool`
 }
 
 pub unsafe fn test_Foo_load(p: &mut Foo, v: Foo) {
-    intrinsics::atomic_load(p);
-    //~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `Foo`
+    intrinsics::atomic_load_seqcst(p);
+    //~^ ERROR `atomic_load_seqcst` intrinsic: expected basic integer type, found `Foo`
 }
 
 pub unsafe fn test_Foo_store(p: &mut Foo, v: Foo) {
-    intrinsics::atomic_store(p, v);
-    //~^ ERROR `atomic_store` intrinsic: expected basic integer type, found `Foo`
+    intrinsics::atomic_store_seqcst(p, v);
+    //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `Foo`
 }
 
 pub unsafe fn test_Foo_xchg(p: &mut Foo, v: Foo) {
-    intrinsics::atomic_xchg(p, v);
-    //~^ ERROR `atomic_xchg` intrinsic: expected basic integer type, found `Foo`
+    intrinsics::atomic_xchg_seqcst(p, v);
+    //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `Foo`
 }
 
 pub unsafe fn test_Foo_cxchg(p: &mut Foo, v: Foo) {
-    intrinsics::atomic_cxchg(p, v, v);
-    //~^ ERROR `atomic_cxchg` intrinsic: expected basic integer type, found `Foo`
+    intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+    //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `Foo`
 }
 
 pub unsafe fn test_Bar_load(p: &mut Bar, v: Bar) {
-    intrinsics::atomic_load(p);
+    intrinsics::atomic_load_seqcst(p);
     //~^ ERROR expected basic integer type, found `&dyn Fn()`
 }
 
 pub unsafe fn test_Bar_store(p: &mut Bar, v: Bar) {
-    intrinsics::atomic_store(p, v);
+    intrinsics::atomic_store_seqcst(p, v);
     //~^ ERROR expected basic integer type, found `&dyn Fn()`
 }
 
 pub unsafe fn test_Bar_xchg(p: &mut Bar, v: Bar) {
-    intrinsics::atomic_xchg(p, v);
+    intrinsics::atomic_xchg_seqcst(p, v);
     //~^ ERROR expected basic integer type, found `&dyn Fn()`
 }
 
 pub unsafe fn test_Bar_cxchg(p: &mut Bar, v: Bar) {
-    intrinsics::atomic_cxchg(p, v, v);
+    intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
     //~^ ERROR expected basic integer type, found `&dyn Fn()`
 }
 
 pub unsafe fn test_Quux_load(p: &mut Quux, v: Quux) {
-    intrinsics::atomic_load(p);
-    //~^ ERROR `atomic_load` intrinsic: expected basic integer type, found `[u8; 100]`
+    intrinsics::atomic_load_seqcst(p);
+    //~^ ERROR `atomic_load_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
 }
 
 pub unsafe fn test_Quux_store(p: &mut Quux, v: Quux) {
-    intrinsics::atomic_store(p, v);
-    //~^ ERROR `atomic_store` intrinsic: expected basic integer type, found `[u8; 100]`
+    intrinsics::atomic_store_seqcst(p, v);
+    //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
 }
 
 pub unsafe fn test_Quux_xchg(p: &mut Quux, v: Quux) {
-    intrinsics::atomic_xchg(p, v);
-    //~^ ERROR `atomic_xchg` intrinsic: expected basic integer type, found `[u8; 100]`
+    intrinsics::atomic_xchg_seqcst(p, v);
+    //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
 }
 
 pub unsafe fn test_Quux_cxchg(p: &mut Quux, v: Quux) {
-    intrinsics::atomic_cxchg(p, v, v);
-    //~^ ERROR `atomic_cxchg` intrinsic: expected basic integer type, found `[u8; 100]`
+    intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+    //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
 }
diff --git a/src/test/ui/intrinsics/non-integer-atomic.stderr b/src/test/ui/intrinsics/non-integer-atomic.stderr
index ee485c21cd6..32791a8e8b7 100644
--- a/src/test/ui/intrinsics/non-integer-atomic.stderr
+++ b/src/test/ui/intrinsics/non-integer-atomic.stderr
@@ -1,98 +1,98 @@
-error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `bool`
+error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `bool`
   --> $DIR/non-integer-atomic.rs:15:5
    |
-LL |     intrinsics::atomic_load(p);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_load_seqcst(p);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `bool`
+error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `bool`
   --> $DIR/non-integer-atomic.rs:20:5
    |
-LL |     intrinsics::atomic_store(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_store_seqcst(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `bool`
+error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `bool`
   --> $DIR/non-integer-atomic.rs:25:5
    |
-LL |     intrinsics::atomic_xchg(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_xchg_seqcst(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `bool`
+error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `bool`
   --> $DIR/non-integer-atomic.rs:30:5
    |
-LL |     intrinsics::atomic_cxchg(p, v, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `Foo`
+error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `Foo`
   --> $DIR/non-integer-atomic.rs:35:5
    |
-LL |     intrinsics::atomic_load(p);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_load_seqcst(p);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `Foo`
+error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `Foo`
   --> $DIR/non-integer-atomic.rs:40:5
    |
-LL |     intrinsics::atomic_store(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_store_seqcst(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `Foo`
+error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `Foo`
   --> $DIR/non-integer-atomic.rs:45:5
    |
-LL |     intrinsics::atomic_xchg(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_xchg_seqcst(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `Foo`
+error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `Foo`
   --> $DIR/non-integer-atomic.rs:50:5
    |
-LL |     intrinsics::atomic_cxchg(p, v, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `&dyn Fn()`
+error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()`
   --> $DIR/non-integer-atomic.rs:55:5
    |
-LL |     intrinsics::atomic_load(p);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_load_seqcst(p);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `&dyn Fn()`
+error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()`
   --> $DIR/non-integer-atomic.rs:60:5
    |
-LL |     intrinsics::atomic_store(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_store_seqcst(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `&dyn Fn()`
+error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()`
   --> $DIR/non-integer-atomic.rs:65:5
    |
-LL |     intrinsics::atomic_xchg(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_xchg_seqcst(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `&dyn Fn()`
+error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()`
   --> $DIR/non-integer-atomic.rs:70:5
    |
-LL |     intrinsics::atomic_cxchg(p, v, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `[u8; 100]`
+error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
   --> $DIR/non-integer-atomic.rs:75:5
    |
-LL |     intrinsics::atomic_load(p);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_load_seqcst(p);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `[u8; 100]`
+error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
   --> $DIR/non-integer-atomic.rs:80:5
    |
-LL |     intrinsics::atomic_store(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_store_seqcst(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `[u8; 100]`
+error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
   --> $DIR/non-integer-atomic.rs:85:5
    |
-LL |     intrinsics::atomic_xchg(p, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_xchg_seqcst(p, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `[u8; 100]`
+error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
   --> $DIR/non-integer-atomic.rs:90:5
    |
-LL |     intrinsics::atomic_cxchg(p, v, v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 16 previous errors
 
diff --git a/src/test/ui/issues/issue-14366.stderr b/src/test/ui/issues/issue-14366.stderr
index b96b07c91a1..10a73b245ac 100644
--- a/src/test/ui/issues/issue-14366.stderr
+++ b/src/test/ui/issues/issue-14366.stderr
@@ -5,7 +5,7 @@ LL |     let _x = "test" as &dyn (::std::any::Any);
    |              ^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
-   = note: required for the cast to the object type `dyn Any`
+   = note: required for the cast from `str` to the object type `dyn Any`
 help: consider borrowing the value, since `&str` can be coerced into `dyn Any`
    |
 LL |     let _x = &"test" as &dyn (::std::any::Any);
diff --git a/src/test/ui/issues/issue-22034.stderr b/src/test/ui/issues/issue-22034.stderr
index edcd21ebd6b..b32de5b24b9 100644
--- a/src/test/ui/issues/issue-22034.stderr
+++ b/src/test/ui/issues/issue-22034.stderr
@@ -6,7 +6,7 @@ LL |         &mut *(ptr as *mut dyn Fn())
    |
    = help: the trait `Fn<()>` is not implemented for `()`
    = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
-   = note: required for the cast to the object type `dyn Fn()`
+   = note: required for the cast from `()` to the object type `dyn Fn()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-22872.stderr b/src/test/ui/issues/issue-22872.stderr
index cd96646d751..a84cb7d8c59 100644
--- a/src/test/ui/issues/issue-22872.stderr
+++ b/src/test/ui/issues/issue-22872.stderr
@@ -10,7 +10,7 @@ note: required because of the requirements on the impl of `for<'b> Wrap<'b>` for
    |
 LL | impl<'b, P> Wrap<'b> for Wrapper<P>
    |             ^^^^^^^^     ^^^^^^^^^^
-   = note: required for the cast to the object type `dyn for<'b> Wrap<'b>`
+   = note: required for the cast from `Wrapper<P>` to the object type `dyn for<'b> Wrap<'b>`
 help: consider further restricting the associated type
    |
 LL | fn push_process<P>(process: P) where P: Process<'static>, <P as Process<'_>>::Item: Iterator {
diff --git a/src/test/ui/issues/issue-26094.rs b/src/test/ui/issues/issue-26094.rs
index 981c3abb4ba..df8c2f73910 100644
--- a/src/test/ui/issues/issue-26094.rs
+++ b/src/test/ui/issues/issue-26094.rs
@@ -1,6 +1,6 @@
 macro_rules! some_macro {
     ($other: expr) => ({
-        $other(None) //~ NOTE argument unexpected
+        $other(None) //~ NOTE argument of type `Option<_>` unexpected
     })
 }
 
diff --git a/src/test/ui/issues/issue-26094.stderr b/src/test/ui/issues/issue-26094.stderr
index 1013518e1da..881a6e538ee 100644
--- a/src/test/ui/issues/issue-26094.stderr
+++ b/src/test/ui/issues/issue-26094.stderr
@@ -2,7 +2,7 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/issue-26094.rs:10:17
    |
 LL |         $other(None)
-   |                ---- argument unexpected
+   |                ---- argument of type `Option<_>` unexpected
 ...
 LL |     some_macro!(some_function);
    |                 ^^^^^^^^^^^^^
diff --git a/src/test/ui/issues/issue-4935.stderr b/src/test/ui/issues/issue-4935.stderr
index b4cebe2a68b..aab19a699ac 100644
--- a/src/test/ui/issues/issue-4935.stderr
+++ b/src/test/ui/issues/issue-4935.stderr
@@ -2,7 +2,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/issue-4935.rs:5:13
    |
 LL | fn main() { foo(5, 6) }
-   |             ^^^    - argument unexpected
+   |             ^^^    - argument of type `{integer}` unexpected
    |
 note: function defined here
   --> $DIR/issue-4935.rs:3:4
diff --git a/src/test/ui/issues/issue-51515.rs b/src/test/ui/issues/issue-51515.rs
index 54fd176de75..797c1085d51 100644
--- a/src/test/ui/issues/issue-51515.rs
+++ b/src/test/ui/issues/issue-51515.rs
@@ -5,8 +5,6 @@ fn main() {
     *foo = 32;
     //~^ ERROR cannot assign to `*foo`, which is behind a `&` reference
     let bar = foo;
-    //~^ HELP consider changing this to be a mutable reference
-    //~| SUGGESTION &mut i32
     *bar = 64;
     //~^ ERROR cannot assign to `*bar`, which is behind a `&` reference
 }
diff --git a/src/test/ui/issues/issue-51515.stderr b/src/test/ui/issues/issue-51515.stderr
index 62bb462faa2..067bdef8b67 100644
--- a/src/test/ui/issues/issue-51515.stderr
+++ b/src/test/ui/issues/issue-51515.stderr
@@ -8,11 +8,10 @@ LL |     *foo = 32;
    |     ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
 
 error[E0594]: cannot assign to `*bar`, which is behind a `&` reference
-  --> $DIR/issue-51515.rs:10:5
+  --> $DIR/issue-51515.rs:8:5
    |
 LL |     let bar = foo;
-   |         --- help: consider changing this to be a mutable reference: `&mut i32`
-...
+   |         --- consider changing this binding's type to be: `&mut i32`
 LL |     *bar = 64;
    |     ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written
 
diff --git a/src/test/ui/issues/issue-7013.stderr b/src/test/ui/issues/issue-7013.stderr
index 98ed67507b1..f6cb1cbdc11 100644
--- a/src/test/ui/issues/issue-7013.stderr
+++ b/src/test/ui/issues/issue-7013.stderr
@@ -11,7 +11,7 @@ note: required because it appears within the type `B`
    |
 LL | struct B {
    |        ^
-   = note: required for the cast to the object type `dyn Foo + Send`
+   = note: required for the cast from `B` to the object type `dyn Foo + Send`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/kindck/kindck-impl-type-params.stderr b/src/test/ui/kindck/kindck-impl-type-params.stderr
index 32759d2fa0e..902349135c5 100644
--- a/src/test/ui/kindck/kindck-impl-type-params.stderr
+++ b/src/test/ui/kindck/kindck-impl-type-params.stderr
@@ -9,7 +9,7 @@ note: required because of the requirements on the impl of `Gettable<T>` for `S<T
    |
 LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
    |                                ^^^^^^^^^^^     ^^^^
-   = note: required for the cast to the object type `dyn Gettable<T>`
+   = note: required for the cast from `S<T>` to the object type `dyn Gettable<T>`
 help: consider restricting type parameter `T`
    |
 LL | fn f<T: std::marker::Send>(val: T) {
@@ -26,7 +26,7 @@ note: required because of the requirements on the impl of `Gettable<T>` for `S<T
    |
 LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
    |                                ^^^^^^^^^^^     ^^^^
-   = note: required for the cast to the object type `dyn Gettable<T>`
+   = note: required for the cast from `S<T>` to the object type `dyn Gettable<T>`
 help: consider restricting type parameter `T`
    |
 LL | fn f<T: std::marker::Copy>(val: T) {
@@ -43,7 +43,7 @@ note: required because of the requirements on the impl of `Gettable<T>` for `S<T
    |
 LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
    |                                ^^^^^^^^^^^     ^^^^
-   = note: required for the cast to the object type `dyn Gettable<T>`
+   = note: required for the cast from `S<T>` to the object type `dyn Gettable<T>`
 help: consider restricting type parameter `T`
    |
 LL | fn g<T: std::marker::Send>(val: T) {
@@ -60,7 +60,7 @@ note: required because of the requirements on the impl of `Gettable<T>` for `S<T
    |
 LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
    |                                ^^^^^^^^^^^     ^^^^
-   = note: required for the cast to the object type `dyn Gettable<T>`
+   = note: required for the cast from `S<T>` to the object type `dyn Gettable<T>`
 help: consider restricting type parameter `T`
    |
 LL | fn g<T: std::marker::Copy>(val: T) {
@@ -78,7 +78,7 @@ note: required because of the requirements on the impl of `Gettable<String>` for
    |
 LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
    |                                ^^^^^^^^^^^     ^^^^
-   = note: required for the cast to the object type `dyn Gettable<String>`
+   = note: required for the cast from `S<String>` to the object type `dyn Gettable<String>`
 
 error[E0277]: the trait bound `Foo: Copy` is not satisfied
   --> $DIR/kindck-impl-type-params.rs:43:37
@@ -92,7 +92,7 @@ note: required because of the requirements on the impl of `Gettable<Foo>` for `S
    |
 LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
    |                                ^^^^^^^^^^^     ^^^^
-   = note: required for the cast to the object type `dyn Gettable<Foo>`
+   = note: required for the cast from `S<Foo>` to the object type `dyn Gettable<Foo>`
 help: consider annotating `Foo` with `#[derive(Copy)]`
    |
 LL |     #[derive(Copy)]
diff --git a/src/test/ui/methods/method-call-err-msg.stderr b/src/test/ui/methods/method-call-err-msg.stderr
index 77308a2c521..57662e1e265 100644
--- a/src/test/ui/methods/method-call-err-msg.stderr
+++ b/src/test/ui/methods/method-call-err-msg.stderr
@@ -2,7 +2,7 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/method-call-err-msg.rs:13:7
    |
 LL |     x.zero(0)
-   |       ^^^^ - argument unexpected
+   |       ^^^^ - argument of type `{integer}` unexpected
    |
 note: associated function defined here
   --> $DIR/method-call-err-msg.rs:5:8
diff --git a/src/test/ui/mismatched_types/cast-rfc0401.stderr b/src/test/ui/mismatched_types/cast-rfc0401.stderr
index e63ca6e11de..eab8e8e80c4 100644
--- a/src/test/ui/mismatched_types/cast-rfc0401.stderr
+++ b/src/test/ui/mismatched_types/cast-rfc0401.stderr
@@ -220,7 +220,7 @@ LL |     let _ = fat_v as *const dyn Foo;
    |             ^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `[u8]`
-   = note: required for the cast to the object type `dyn Foo`
+   = note: required for the cast from `[u8]` to the object type `dyn Foo`
 help: consider borrowing the value, since `&[u8]` can be coerced into `dyn Foo`
    |
 LL |     let _ = &fat_v as *const dyn Foo;
@@ -233,7 +233,7 @@ LL |     let _ = a as *const dyn Foo;
    |             ^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
-   = note: required for the cast to the object type `dyn Foo`
+   = note: required for the cast from `str` to the object type `dyn Foo`
 help: consider borrowing the value, since `&str` can be coerced into `dyn Foo`
    |
 LL |     let _ = &a as *const dyn Foo;
diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
index 4000b2ba312..cb93a7ad900 100644
--- a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
+++ b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
@@ -32,7 +32,7 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/overloaded-calls-bad.rs:31:15
    |
 LL |     let ans = s("burma", "shave");
-   |               ^ -------  ------- argument unexpected
+   |               ^ -------  ------- argument of type `&'static str` unexpected
    |                 |
    |                 expected `isize`, found `&str`
    |
diff --git a/src/test/ui/never_type/fallback-closure-wrap.fallback.stderr b/src/test/ui/never_type/fallback-closure-wrap.fallback.stderr
index 78d1a3caf4a..6b9635d4a60 100644
--- a/src/test/ui/never_type/fallback-closure-wrap.fallback.stderr
+++ b/src/test/ui/never_type/fallback-closure-wrap.fallback.stderr
@@ -10,7 +10,7 @@ LL | |     }) as Box<dyn FnMut()>);
    |
    = note: expected unit type `()`
                    found type `!`
-   = note: required for the cast to the object type `dyn FnMut()`
+   = note: required for the cast from `[closure@$DIR/fallback-closure-wrap.rs:18:40: 21:6]` to the object type `dyn FnMut()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr
index 68da9f0dc88..e676d7372e8 100644
--- a/src/test/ui/span/issue-34264.stderr
+++ b/src/test/ui/span/issue-34264.stderr
@@ -54,7 +54,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/issue-34264.rs:7:5
    |
 LL |     foo(Some(42), 2, "");
-   |     ^^^              -- argument unexpected
+   |     ^^^              -- argument of type `&'static str` unexpected
    |
 note: function defined here
   --> $DIR/issue-34264.rs:1:4
@@ -84,7 +84,7 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/issue-34264.rs:10:5
    |
 LL |     bar(1, 2, 3);
-   |     ^^^       - argument unexpected
+   |     ^^^       - argument of type `{integer}` unexpected
    |
 note: function defined here
   --> $DIR/issue-34264.rs:3:4
diff --git a/src/test/ui/specialization/min_specialization/issue-79224.rs b/src/test/ui/specialization/min_specialization/issue-79224.rs
new file mode 100644
index 00000000000..408732fe944
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/issue-79224.rs
@@ -0,0 +1,24 @@
+#![feature(min_specialization)]
+use std::fmt::{self, Display};
+
+pub enum Cow<'a, B: ?Sized + 'a, O = <B as ToOwned>::Owned>
+where
+    B: ToOwned,
+{
+    Borrowed(&'a B),
+    Owned(O),
+}
+
+impl ToString for Cow<'_, str> {
+    fn to_string(&self) -> String {
+        String::new()
+    }
+}
+
+impl<B: ?Sized> Display for Cow<'_, B> { //~ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { //~ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
+        write!(f, "foo")
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/min_specialization/issue-79224.stderr b/src/test/ui/specialization/min_specialization/issue-79224.stderr
new file mode 100644
index 00000000000..44c6ec1426b
--- /dev/null
+++ b/src/test/ui/specialization/min_specialization/issue-79224.stderr
@@ -0,0 +1,29 @@
+error[E0277]: the trait bound `B: Clone` is not satisfied
+  --> $DIR/issue-79224.rs:18:17
+   |
+LL | impl<B: ?Sized> Display for Cow<'_, B> {
+   |                 ^^^^^^^ the trait `Clone` is not implemented for `B`
+   |
+   = note: required because of the requirements on the impl of `ToOwned` for `B`
+help: consider further restricting this bound
+   |
+LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
+   |                +++++++++++++++++++
+
+error[E0277]: the trait bound `B: Clone` is not satisfied
+  --> $DIR/issue-79224.rs:19:5
+   |
+LL | /     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+LL | |         write!(f, "foo")
+LL | |     }
+   | |_____^ the trait `Clone` is not implemented for `B`
+   |
+   = note: required because of the requirements on the impl of `ToOwned` for `B`
+help: consider further restricting this bound
+   |
+LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
+   |                +++++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
index 3d367eca707..805c75f464c 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
+++ b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
@@ -2,7 +2,7 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
   --> $DIR/args-instead-of-tuple-errors.rs:6:34
    |
 LL |     let _: Option<(i32, bool)> = Some(1, 2);
-   |                                  ^^^^ -  - argument unexpected
+   |                                  ^^^^ -  - argument of type `{integer}` unexpected
    |                                       |
    |                                       expected tuple, found integer
    |
@@ -22,7 +22,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/args-instead-of-tuple-errors.rs:8:5
    |
 LL |     int_bool(1, 2);
-   |     ^^^^^^^^ -  - argument unexpected
+   |     ^^^^^^^^ -  - argument of type `{integer}` unexpected
    |              |
    |              expected tuple, found integer
    |
diff --git a/src/test/ui/suggestions/derive-macro-missing-bounds.stderr b/src/test/ui/suggestions/derive-macro-missing-bounds.stderr
index 501d083e2bc..4186dc7cb35 100644
--- a/src/test/ui/suggestions/derive-macro-missing-bounds.stderr
+++ b/src/test/ui/suggestions/derive-macro-missing-bounds.stderr
@@ -33,7 +33,7 @@ LL |     impl<T: Debug + Trait> Debug for Inner<T> {
    |                            ^^^^^     ^^^^^^^^
    = note: 1 redundant requirement hidden
    = note: required because of the requirements on the impl of `Debug` for `&c::Inner<T>`
-   = note: required for the cast to the object type `dyn Debug`
+   = note: required for the cast from `&c::Inner<T>` to the object type `dyn Debug`
    = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider restricting type parameter `T`
    |
@@ -55,7 +55,7 @@ LL |     impl<T> Debug for Inner<T> where T: Debug, T: Trait {
    |             ^^^^^     ^^^^^^^^
    = note: 1 redundant requirement hidden
    = note: required because of the requirements on the impl of `Debug` for `&d::Inner<T>`
-   = note: required for the cast to the object type `dyn Debug`
+   = note: required for the cast from `&d::Inner<T>` to the object type `dyn Debug`
    = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider restricting type parameter `T`
    |
@@ -77,7 +77,7 @@ LL |     impl<T> Debug for Inner<T> where T: Debug + Trait {
    |             ^^^^^     ^^^^^^^^
    = note: 1 redundant requirement hidden
    = note: required because of the requirements on the impl of `Debug` for `&e::Inner<T>`
-   = note: required for the cast to the object type `dyn Debug`
+   = note: required for the cast from `&e::Inner<T>` to the object type `dyn Debug`
    = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider restricting type parameter `T`
    |
@@ -99,7 +99,7 @@ LL |     impl<T: Debug> Debug for Inner<T> where T: Trait {
    |                    ^^^^^     ^^^^^^^^
    = note: 1 redundant requirement hidden
    = note: required because of the requirements on the impl of `Debug` for `&f::Inner<T>`
-   = note: required for the cast to the object type `dyn Debug`
+   = note: required for the cast from `&f::Inner<T>` to the object type `dyn Debug`
    = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider restricting type parameter `T`
    |
diff --git a/src/test/ui/suggestions/option-content-move.stderr b/src/test/ui/suggestions/option-content-move.stderr
index a9e540084e5..fccfbe1d744 100644
--- a/src/test/ui/suggestions/option-content-move.stderr
+++ b/src/test/ui/suggestions/option-content-move.stderr
@@ -2,23 +2,37 @@ error[E0507]: cannot move out of `selection.1` which is behind a shared referenc
   --> $DIR/option-content-move.rs:11:20
    |
 LL |                 if selection.1.unwrap().contains(selection.0) {
-   |                    ^^^^^^^^^^^ move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait
+   |                    ^^^^^^^^^^^ -------- `selection.1` moved due to this method call
+   |                    |
+   |                    move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait
    |
-help: consider borrowing the `Option`'s content
+note: this function takes ownership of the receiver `self`, which moves `selection.1`
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+   |
+LL |     pub const fn unwrap(self) -> T {
+   |                         ^^^^
+help: consider calling `.as_ref()` to borrow the type's contents
    |
 LL |                 if selection.1.as_ref().unwrap().contains(selection.0) {
-   |                               +++++++++
+   |                                +++++++++
 
 error[E0507]: cannot move out of `selection.1` which is behind a shared reference
   --> $DIR/option-content-move.rs:29:20
    |
 LL |                 if selection.1.unwrap().contains(selection.0) {
-   |                    ^^^^^^^^^^^ move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait
+   |                    ^^^^^^^^^^^ -------- `selection.1` moved due to this method call
+   |                    |
+   |                    move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait
+   |
+note: this function takes ownership of the receiver `self`, which moves `selection.1`
+  --> $SRC_DIR/core/src/result.rs:LL:COL
    |
-help: consider borrowing the `Result`'s content
+LL |     pub fn unwrap(self) -> T
+   |                   ^^^^
+help: consider calling `.as_ref()` to borrow the type's contents
    |
 LL |                 if selection.1.as_ref().unwrap().contains(selection.0) {
-   |                               +++++++++
+   |                                +++++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/suggestions/suggest-borrow-to-dyn-object.rs b/src/test/ui/suggestions/suggest-borrow-to-dyn-object.rs
new file mode 100644
index 00000000000..120fc538307
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-borrow-to-dyn-object.rs
@@ -0,0 +1,16 @@
+use std::ffi::{OsStr, OsString};
+use std::path::Path;
+
+fn check(p: &dyn AsRef<Path>) {
+    let m = std::fs::metadata(&p);
+    println!("{:?}", &m);
+}
+
+fn main() {
+    let s: OsString = ".".into();
+    let s: &OsStr = &s;
+    check(s);
+    //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
+    //~| HELP within `OsStr`, the trait `Sized` is not implemented for `[u8]`
+    //~| HELP consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef<Path>`
+}
diff --git a/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr b/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr
new file mode 100644
index 00000000000..6b6e406130e
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/suggest-borrow-to-dyn-object.rs:12:11
+   |
+LL |     check(s);
+   |     ----- ^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: within `OsStr`, the trait `Sized` is not implemented for `[u8]`
+   = note: required because it appears within the type `OsStr`
+   = note: required for the cast from `OsStr` to the object type `dyn AsRef<Path>`
+help: consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef<Path>`
+   |
+LL |     check(&s);
+   |           +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/traits/coercion-generic-bad.stderr b/src/test/ui/traits/coercion-generic-bad.stderr
index b213ee635df..93d6770eb47 100644
--- a/src/test/ui/traits/coercion-generic-bad.stderr
+++ b/src/test/ui/traits/coercion-generic-bad.stderr
@@ -5,7 +5,7 @@ LL |     let s: Box<dyn Trait<isize>> = Box::new(Struct { person: "Fred" });
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<isize>` is not implemented for `Struct`
    |
    = help: the trait `Trait<&'static str>` is implemented for `Struct`
-   = note: required for the cast to the object type `dyn Trait<isize>`
+   = note: required for the cast from `Struct` to the object type `dyn Trait<isize>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/map-types.stderr b/src/test/ui/traits/map-types.stderr
index a4686edb717..f685c50b07d 100644
--- a/src/test/ui/traits/map-types.stderr
+++ b/src/test/ui/traits/map-types.stderr
@@ -5,7 +5,7 @@ LL |     let y: Box<dyn Map<usize, isize>> = Box::new(x);
    |                                         ^^^^^^^^^^^ the trait `Map<usize, isize>` is not implemented for `Box<dyn Map<isize, isize>>`
    |
    = help: the trait `Map<K, V>` is implemented for `HashMap<K, V>`
-   = note: required for the cast to the object type `dyn Map<usize, isize>`
+   = note: required for the cast from `Box<dyn Map<isize, isize>>` to the object type `dyn Map<usize, isize>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr
index 44f32e0cec9..3985372119e 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr
@@ -15,7 +15,7 @@ error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied
 LL |     let _ = x as &dyn Bar<_>; // Ambiguous
    |             ^ the trait `Bar<_>` is not implemented for `&dyn Foo`
    |
-   = note: required for the cast to the object type `dyn Bar<_>`
+   = note: required for the cast from `&dyn Foo` to the object type `dyn Bar<_>`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr
index 4ae4c8552c1..93c71f54eb5 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr
@@ -15,7 +15,7 @@ error[E0277]: the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
 LL |     let _ = x as &dyn Bar<u32>; // Error
    |             ^ the trait `Bar<u32>` is not implemented for `&dyn Foo<i32>`
    |
-   = note: required for the cast to the object type `dyn Bar<u32>`
+   = note: required for the cast from `&dyn Foo<i32>` to the object type `dyn Bar<u32>`
 
 error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>`
   --> $DIR/type-checking-test-2.rs:26:13
@@ -34,7 +34,7 @@ error[E0277]: the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
 LL |     let a = x as &dyn Bar<_>; // Ambiguous
    |             ^ the trait `Bar<_>` is not implemented for `&dyn Foo<u32>`
    |
-   = note: required for the cast to the object type `dyn Bar<_>`
+   = note: required for the cast from `&dyn Foo<u32>` to the object type `dyn Bar<_>`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/tuple/wrong_argument_ice-3.stderr b/src/test/ui/tuple/wrong_argument_ice-3.stderr
index 667b15776ef..2733fb3149b 100644
--- a/src/test/ui/tuple/wrong_argument_ice-3.stderr
+++ b/src/test/ui/tuple/wrong_argument_ice-3.stderr
@@ -2,7 +2,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/wrong_argument_ice-3.rs:9:16
    |
 LL |         groups.push(new_group, vec![process]);
-   |                ^^^^ ---------  ------------- argument unexpected
+   |                ^^^^ ---------  ------------- argument of type `Vec<&Process>` unexpected
    |                     |
    |                     expected tuple, found struct `Vec`
    |
diff --git a/src/test/ui/tuple/wrong_argument_ice-4.stderr b/src/test/ui/tuple/wrong_argument_ice-4.stderr
index f8dfc4cd043..3645d11842f 100644
--- a/src/test/ui/tuple/wrong_argument_ice-4.stderr
+++ b/src/test/ui/tuple/wrong_argument_ice-4.stderr
@@ -6,7 +6,7 @@ LL |       (|| {})(|| {
 LL | |
 LL | |         let b = 1;
 LL | |     });
-   | |_____- argument unexpected
+   | |_____- argument of type `[closure@$DIR/wrong_argument_ice-4.rs:2:13: 5:6]` unexpected
    |
 note: closure defined here
   --> $DIR/wrong_argument_ice-4.rs:2:6
diff --git a/src/test/ui/type/type-ascription-instead-of-initializer.stderr b/src/test/ui/type/type-ascription-instead-of-initializer.stderr
index 18ed4986f89..fcac6c495c4 100644
--- a/src/test/ui/type/type-ascription-instead-of-initializer.stderr
+++ b/src/test/ui/type/type-ascription-instead-of-initializer.stderr
@@ -11,7 +11,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/type-ascription-instead-of-initializer.rs:2:12
    |
 LL |     let x: Vec::with_capacity(10, 20);
-   |            ^^^^^^^^^^^^^^^^^^     -- argument unexpected
+   |            ^^^^^^^^^^^^^^^^^^     -- argument of type `{integer}` unexpected
    |
 note: associated function defined here
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
diff --git a/src/test/ui/typeck/remove-extra-argument.stderr b/src/test/ui/typeck/remove-extra-argument.stderr
index 815297765c1..703032a8322 100644
--- a/src/test/ui/typeck/remove-extra-argument.stderr
+++ b/src/test/ui/typeck/remove-extra-argument.stderr
@@ -2,7 +2,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/remove-extra-argument.rs:6:5
    |
 LL |     l(vec![], vec![])
-   |     ^         ------ argument unexpected
+   |     ^         ------ argument of type `Vec<_>` unexpected
    |
 note: function defined here
   --> $DIR/remove-extra-argument.rs:3:4
diff --git a/src/test/ui/typeck/struct-enum-wrong-args.stderr b/src/test/ui/typeck/struct-enum-wrong-args.stderr
index 2ea822df275..f72082d5301 100644
--- a/src/test/ui/typeck/struct-enum-wrong-args.stderr
+++ b/src/test/ui/typeck/struct-enum-wrong-args.stderr
@@ -2,7 +2,7 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:6:13
    |
 LL |     let _ = Some(3, 2);
-   |             ^^^^    - argument unexpected
+   |             ^^^^    - argument of type `{integer}` unexpected
    |
 note: tuple variant defined here
   --> $SRC_DIR/core/src/option.rs:LL:COL
@@ -18,9 +18,9 @@ error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:7:13
    |
 LL |     let _ = Ok(3, 6, 2);
-   |             ^^    -  - argument unexpected
+   |             ^^    -  - argument of type `{integer}` unexpected
    |                   |
-   |                   argument unexpected
+   |                   argument of type `{integer}` unexpected
    |
 note: tuple variant defined here
   --> $SRC_DIR/core/src/result.rs:LL:COL
@@ -68,7 +68,7 @@ error[E0061]: this struct takes 1 argument but 2 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:10:13
    |
 LL |     let _ = Wrapper(5, 2);
-   |             ^^^^^^^    - argument unexpected
+   |             ^^^^^^^    - argument of type `{integer}` unexpected
    |
 note: tuple struct defined here
   --> $DIR/struct-enum-wrong-args.rs:2:8
@@ -116,7 +116,7 @@ error[E0061]: this struct takes 2 arguments but 3 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:13:13
    |
 LL |     let _ = DoubleWrapper(5, 2, 7);
-   |             ^^^^^^^^^^^^^       - argument unexpected
+   |             ^^^^^^^^^^^^^       - argument of type `{integer}` unexpected
    |
 note: tuple struct defined here
   --> $DIR/struct-enum-wrong-args.rs:3:8
diff --git a/src/test/ui/unop-move-semantics.stderr b/src/test/ui/unop-move-semantics.stderr
index 14052486cbb..65d866c716e 100644
--- a/src/test/ui/unop-move-semantics.stderr
+++ b/src/test/ui/unop-move-semantics.stderr
@@ -46,13 +46,25 @@ error[E0507]: cannot move out of `*m` which is behind a mutable reference
   --> $DIR/unop-move-semantics.rs:24:6
    |
 LL |     !*m;
-   |      ^^ move occurs because `*m` has type `T`, which does not implement the `Copy` trait
+   |     -^^
+   |     ||
+   |     |move occurs because `*m` has type `T`, which does not implement the `Copy` trait
+   |     `*m` moved due to usage in operator
+   |
+note: calling this operator moves the left-hand side
+  --> $SRC_DIR/core/src/ops/bit.rs:LL:COL
+   |
+LL |     fn not(self) -> Self::Output;
+   |            ^^^^
 
 error[E0507]: cannot move out of `*n` which is behind a shared reference
   --> $DIR/unop-move-semantics.rs:26:6
    |
 LL |     !*n;
-   |      ^^ move occurs because `*n` has type `T`, which does not implement the `Copy` trait
+   |     -^^
+   |     ||
+   |     |move occurs because `*n` has type `T`, which does not implement the `Copy` trait
+   |     `*n` moved due to usage in operator
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/unsized/unsized-fn-param.stderr b/src/test/ui/unsized/unsized-fn-param.stderr
index 3eecca0fa09..b4772605432 100644
--- a/src/test/ui/unsized/unsized-fn-param.stderr
+++ b/src/test/ui/unsized/unsized-fn-param.stderr
@@ -5,7 +5,7 @@ LL |     foo11("bar", &"baz");
    |           ^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
-   = note: required for the cast to the object type `dyn AsRef<Path>`
+   = note: required for the cast from `str` to the object type `dyn AsRef<Path>`
 help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<Path>`
    |
 LL |     foo11(&"bar", &"baz");
@@ -18,7 +18,7 @@ LL |     foo12(&"bar", "baz");
    |                   ^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
-   = note: required for the cast to the object type `dyn AsRef<Path>`
+   = note: required for the cast from `str` to the object type `dyn AsRef<Path>`
 help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<Path>`
    |
 LL |     foo12(&"bar", &"baz");
@@ -31,7 +31,7 @@ LL |     foo21("bar", &"baz");
    |           ^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
-   = note: required for the cast to the object type `dyn AsRef<str>`
+   = note: required for the cast from `str` to the object type `dyn AsRef<str>`
 help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<str>`
    |
 LL |     foo21(&"bar", &"baz");
@@ -44,7 +44,7 @@ LL |     foo22(&"bar", "baz");
    |                   ^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
-   = note: required for the cast to the object type `dyn AsRef<str>`
+   = note: required for the cast from `str` to the object type `dyn AsRef<str>`
 help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<str>`
    |
 LL |     foo22(&"bar", &"baz");