]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #98665 - ChrisDenton:deprecated-suggestion, r=compiler-errors
authorMatthias Krüger <matthias.krueger@famsik.de>
Wed, 29 Jun 2022 18:35:06 +0000 (20:35 +0200)
committerGitHub <noreply@github.com>
Wed, 29 Jun 2022 18:35:06 +0000 (20:35 +0200)
Use verbose help for deprecation suggestion

Fixes #98631

r? `@compiler-errors`

176 files changed:
Cargo.lock
compiler/rustc_apfloat/Cargo.toml
compiler/rustc_arena/Cargo.toml
compiler/rustc_ast/Cargo.toml
compiler/rustc_ast_lowering/Cargo.toml
compiler/rustc_borrowck/Cargo.toml
compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
compiler/rustc_borrowck/src/diagnostics/move_errors.rs
compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
compiler/rustc_borrowck/src/diagnostics/region_errors.rs
compiler/rustc_borrowck/src/lib.rs
compiler/rustc_borrowck/src/session_diagnostics.rs [new file with mode: 0644]
compiler/rustc_borrowck/src/type_check/mod.rs
compiler/rustc_builtin_macros/Cargo.toml
compiler/rustc_codegen_cranelift/Cargo.lock
compiler/rustc_codegen_cranelift/Cargo.toml
compiler/rustc_codegen_llvm/Cargo.toml
compiler/rustc_codegen_ssa/Cargo.toml
compiler/rustc_codegen_ssa/src/lib.rs
compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
compiler/rustc_const_eval/src/const_eval/error.rs
compiler/rustc_const_eval/src/const_eval/eval_queries.rs
compiler/rustc_const_eval/src/const_eval/mod.rs
compiler/rustc_const_eval/src/interpret/cast.rs
compiler/rustc_const_eval/src/interpret/eval_context.rs
compiler/rustc_const_eval/src/interpret/validity.rs
compiler/rustc_const_eval/src/lib.rs
compiler/rustc_data_structures/Cargo.toml
compiler/rustc_error_codes/src/error_codes/E0093.md
compiler/rustc_error_messages/locales/en-US/borrowck.ftl [new file with mode: 0644]
compiler/rustc_error_messages/src/lib.rs
compiler/rustc_errors/src/emitter.rs
compiler/rustc_expand/Cargo.toml
compiler/rustc_hir/Cargo.toml
compiler/rustc_index/Cargo.toml
compiler/rustc_infer/Cargo.toml
compiler/rustc_infer/src/infer/error_reporting/mod.rs
compiler/rustc_interface/Cargo.toml
compiler/rustc_metadata/Cargo.toml
compiler/rustc_metadata/src/rmeta/decoder.rs
compiler/rustc_middle/Cargo.toml
compiler/rustc_middle/src/mir/interpret/queries.rs
compiler/rustc_middle/src/query/mod.rs
compiler/rustc_middle/src/traits/mod.rs
compiler/rustc_middle/src/ty/print/pretty.rs
compiler/rustc_mir_build/Cargo.toml
compiler/rustc_mir_build/src/build/mod.rs
compiler/rustc_mir_dataflow/Cargo.toml
compiler/rustc_mir_transform/Cargo.toml
compiler/rustc_mir_transform/src/add_retag.rs
compiler/rustc_monomorphize/Cargo.toml
compiler/rustc_query_system/Cargo.toml
compiler/rustc_resolve/Cargo.toml
compiler/rustc_serialize/Cargo.toml
compiler/rustc_trait_selection/Cargo.toml
compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
compiler/rustc_trait_selection/src/traits/select/confirmation.rs
compiler/rustc_traits/Cargo.toml
compiler/rustc_ty_utils/src/consts.rs [new file with mode: 0644]
compiler/rustc_ty_utils/src/lib.rs
compiler/rustc_type_ir/Cargo.toml
compiler/rustc_typeck/Cargo.toml
compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs
compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
compiler/rustc_typeck/src/variance/mod.rs
library/alloc/src/boxed/thin.rs
library/alloc/src/raw_vec.rs
library/alloc/src/string.rs
library/alloc/src/vec/into_iter.rs
library/core/src/ffi/mod.rs
library/core/src/intrinsics.rs
library/core/src/sync/atomic.rs
src/bootstrap/cc_detect.rs
src/librustdoc/Cargo.toml
src/librustdoc/html/static/js/main.js
src/test/mir-opt/retag.array_casts.SimplifyCfg-elaborate-drops.after.mir
src/test/run-make-fulldeps/alloc-no-oom-handling/Makefile
src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs
src/test/rustdoc-gui/pocket-menu.goml
src/test/rustdoc-gui/settings.goml
src/test/ui/argument-suggestions/basic.stderr
src/test/ui/argument-suggestions/extra_arguments.stderr
src/test/ui/argument-suggestions/issue-97484.stderr
src/test/ui/argument-suggestions/mixed_cases.stderr
src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
src/test/ui/associated-types/associated-types-eq-3.stderr
src/test/ui/associated-types/associated-types-overridden-binding-2.stderr
src/test/ui/associated-types/issue-65774-1.stderr
src/test/ui/associated-types/issue-65774-2.stderr
src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
src/test/ui/async-await/issue-86507.stderr
src/test/ui/binop/binop-move-semantics.stderr
src/test/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.stderr
src/test/ui/borrowck/issue-85765.rs
src/test/ui/borrowck/issue-85765.stderr
src/test/ui/borrowck/issue-91206.rs
src/test/ui/borrowck/issue-91206.stderr
src/test/ui/borrowck/issue-92015.stderr
src/test/ui/borrowck/suggest-as-ref-on-mut-closure.rs [new file with mode: 0644]
src/test/ui/borrowck/suggest-as-ref-on-mut-closure.stderr [new file with mode: 0644]
src/test/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr
src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr
src/test/ui/const-generics/defaults/trait_objects_fail.stderr
src/test/ui/const-generics/issue-66451.rs [new file with mode: 0644]
src/test/ui/const-generics/issue-66451.stderr [new file with mode: 0644]
src/test/ui/const-generics/try_unify_ignore_lifetimes.rs [new file with mode: 0644]
src/test/ui/custom_test_frameworks/mismatch.stderr
src/test/ui/dst/dst-bad-coerce1.stderr
src/test/ui/dst/dst-index.stderr
src/test/ui/dst/dst-object-from-unsized-type.stderr
src/test/ui/error-codes/E0057.stderr
src/test/ui/error-codes/E0161.base.stderr
src/test/ui/generic-associated-types/issue-79422.extended.stderr
src/test/ui/higher-rank-trait-bounds/issue-59311.stderr
src/test/ui/intrinsics/auxiliary/cci_intrinsic.rs
src/test/ui/intrinsics/intrinsic-atomics-cc.rs
src/test/ui/intrinsics/intrinsic-atomics.rs
src/test/ui/intrinsics/non-integer-atomic.rs
src/test/ui/intrinsics/non-integer-atomic.stderr
src/test/ui/issues/issue-14366.stderr
src/test/ui/issues/issue-22034.stderr
src/test/ui/issues/issue-22872.stderr
src/test/ui/issues/issue-26094.rs
src/test/ui/issues/issue-26094.stderr
src/test/ui/issues/issue-4935.stderr
src/test/ui/issues/issue-51515.rs
src/test/ui/issues/issue-51515.stderr
src/test/ui/issues/issue-7013.stderr
src/test/ui/kindck/kindck-impl-type-params.stderr
src/test/ui/lifetimes/re-empty-in-error.stderr
src/test/ui/methods/method-call-err-msg.stderr
src/test/ui/mir/issue-67947.rs
src/test/ui/mir/issue-67947.stderr
src/test/ui/mismatched_types/cast-rfc0401.stderr
src/test/ui/mismatched_types/overloaded-calls-bad.stderr
src/test/ui/never_type/fallback-closure-wrap.fallback.stderr
src/test/ui/object-safety/object-safety-by-value-self-use.rs
src/test/ui/object-safety/object-safety-by-value-self-use.stderr
src/test/ui/proc-macro/invalid-punct-ident-1.rs
src/test/ui/proc-macro/invalid-punct-ident-1.stderr
src/test/ui/proc-macro/signature.stderr
src/test/ui/span/issue-34264.stderr
src/test/ui/specialization/min_specialization/issue-79224.rs [new file with mode: 0644]
src/test/ui/specialization/min_specialization/issue-79224.stderr [new file with mode: 0644]
src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
src/test/ui/suggestions/args-instead-of-tuple.stderr
src/test/ui/suggestions/derive-macro-missing-bounds.stderr
src/test/ui/suggestions/option-content-move.stderr
src/test/ui/suggestions/suggest-borrow-to-dyn-object.rs [new file with mode: 0644]
src/test/ui/suggestions/suggest-borrow-to-dyn-object.stderr [new file with mode: 0644]
src/test/ui/traits/coercion-generic-bad.stderr
src/test/ui/traits/map-types.stderr
src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr
src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr
src/test/ui/tuple/add-tuple-within-arguments.rs [new file with mode: 0644]
src/test/ui/tuple/add-tuple-within-arguments.stderr [new file with mode: 0644]
src/test/ui/tuple/wrong_argument_ice-2.stderr
src/test/ui/tuple/wrong_argument_ice-3.stderr
src/test/ui/tuple/wrong_argument_ice-4.stderr
src/test/ui/tuple/wrong_argument_ice.stderr
src/test/ui/type/type-ascription-instead-of-initializer.stderr
src/test/ui/typeck/issue-98260.rs [new file with mode: 0644]
src/test/ui/typeck/issue-98260.stderr [new file with mode: 0644]
src/test/ui/typeck/remove-extra-argument.stderr
src/test/ui/typeck/struct-enum-wrong-args.stderr
src/test/ui/unop-move-semantics.stderr
src/test/ui/unsized/return-unsized-from-trait-method.rs
src/test/ui/unsized/return-unsized-from-trait-method.stderr
src/test/ui/unsized/unsized-fn-param.stderr
src/test/ui/unsized/unsized3.rs
src/test/ui/unsized/unsized3.stderr
src/tools/cargo
src/tools/rustc-workspace-hack/Cargo.toml
triagebot.toml

index 96d9449db57c076c5db7f44fa8c9dc92c12a479d..c0905982467dffd45bb99232a0596a219255fb16 100644 (file)
@@ -3595,6 +3595,7 @@ dependencies = [
  "rustc_index",
  "rustc_infer",
  "rustc_lexer",
+ "rustc_macros",
  "rustc_middle",
  "rustc_mir_dataflow",
  "rustc_serialize",
@@ -4907,9 +4908,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
 
 [[package]]
 name = "smallvec"
-version = "1.7.0"
+version = "1.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
+checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2"
 
 [[package]]
 name = "snap"
index bb01d4f51b899d8e1329668951d53f59fa87ea9a..98305201bc9433b7e071695fa9dd750e25293114 100644 (file)
@@ -5,4 +5,4 @@ edition = "2021"
 
 [dependencies]
 bitflags = "1.2.1"
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
index ee3a7b51b699a693de3465e7c8b0b1efcc036576..5c2aee6b47f9a24a1909777296004b70ca313e84 100644 (file)
@@ -4,4 +4,4 @@ version = "0.0.0"
 edition = "2021"
 
 [dependencies]
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
index 58b967a370415741c3f0ba94c5cd1af099070006..9822e9864e2103774c7cf92baa8bf5d05ffad23f 100644 (file)
@@ -14,5 +14,5 @@ rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_index = { path = "../rustc_index" }
 rustc_lexer = { path = "../rustc_lexer" }
 rustc_macros = { path = "../rustc_macros" }
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 bitflags = "1.2.1"
index e344d8a7637c483cd67f0845e866f0576af051c0..39ba62ef2ffc551a1cda0f9b18a2d7bb61ab347a 100644 (file)
@@ -20,4 +20,4 @@ rustc_span = { path = "../rustc_span" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_session = { path = "../rustc_session" }
 rustc_ast = { path = "../rustc_ast" }
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
index 0b531623ba6f5e3f08683e14949caedecf6b7d3f..fbf628e865e2c8bc52331cf6a413cfdcfbeddf3a 100644 (file)
@@ -11,7 +11,7 @@ either = "1.5.0"
 itertools = "0.10.1"
 tracing = "0.1"
 polonius-engine = "0.13.0"
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_graphviz = { path = "../rustc_graphviz" }
@@ -19,6 +19,7 @@ rustc_hir = { path = "../rustc_hir" }
 rustc_index = { path = "../rustc_index" }
 rustc_infer = { path = "../rustc_infer" }
 rustc_lexer = { path = "../rustc_lexer" }
+rustc_macros = { path = "../rustc_macros" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_const_eval = { path = "../rustc_const_eval" }
 rustc_mir_dataflow = { path = "../rustc_mir_dataflow" }
index 07f182102f346009b130861e5938fd4723032652..1ef2b0ae98843b3edd575b71783fd86a7f0e8b14 100644 (file)
@@ -19,6 +19,9 @@
 use std::rc::Rc;
 
 use crate::region_infer::values::RegionElement;
+use crate::session_diagnostics::HigherRankedErrorCause;
+use crate::session_diagnostics::HigherRankedLifetimeError;
+use crate::session_diagnostics::HigherRankedSubtypeError;
 use crate::MirBorrowckCtxt;
 
 #[derive(Clone)]
@@ -69,7 +72,7 @@ pub(crate) fn report_error(
                 // up in the existing UI tests. Consider investigating this
                 // some more.
                 mbcx.buffer_error(
-                    mbcx.infcx.tcx.sess.struct_span_err(cause.span, "higher-ranked subtype error"),
+                    mbcx.infcx.tcx.sess.create_err(HigherRankedSubtypeError { span: cause.span }),
                 );
             }
         }
@@ -216,9 +219,12 @@ fn fallback_error(
         tcx: TyCtxt<'tcx>,
         span: Span,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
-        let mut err = tcx.sess.struct_span_err(span, "higher-ranked lifetime error");
-        err.note(&format!("could not prove {}", self.canonical_query.value.value.predicate));
-        err
+        tcx.sess.create_err(HigherRankedLifetimeError {
+            cause: Some(HigherRankedErrorCause::CouldNotProve {
+                predicate: self.canonical_query.value.value.predicate.to_string(),
+            }),
+            span,
+        })
     }
 
     fn base_universe(&self) -> ty::UniverseIndex {
@@ -263,9 +269,12 @@ fn fallback_error(
         tcx: TyCtxt<'tcx>,
         span: Span,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
-        let mut err = tcx.sess.struct_span_err(span, "higher-ranked lifetime error");
-        err.note(&format!("could not normalize `{}`", self.canonical_query.value.value.value));
-        err
+        tcx.sess.create_err(HigherRankedLifetimeError {
+            cause: Some(HigherRankedErrorCause::CouldNotNormalize {
+                value: self.canonical_query.value.value.value.to_string(),
+            }),
+            span,
+        })
     }
 
     fn base_universe(&self) -> ty::UniverseIndex {
@@ -326,7 +335,7 @@ fn fallback_error(
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests,
         // and is only the fallback when the nice error fails. Consider improving this some more.
-        tcx.sess.struct_span_err(span, "higher-ranked lifetime error")
+        tcx.sess.create_err(HigherRankedLifetimeError { cause: None, span })
     }
 
     fn base_universe(&self) -> ty::UniverseIndex {
@@ -366,7 +375,7 @@ fn fallback_error(
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests,
         // and is only the fallback when the nice error fails. Consider improving this some more.
-        tcx.sess.struct_span_err(span, "higher-ranked lifetime error for opaque type!")
+        tcx.sess.create_err(HigherRankedLifetimeError { cause: None, span })
     }
 
     fn base_universe(&self) -> ty::UniverseIndex {
index eb5e61fa064bddf385035b7682c8d2979d09f72e..becb81b2e26a8d916a8ea6a84853004803060db1 100644 (file)
@@ -4,7 +4,7 @@
 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 @@ fn append_binding_error(
 
     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 @@ fn report(&mut self, error: GroupedMoveError<'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 @@ fn report_cannot_move_from_borrowed_content(
         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 @@ fn report_cannot_move_from_borrowed_content(
                 }
             }
         };
-        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,
             );
index 861c5e973f1f104eddbe45bdb4bc5559810a94d5..49b24a05071b2746b0f9bbeba07cef3449862527 100644 (file)
@@ -434,8 +434,8 @@ pub(crate) fn report_mutability_error(
 
                 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 @@ pub(crate) fn report_mutability_error(
                                 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 @@ pub(crate) fn report_mutability_error(
                                     // 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 @@ pub(crate) fn report_mutability_error(
                                                         ..
                                                     }),
                                                 ))) => {
-                                                    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 @@ pub(crate) fn report_mutability_error(
                                                 ),
                                             }
                                         };
-                                        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 @@ pub(crate) fn report_mutability_error(
                                     .map(|replacement| (true, pattern_span, replacement))
                             }
 
-                            box LocalInfo::User(ClearCrossCrate::Clear) => {
+                            LocalInfo::User(ClearCrossCrate::Clear) => {
                                 bug!("saw cleared local state")
                             }
 
@@ -559,7 +558,12 @@ pub(crate) fn report_mutability_error(
                                 }
                             }
                             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)
index e0f8da1c872d3abfef62ec2426b9554ee2e5b8de..5d3997289bb333ec6f7b8b55b0f42e45eb6ca68f 100644 (file)
@@ -24,6 +24,7 @@
 use rustc_span::Span;
 
 use crate::borrowck_errors;
+use crate::session_diagnostics::GenericDoesNotLiveLongEnough;
 
 use super::{OutlivesSuggestionBuilder, RegionName};
 use crate::region_infer::BlameConstraint;
@@ -196,9 +197,11 @@ pub(crate) fn report_region_errors(&mut self, nll_errors: RegionErrors<'tcx>) {
                         // to report it; we could probably handle it by
                         // iterating over the universal regions and reporting
                         // an error that multiple bounds are required.
-                        self.buffer_error(self.infcx.tcx.sess.struct_span_err(
-                            type_test_span,
-                            &format!("`{}` does not live long enough", type_test.generic_kind),
+                        self.buffer_error(self.infcx.tcx.sess.create_err(
+                            GenericDoesNotLiveLongEnough {
+                                kind: type_test.generic_kind.to_string(),
+                                span: type_test_span,
+                            },
                         ));
                     }
                 }
index a2df072aa31195f63964f71d9d45bc4e4dfdb08c..7d6f37340c2bb06218aa855cb451ddc3998bda5e 100644 (file)
@@ -76,6 +76,7 @@
 mod prefixes;
 mod region_infer;
 mod renumber;
+mod session_diagnostics;
 mod type_check;
 mod universal_regions;
 mod used_muts;
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
new file mode 100644 (file)
index 0000000..895723d
--- /dev/null
@@ -0,0 +1,44 @@
+use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
+use rustc_middle::ty::Ty;
+use rustc_span::Span;
+
+#[derive(SessionDiagnostic)]
+#[error(borrowck::move_unsized, code = "E0161")]
+pub(crate) struct MoveUnsized<'tcx> {
+    pub ty: Ty<'tcx>,
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(borrowck::higher_ranked_lifetime_error)]
+pub(crate) struct HigherRankedLifetimeError {
+    #[subdiagnostic]
+    pub cause: Option<HigherRankedErrorCause>,
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum HigherRankedErrorCause {
+    #[note(borrowck::could_not_prove)]
+    CouldNotProve { predicate: String },
+    #[note(borrowck::could_not_normalize)]
+    CouldNotNormalize { value: String },
+}
+
+#[derive(SessionDiagnostic)]
+#[error(borrowck::higher_ranked_subtype_error)]
+pub(crate) struct HigherRankedSubtypeError {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[error(borrowck::generic_does_not_live_long_enough)]
+pub(crate) struct GenericDoesNotLiveLongEnough {
+    pub kind: String,
+    #[primary_span]
+    pub span: Span,
+}
index 542fc6b0f485d439d99baaf6dcd8be4f0a865dbe..5ee1f5a8e8e37f414e05a2d5dde65febdbcc21ee 100644 (file)
@@ -9,7 +9,6 @@
 use rustc_data_structures::frozen::Frozen;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::vec_map::VecMap;
-use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
@@ -48,6 +47,7 @@
 use rustc_mir_dataflow::move_paths::MoveData;
 use rustc_mir_dataflow::ResultsCursor;
 
+use crate::session_diagnostics::MoveUnsized;
 use crate::{
     borrow_set::BorrowSet,
     constraints::{OutlivesConstraint, OutlivesConstraintSet},
@@ -1780,19 +1780,10 @@ fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) {
             // slot or local, so to find all unsized rvalues it is enough
             // to check all temps, return slots and locals.
             if self.reported_errors.replace((ty, span)).is_none() {
-                let mut diag = struct_span_err!(
-                    self.tcx().sess,
-                    span,
-                    E0161,
-                    "cannot move a value of type {0}: the size of {0} \
-                     cannot be statically determined",
-                    ty
-                );
-
                 // While this is located in `nll::typeck` this error is not
                 // an NLL error, it's a required check to prevent creation
                 // of unsized rvalues in a call expression.
-                diag.emit();
+                self.tcx().sess.emit_err(MoveUnsized { ty, span });
             }
         }
     }
index 7dc947f7d9a143fb1e72d6cdf9ae97814c7908ca..8d8e9d9b5ff4e03a5b8496f36b406a1a7746da3b 100644 (file)
@@ -20,7 +20,7 @@ rustc_macros = { path = "../rustc_macros" }
 rustc_parse = { path = "../rustc_parse" }
 rustc_target = { path = "../rustc_target" }
 rustc_session = { path = "../rustc_session" }
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 rustc_ast = { path = "../rustc_ast" }
 rustc_expand = { path = "../rustc_expand" }
 rustc_span = { path = "../rustc_span" }
index 7b8e43b639f993f97aec41c1da60d8775fdb613a..da18ac7eacbfcb0a88d69edc6a035f56c2c6aa11 100644 (file)
@@ -285,9 +285,9 @@ dependencies = [
 
 [[package]]
 name = "smallvec"
-version = "1.8.0"
+version = "1.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
+checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2"
 
 [[package]]
 name = "target-lexicon"
index 18d7f41cf408a7713cf1fc4ae9066dad23987b8a..ec2c1f2ca71b31f841b39372a0db4fd78ffadfea 100644 (file)
@@ -22,7 +22,7 @@ ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg
 indexmap = "1.8.0"
 libloading = { version = "0.6.0", optional = true }
 once_cell = "1.10.0"
-smallvec = "1.6.1"
+smallvec = "1.8.1"
 
 [patch.crates-io]
 # Uncomment to use local checkout of cranelift
index b486af133760f73ef2e68b45318224fa1b1918aa..d8fbd0a84fb36e7ebb0b33291bc5711c334038f8 100644 (file)
@@ -31,6 +31,6 @@ rustc_query_system = { path = "../rustc_query_system" }
 rustc_session = { path = "../rustc_session" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_target = { path = "../rustc_target" }
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 rustc_ast = { path = "../rustc_ast" }
 rustc_span = { path = "../rustc_span" }
index 1bdc473c29b6ee522bbbaa3736602f066ade81ea..faabea92f5a6c80da5c54d03d69757768a50d53b 100644 (file)
@@ -18,7 +18,7 @@ thorin-dwp = "0.2"
 pathdiff = "0.2.0"
 serde_json = "1.0.59"
 snap = "1"
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 regex = "1.4"
 
 rustc_serialize = { path = "../rustc_serialize" }
index 6c30923bc3d737c3a712f768732dac32a8f9cf2f..4be3ae11e4e5bf2fab4a05b146472cdc87fa8281 100644 (file)
@@ -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)]
 
index 0ed4c3f1d9430652f529e9c8c0d404545e0c1a56..7f14b95317b46e66ca0be4501eecfdf7281fe0b0 100644 (file)
@@ -376,32 +376,23 @@ pub fn codegen_intrinsic_call(
             }
 
             // 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 @@ pub fn codegen_intrinsic_call(
                     );
                 };
 
-                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 @@ pub fn codegen_intrinsic_call(
                                 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 @@ pub fn codegen_intrinsic_call(
                                 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 @@ pub fn codegen_intrinsic_call(
                                 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 @@ pub fn codegen_intrinsic_call(
                     }
 
                     "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 @@ pub fn codegen_intrinsic_call(
                                 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);
                         }
index 3eeb0138b37f7b06dcfd14cf62811206c30e668e..eb81f43c3fe8cbafa2b3b9fa1f70e40594b88904 100644 (file)
@@ -82,12 +82,12 @@ pub fn new<'mir, M: Machine<'mir, '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(
index b7e5e7aea49ce5a1cdf544db80be81b02bb79d5e..09a2977af04033b6e2559c38f7d0a575e9077d75 100644 (file)
@@ -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(
index a1d2e5cf3ef1228f4754c0ab31672909f61a07ba..bf65fdc54ca48a6ca15525213e2091ec06326ca7 100644 (file)
@@ -5,7 +5,6 @@
 use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::{source_map::DUMMY_SP, symbol::Symbol};
-use rustc_target::abi::VariantIdx;
 
 use crate::interpret::{
     intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, MemPlaceMeta,
@@ -91,83 +90,6 @@ pub(crate) fn eval_to_valtree<'tcx>(
     }
 }
 
-/// Tries to destructure constants of type Array or Adt into the constants
-/// of its fields.
-pub(crate) fn try_destructure_const<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    const_: ty::Const<'tcx>,
-) -> Option<ty::DestructuredConst<'tcx>> {
-    if let ty::ConstKind::Value(valtree) = const_.kind() {
-        let branches = match valtree {
-            ty::ValTree::Branch(b) => b,
-            _ => return None,
-        };
-
-        let (fields, variant) = match const_.ty().kind() {
-            ty::Array(inner_ty, _) | ty::Slice(inner_ty) => {
-                // construct the consts for the elements of the array/slice
-                let field_consts = branches
-                    .iter()
-                    .map(|b| {
-                        tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Value(*b), ty: *inner_ty })
-                    })
-                    .collect::<Vec<_>>();
-                debug!(?field_consts);
-
-                (field_consts, None)
-            }
-            ty::Adt(def, _) if def.variants().is_empty() => bug!("unreachable"),
-            ty::Adt(def, substs) => {
-                let variant_idx = if def.is_enum() {
-                    VariantIdx::from_u32(branches[0].unwrap_leaf().try_to_u32().ok()?)
-                } else {
-                    VariantIdx::from_u32(0)
-                };
-                let fields = &def.variant(variant_idx).fields;
-                let mut field_consts = Vec::with_capacity(fields.len());
-
-                // Note: First element inValTree corresponds to variant of enum
-                let mut valtree_idx = if def.is_enum() { 1 } else { 0 };
-                for field in fields {
-                    let field_ty = field.ty(tcx, substs);
-                    let field_valtree = branches[valtree_idx]; // first element of branches is variant
-                    let field_const = tcx.mk_const(ty::ConstS {
-                        kind: ty::ConstKind::Value(field_valtree),
-                        ty: field_ty,
-                    });
-                    field_consts.push(field_const);
-                    valtree_idx += 1;
-                }
-                debug!(?field_consts);
-
-                (field_consts, Some(variant_idx))
-            }
-            ty::Tuple(elem_tys) => {
-                let fields = elem_tys
-                    .iter()
-                    .enumerate()
-                    .map(|(i, elem_ty)| {
-                        let elem_valtree = branches[i];
-                        tcx.mk_const(ty::ConstS {
-                            kind: ty::ConstKind::Value(elem_valtree),
-                            ty: elem_ty,
-                        })
-                    })
-                    .collect::<Vec<_>>();
-
-                (fields, None)
-            }
-            _ => bug!("cannot destructure constant {:?}", const_),
-        };
-
-        let fields = tcx.arena.alloc_from_iter(fields.into_iter());
-
-        Some(ty::DestructuredConst { variant, fields })
-    } else {
-        None
-    }
-}
-
 #[instrument(skip(tcx), level = "debug")]
 pub(crate) fn try_destructure_mir_constant<'tcx>(
     tcx: TyCtxt<'tcx>,
index fb484fba9fd066e77ed8f5edffe2210b0221dfd5..076415b2d1b2f3b8f4df9267488db7b82dbffd8b 100644 (file)
@@ -366,22 +366,6 @@ fn unsize_into(
             }
             (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
                 assert_eq!(def_a, def_b);
-                if def_a.is_box() || def_b.is_box() {
-                    if !def_a.is_box() || !def_b.is_box() {
-                        span_bug!(
-                            self.cur_span(),
-                            "invalid unsizing between {:?} -> {:?}",
-                            src.layout.ty,
-                            cast_ty.ty
-                        );
-                    }
-                    return self.unsize_into_ptr(
-                        src,
-                        dest,
-                        src.layout.ty.boxed_ty(),
-                        cast_ty.ty.boxed_ty(),
-                    );
-                }
 
                 // unsizing of generic struct with pointer fields
                 // Example: `Arc<T>` -> `Arc<Trait>`
index 1c1bbd370bd4932ac1469e34e726e6f8581689ac..66c736245017c5397775201dd6829d2285074a29 100644 (file)
@@ -428,11 +428,9 @@ pub fn new(
 
     #[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 @@ pub fn dump_place(&self, place: Place<M::PointerTag>) -> PlacePrinter<'_, 'mir,
     #[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),
index 630281bb09254ec90b401737ed88c94970e72898..905ab6cb578fc1e0eef52b71276797efe7f530ab 100644 (file)
@@ -594,7 +594,13 @@ fn try_visit_primitive(
                 Ok(true)
             }
             ty::Adt(def, ..) if def.is_box() => {
-                self.check_safe_pointer(value, "box")?;
+                let unique = self.ecx.operand_field(value, 0)?;
+                let nonnull = self.ecx.operand_field(&unique, 0)?;
+                let ptr = self.ecx.operand_field(&nonnull, 0)?;
+                self.check_safe_pointer(&ptr, "box")?;
+
+                // Check other fields of Box
+                self.walk_value(value)?;
                 Ok(true)
             }
             ty::FnPtr(_sig) => {
index 64a74e9d7e206931ee3fe0f3309aaaca8ce4fdc4..5bf91879066f483008426082dd542e3796a7eeee 100644 (file)
@@ -42,7 +42,6 @@ pub fn provide(providers: &mut Providers) {
     providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider;
     providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider;
     providers.const_caller_location = const_eval::const_caller_location;
-    providers.try_destructure_const = |tcx, val| const_eval::try_destructure_const(tcx, val);
     providers.eval_to_valtree = |tcx, param_env_and_value| {
         let (param_env, raw) = param_env_and_value.into_parts();
         const_eval::eval_to_valtree(tcx, param_env, raw)
index 33deadb32d447783659449c7bdadfbfa6fc4174a..2a801d0e7026900025c05173926ccce1cbb775a2 100644 (file)
@@ -20,7 +20,7 @@ stable_deref_trait = "1.0.0"
 rayon = { version = "0.4.0", package = "rustc-rayon", optional = true }
 rayon-core = { version = "0.4.0", package = "rustc-rayon-core", optional = true }
 rustc-hash = "1.1.0"
-smallvec = { version = "1.6.1", features = ["const_generics", "union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["const_generics", "union", "may_dangle"] }
 rustc_index = { path = "../rustc_index", package = "rustc_index" }
 bitflags = "1.2.1"
 measureme = "10.0.0"
index 6d58e50ec8813d515f80c6925995c75890e18743..b1683cf4fc4aea0970c161604e22eed460daacc2 100644 (file)
@@ -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_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
new file mode 100644 (file)
index 0000000..645673e
--- /dev/null
@@ -0,0 +1,18 @@
+borrowck-move-unsized =
+    cannot move a value of type `{$ty}`
+    .label = the size of `{$ty}` cannot be statically determined
+
+borrowck-higher-ranked-lifetime-error =
+    higher-ranked lifetime error
+
+borrowck-could-not-prove =
+    could not prove `{$predicate}`
+
+borrowck-could-not-normalize =
+    could not normalize `{$value}`
+
+borrowck-higher-ranked-subtype-error =
+    higher-ranked subtype error
+  
+generic-does-not-live-long-enough =
+    `{$kind}` does not live long enough
\ No newline at end of file
index 90eb5ef54462d87181a41f1d0549746d9ca37360..d52b94b78dfac035f1d227d3c385364bb4bc32cd 100644 (file)
@@ -35,6 +35,7 @@
     privacy => "../locales/en-US/privacy.ftl",
     typeck => "../locales/en-US/typeck.ftl",
     builtin_macros => "../locales/en-US/builtin_macros.ftl",
+    borrowck => "../locales/en-US/borrowck.ftl",
 }
 
 pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES};
index 8b2a995f1c58ebf974d0d1f903f934565af8016b..6d74e9a9f2b9e5dd20ab8c134b8d21d05934142e 100644 (file)
@@ -281,9 +281,19 @@ fn translate_message<'a>(
         let message = bundle.get_message(&identifier).expect("missing diagnostic in fluent bundle");
         let value = match attr {
             Some(attr) => {
-                message.get_attribute(attr).expect("missing attribute in fluent message").value()
+                if let Some(attr) = message.get_attribute(attr) {
+                    attr.value()
+                } else {
+                    panic!("missing attribute `{attr}` in fluent message `{identifier}`")
+                }
+            }
+            None => {
+                if let Some(value) = message.value() {
+                    value
+                } else {
+                    panic!("missing value in fluent message `{identifier}`")
+                }
             }
-            None => message.value().expect("missing value in fluent message"),
         };
 
         let mut err = vec![];
index 45237ab2e9f2502b32f48afd13dbf582c9e7c7a7..05e5913baa0c76396148b0747f29828b53952270 100644 (file)
@@ -22,5 +22,5 @@ rustc_macros = { path = "../rustc_macros" }
 rustc_lexer = { path = "../rustc_lexer" }
 rustc_parse = { path = "../rustc_parse" }
 rustc_session = { path = "../rustc_session" }
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 rustc_ast = { path = "../rustc_ast" }
index 47ace7ca3a750e6eb77bbebad402377d6eb9ede6..064ed0cde9675dd1ddfe45eb589dab62eb6b86de 100644 (file)
@@ -16,5 +16,5 @@ rustc_span = { path = "../rustc_span" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_ast = { path = "../rustc_ast" }
 tracing = "0.1"
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 odht = { version = "0.3.1", features = ["nightly"] }
index 89419bfce6f5bf86846713017ce68afab612aca1..8a81a93a99cfd67af66bd33e55ee4d4e818749d4 100644 (file)
@@ -10,4 +10,4 @@ doctest = false
 arrayvec = { version = "0.7", default-features = false }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_macros = { path = "../rustc_macros" }
-smallvec = "1"
+smallvec = "1.8.1"
index bbc2b767734714152aea4a8a31084d4bf2725008..02ac83a5e8b25b3f32ecdbfb62d81013c34a71f3 100644 (file)
@@ -17,4 +17,4 @@ rustc_macros = { path = "../rustc_macros" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
index b94d205488d01d494c2d6210f3928f612c53b9ef..e319f17b0e60d5fccc69536a0b085b279e2f4c91 100644 (file)
@@ -342,8 +342,8 @@ pub fn same_type_modulo_infer<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
         )
         | (&ty::Infer(ty::InferTy::TyVar(_)), _)
         | (_, &ty::Infer(ty::InferTy::TyVar(_))) => true,
-        (&ty::Ref(reg_a, ty_a, mut_a), &ty::Ref(reg_b, ty_b, mut_b)) => {
-            reg_a == reg_b && mut_a == mut_b && same_type_modulo_infer(*ty_a, *ty_b)
+        (&ty::Ref(_, ty_a, mut_a), &ty::Ref(_, ty_b, mut_b)) => {
+            mut_a == mut_b && same_type_modulo_infer(*ty_a, *ty_b)
         }
         _ => a == b,
     }
index 26b1b9948a0472c226654f8118609790eb112ebe..9aacfba3c8208b715dc1fb045357fdb061334eb9 100644 (file)
@@ -11,7 +11,7 @@ libloading = "0.7.1"
 tracing = "0.1"
 rustc-rayon-core = { version = "0.4.0", optional = true }
 rayon = { version = "0.4.0", package = "rustc-rayon", optional = true }
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 rustc_ast = { path = "../rustc_ast" }
 rustc_attr = { path = "../rustc_attr" }
 rustc_borrowck = { path = "../rustc_borrowck" }
index 41224e33461776b212e3d92a20bcc63b08adc7ed..3ab4a8b7294aa53743b0434f9c56d2d3213f0de8 100644 (file)
@@ -11,7 +11,7 @@ libloading = "0.7.1"
 odht = { version = "0.3.1", features = ["nightly"] }
 snap = "1"
 tracing = "0.1"
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 rustc_middle = { path = "../rustc_middle" }
 rustc_attr = { path = "../rustc_attr" }
 rustc_data_structures = { path = "../rustc_data_structures" }
index c1ded99a25af56fd51bd35c24ce6f6bfbe4cd6f7..3280fd5c3108b462495d8449453d1525e54dd797 100644 (file)
@@ -42,7 +42,7 @@
 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 @@ fn imported_source_files(self, sess: &Session) -> &'a [ImportedSourceFile] {
         //
         // 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 @@ fn imported_source_files(self, sess: &Session) -> &'a [ImportedSourceFile] {
                 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 } =
index cee80823443f53c29e55cbfe49c21c569a4fd4f1..008d2c7091c1ea56ef61e1e580b3db46c2520621 100644 (file)
@@ -30,7 +30,7 @@ rustc_serialize = { path = "../rustc_serialize" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_span = { path = "../rustc_span" }
 chalk-ir = "0.80.0"
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 rustc_session = { path = "../rustc_session" }
 rustc_type_ir = { path = "../rustc_type_ir" }
 rand = "0.8.4"
index 4895b53bb2677ed8fae9ecb3e62d3d277ca0a113..575147feebc94f051bb3109d42fc16114a1cf358 100644 (file)
@@ -205,14 +205,8 @@ pub fn eval_static_initializer(self, def_id: DefId) {
 }
 
 impl<'tcx> TyCtxt<'tcx> {
-    /// Destructure a type-level constant ADT or array into its variant index and its field values.
-    /// Panics if the destructuring fails, use `try_destructure_const` for fallible version.
-    pub fn destructure_const(self, const_: ty::Const<'tcx>) -> ty::DestructuredConst<'tcx> {
-        self.try_destructure_const(const_).unwrap()
-    }
-
     /// Destructure a mir constant ADT or array into its variant index and its field values.
-    /// Panics if the destructuring fails, use `try_destructure_const` for fallible version.
+    /// Panics if the destructuring fails, use `try_destructure_mir_constant` for fallible version.
     pub fn destructure_mir_constant(
         self,
         param_env: ty::ParamEnv<'tcx>,
index 2e68fc8a7c050cb58191a79e1dd098f284706ea6..a1065eef8509dcce3020626974a751df9622f9e8 100644 (file)
         desc { "converting type-level constant value to mir constant value"}
     }
 
-    /// Destructure a constant ADT or array into its variant index and its
-    /// field values or return `None` if constant is invalid.
-    ///
-    /// Use infallible `TyCtxt::destructure_const` when you know that constant is valid.
-    query try_destructure_const(key: ty::Const<'tcx>) -> Option<ty::DestructuredConst<'tcx>> {
+    /// Destructures array, ADT or tuple constants into the constants
+    /// of their fields.
+    query destructure_const(key: ty::Const<'tcx>) -> ty::DestructuredConst<'tcx> {
         desc { "destructuring type level constant"}
     }
 
index ed8de24a65eefbf3b93d90746d9575d072c484f4..7f913faf86058674556590620db0e944721d7798 100644 (file)
@@ -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 {
index c56909ba18b143559e34418c949147fda55d516f..7f3b0fdccc6f11ffc9a05bef5a95a634a7102d6b 100644 (file)
@@ -1447,7 +1447,11 @@ fn pretty_print_const_valtree(
                     p!(write("{:?}", String::from_utf8_lossy(bytes)));
                     return Ok(self);
                 }
-                _ => {}
+                _ => {
+                    p!("&");
+                    p!(pretty_print_const_valtree(valtree, *inner_ty, print_ty));
+                    return Ok(self);
+                }
             },
             (ty::ValTree::Branch(_), ty::Array(t, _)) if *t == u8_type => {
                 let bytes = valtree.try_to_raw_bytes(self.tcx(), *t).unwrap_or_else(|| {
@@ -1459,16 +1463,8 @@ fn pretty_print_const_valtree(
             }
             // Aggregates, printed as array/tuple/struct/variant construction syntax.
             (ty::ValTree::Branch(_), ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) => {
-                let Some(contents) = self.tcx().try_destructure_const(
-                    ty::Const::from_value(self.tcx(), valtree, ty)
-                ) else {
-                    // Fall back to debug pretty printing for invalid constants.
-                    p!(write("{:?}", valtree));
-                    if print_ty {
-                        p!(": ", print(ty));
-                    }
-                    return Ok(self);
-                };
+                let contents =
+                    self.tcx().destructure_const(ty::Const::from_value(self.tcx(), valtree, ty));
                 let fields = contents.fields.iter().copied();
                 match *ty.kind() {
                     ty::Array(..) => {
index 998b80a36c2f7eb73ecb7e920eeb6969cfa89450..30f90e383a889d59537b0d3c3c0c32d9c0164129 100644 (file)
@@ -23,4 +23,4 @@ rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 rustc_ast = { path = "../rustc_ast" }
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
index e2399818929123e505d6153741b1b169920038a8..cdacf3ad892e0c71531e5910b0b6475b45ece6c1 100644 (file)
@@ -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),
index a0c70a3fd81f1880dda81c076e65b3022b7a4fdf..baf9735fbc846d074856d9ae49d15623e7d25ebf 100644 (file)
@@ -9,7 +9,7 @@ doctest = false
 [dependencies]
 polonius-engine = "0.13.0"
 regex = "1"
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 rustc_ast = { path = "../rustc_ast" }
 rustc_data_structures = { path = "../rustc_data_structures" }
index 8a8098e9ab996db255c48ecc2310389576fca848..85b7a4af598947f889afc30da19fdc77628cd161 100644 (file)
@@ -8,7 +8,7 @@ doctest = false
 
 [dependencies]
 itertools = "0.10.1"
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 rustc_ast = { path = "../rustc_ast" }
 rustc_attr = { path = "../rustc_attr" }
index 0495439385beec0d65cee6a47e40a3cdbd1f637c..0f87e638d2618e2ea92aa756008ed40f0a230c03 100644 (file)
@@ -33,8 +33,9 @@ fn is_stable(place: PlaceRef<'_>) -> bool {
     })
 }
 
-/// Determine whether this type may be a reference (or box), and thus needs retagging.
-fn may_be_reference(ty: Ty<'_>) -> bool {
+/// Determine whether this type may contain a reference (or box), and thus needs retagging.
+/// We will only recurse `depth` times into Tuples/ADTs to bound the cost of this.
+fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> bool {
     match ty.kind() {
         // Primitive types that are not references
         ty::Bool
@@ -50,8 +51,20 @@ fn may_be_reference(ty: Ty<'_>) -> bool {
         // References
         ty::Ref(..) => true,
         ty::Adt(..) if ty.is_box() => true,
-        // Compound types are not references
-        ty::Array(..) | ty::Slice(..) | ty::Tuple(..) | ty::Adt(..) => false,
+        // Compound types: recurse
+        ty::Array(ty, _) | ty::Slice(ty) => {
+            // This does not branch so we keep the depth the same.
+            may_contain_reference(*ty, depth, tcx)
+        }
+        ty::Tuple(tys) => {
+            depth == 0 || tys.iter().any(|ty| may_contain_reference(ty, depth - 1, tcx))
+        }
+        ty::Adt(adt, subst) => {
+            depth == 0
+                || adt.variants().iter().any(|v| {
+                    v.fields.iter().any(|f| may_contain_reference(f.ty(tcx, subst), depth - 1, tcx))
+                })
+        }
         // Conservative fallback
         _ => true,
     }
@@ -83,7 +96,7 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
             // FIXME: Instead of giving up for unstable places, we should introduce
             // a temporary and retag on that.
             is_stable(place.as_ref())
-                && may_be_reference(place.ty(&*local_decls, tcx).ty)
+                && may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx)
                 && is_not_temp(&local_decls[place.local])
         };
         let place_base_raw = |place: &Place<'tcx>| {
index e4ac47f4982cbd60debb0f9ca2fd36c3d53e3d8e..41ba4d4b64a34143376e9421da4719b145725d6c 100644 (file)
@@ -7,7 +7,7 @@ edition = "2021"
 doctest = false
 
 [dependencies]
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 tracing = "0.1"
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_hir = { path = "../rustc_hir" }
index b5a37cf324b008fa10c4351cec36e95adecc34e5..b7787aeb8f7655a60b4a114adc36c5536982886b 100644 (file)
@@ -22,7 +22,7 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 parking_lot = "0.11"
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 
 [features]
 rustc_use_parallel_compiler = ["rustc-rayon-core"]
index 8bd8eb488b70721af7e381701a7671edafe369bc..5d2b606b43cd5638a2213f781c7249d1409152c0 100644 (file)
@@ -24,4 +24,4 @@ rustc_metadata = { path = "../rustc_metadata" }
 rustc_query_system = { path = "../rustc_query_system" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
index f6b9e17e58ed9a97105260f881a98444ae5a6f45..5056163b7fe7de5453e1928a19e4e9be8e9eb31b 100644 (file)
@@ -5,7 +5,7 @@ edition = "2021"
 
 [dependencies]
 indexmap = "1.8.0"
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 
 [dev-dependencies]
 rustc_macros = { path = "../rustc_macros" }
index d59bdae0332cb3001868854c7744692c059d68a3..aebeb49e623b9a36cdb6450dd8095ed7a5a49b2c 100644 (file)
@@ -23,4 +23,4 @@ rustc_query_system = { path = "../rustc_query_system" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
index 5d08ea99ac64a2975c3917fda763de80518eae22..424eff2f6212a6dfcb71b1792781cbae049fd05a 100644 (file)
@@ -236,7 +236,7 @@ pub fn new(
     ) -> Result<Option<AbstractConst<'tcx>>, ErrorGuaranteed> {
         let inner = tcx.thir_abstract_const_opt_const_arg(uv.def)?;
         debug!("AbstractConst::new({:?}) = {:?}", uv, inner);
-        Ok(inner.map(|inner| AbstractConst { inner, substs: uv.substs }))
+        Ok(inner.map(|inner| AbstractConst { inner, substs: tcx.erase_regions(uv.substs) }))
     }
 
     pub fn from_const(
@@ -416,6 +416,7 @@ fn build(mut self) -> Result<&'tcx [Node<'tcx>], ErrorGuaranteed> {
                     // `AbstractConst`s should not contain any promoteds as they require references which
                     // are not allowed.
                     assert_eq!(ct.promoted, None);
+                    assert_eq!(ct, self.tcx.erase_regions(ct));
                 }
             }
         }
index af0803fbd54148e45279488e96eff7d3c95f4639..debb9e8295122ad06bc8d0c929f8b9429d824b12 100644 (file)
@@ -484,10 +484,9 @@ fn report_selection_error(
                             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 @@ fn report_projection_error(
                     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(
index fbe66d7dcdd2bd98e0fb4589383139017178fdba..12858172ee554288d8ca6198b3216f622ab7ca92 100644 (file)
@@ -2217,9 +2217,10 @@ fn note_obligation_cause_code<T>(
                     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)
                 ));
             }
index 5942bb79d69e8945de8411b0cac237f4908cac84..e1131140c39e881618139d2b1ecf491669ef19f5 100644 (file)
@@ -813,7 +813,7 @@ fn confirm_trait_upcasting_unsize_candidate(
                 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 @@ fn confirm_builtin_unsize_candidate(
                 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 @@ fn confirm_builtin_unsize_candidate(
                 let cause = ObligationCause::new(
                     obligation.cause.span,
                     obligation.cause.body_id,
-                    ObjectCastObligation(target),
+                    ObjectCastObligation(source, target),
                 );
 
                 let predicate_to_obligation = |predicate| {
index 67f878df31cb545bae51629fb464773c91f13402..951554c77fbb567b0f2476a38df68f019fd3b676 100644 (file)
@@ -15,6 +15,6 @@ rustc_span = { path = "../rustc_span" }
 chalk-ir = "0.80.0"
 chalk-engine = "0.80.0"
 chalk-solve = "0.80.0"
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 rustc_infer = { path = "../rustc_infer" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
new file mode 100644 (file)
index 0000000..0b83cdb
--- /dev/null
@@ -0,0 +1,77 @@
+use rustc_middle::ty::{self, TyCtxt};
+use rustc_target::abi::VariantIdx;
+
+use std::iter;
+
+/// Destructures array, ADT or tuple constants into the constants
+/// of their fields.
+pub(crate) fn destructure_const<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    const_: ty::Const<'tcx>,
+) -> ty::DestructuredConst<'tcx> {
+    let ty::ConstKind::Value(valtree) = const_.kind() else {
+        bug!("cannot destructure constant {:?}", const_)
+    };
+
+    let branches = match valtree {
+        ty::ValTree::Branch(b) => b,
+        _ => bug!("cannot destructure constant {:?}", const_),
+    };
+
+    let (fields, variant) = match const_.ty().kind() {
+        ty::Array(inner_ty, _) | ty::Slice(inner_ty) => {
+            // construct the consts for the elements of the array/slice
+            let field_consts = branches
+                .iter()
+                .map(|b| tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Value(*b), ty: *inner_ty }))
+                .collect::<Vec<_>>();
+            debug!(?field_consts);
+
+            (field_consts, None)
+        }
+        ty::Adt(def, _) if def.variants().is_empty() => bug!("unreachable"),
+        ty::Adt(def, substs) => {
+            let (variant_idx, branches) = if def.is_enum() {
+                let (head, rest) = branches.split_first().unwrap();
+                (VariantIdx::from_u32(head.unwrap_leaf().try_to_u32().unwrap()), rest)
+            } else {
+                (VariantIdx::from_u32(0), branches)
+            };
+            let fields = &def.variant(variant_idx).fields;
+            let mut field_consts = Vec::with_capacity(fields.len());
+
+            for (field, field_valtree) in iter::zip(fields, branches) {
+                let field_ty = field.ty(tcx, substs);
+                let field_const = tcx.mk_const(ty::ConstS {
+                    kind: ty::ConstKind::Value(*field_valtree),
+                    ty: field_ty,
+                });
+                field_consts.push(field_const);
+            }
+            debug!(?field_consts);
+
+            (field_consts, Some(variant_idx))
+        }
+        ty::Tuple(elem_tys) => {
+            let fields = iter::zip(*elem_tys, branches)
+                .map(|(elem_ty, elem_valtree)| {
+                    tcx.mk_const(ty::ConstS {
+                        kind: ty::ConstKind::Value(*elem_valtree),
+                        ty: elem_ty,
+                    })
+                })
+                .collect::<Vec<_>>();
+
+            (fields, None)
+        }
+        _ => bug!("cannot destructure constant {:?}", const_),
+    };
+
+    let fields = tcx.arena.alloc_from_iter(fields.into_iter());
+
+    ty::DestructuredConst { variant, fields }
+}
+
+pub fn provide(providers: &mut ty::query::Providers) {
+    *providers = ty::query::Providers { destructure_const, ..*providers };
+}
index 484967bbef8ce838d3a57ceee6cfd986264625f3..7624d31b40bc7d851df965b3c06476b9c89a9153 100644 (file)
@@ -18,6 +18,7 @@
 
 mod assoc;
 mod common_traits;
+mod consts;
 pub mod instance;
 mod needs_drop;
 pub mod representability;
@@ -26,6 +27,7 @@
 pub fn provide(providers: &mut Providers) {
     assoc::provide(providers);
     common_traits::provide(providers);
+    consts::provide(providers);
     needs_drop::provide(providers);
     ty::provide(providers);
     instance::provide(providers);
index b8066f2e5d89186f73191fb623400c1ec3593065..5aa3cf017fa687d0fc392f42863a9f5ab0ad96d5 100644 (file)
@@ -12,4 +12,4 @@ rustc_index = { path = "../rustc_index" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_macros = { path = "../rustc_macros" }
-smallvec = { version = "1.0", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
index c08023ee6a70a50187c9c8bbf4b19f17c5d96c8b..faf52e2695a33507a26a659741d934e2453ea7ea 100644 (file)
@@ -20,7 +20,7 @@ rustc_hir = { path = "../rustc_hir" }
 rustc_hir_pretty = { path = "../rustc_hir_pretty" }
 rustc_target = { path = "../rustc_target" }
 rustc_session = { path = "../rustc_session" }
-smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
+smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 rustc_ast = { path = "../rustc_ast" }
 rustc_span = { path = "../rustc_span" }
 rustc_index = { path = "../rustc_index" }
index b7ba9d978784627a3752e6c374b067dc05d26538..7602f2550e85baa18b943bd8ad53df0faf0fb340 100644 (file)
@@ -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 @@ fn find_issue(&self) -> Option<Issue> {
     //
     // 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 @@ pub(crate) fn find_errors(mut self) -> (Vec<Error<'tcx>>, Vec<Option<usize>>) {
         // 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 @@ pub(crate) fn find_errors(mut self) -> (Vec<Error<'tcx>>, Vec<Option<usize>>) {
                 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);
                     }
index 2326c4069e483a7e8386abb1eb740d64f1645a28..dc49ff90f34b0035dd77a4a5ead4c66c8641aa99 100644 (file)
@@ -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::*;
 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};
 use std::iter;
 use std::slice;
 
-enum TupleMatchFound {
-    None,
-    Single,
-    /// Beginning and end Span
-    Multiple(Span, Span),
-}
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub(in super::super) fn check_casts(&self) {
         let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
@@ -213,13 +209,10 @@ pub(in super::super) fn check_argument_types(
         let minimum_input_count = expected_input_tys.len();
         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
-        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
         // This is more complicated than just checking type equality, as arguments could be coerced
         // This version writes those types back so further type checking uses the narrowed types
-        let demand_compatible = |idx, final_arg_types: &mut Vec<Option<(Ty<'tcx>, Ty<'tcx>)>>| {
+        let demand_compatible = |idx| {
             let formal_input_ty: Ty<'tcx> = formal_input_tys[idx];
             let expected_input_ty: Ty<'tcx> = expected_input_tys[idx];
             let provided_arg = &provided_args[idx];
@@ -238,9 +231,6 @@ pub(in super::super) fn check_argument_types(
             //    `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
             let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty);
 
-            // Keep track of these for below
-            final_arg_types[idx] = Some((checked_ty, coerced_ty));
-
             // Cause selection errors caused by resolving a single argument to point at the
             // argument and not the call. This lets us customize the span pointed to in the
             // fulfillment error to be more accurate.
@@ -249,16 +239,13 @@ pub(in super::super) fn check_argument_types(
                     self.point_at_type_arg_instead_of_call_if_possible(errors, call_expr);
                     self.point_at_arg_instead_of_call_if_possible(
                         errors,
-                        &final_arg_types,
                         call_expr,
                         call_span,
                         provided_args,
+                        &expected_input_tys,
                     );
                 });
 
-            // Make sure we store the resolved type
-            final_arg_types[idx] = Some((checked_ty, coerced_ty));
-
             let coerce_error = self
                 .try_coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None)
                 .err();
@@ -287,54 +274,10 @@ pub(in super::super) fn check_argument_types(
             }
         };
 
-        // 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,
@@ -360,10 +303,10 @@ pub(in super::super) fn check_argument_types(
                     self.point_at_type_arg_instead_of_call_if_possible(errors, call_expr);
                     self.point_at_arg_instead_of_call_if_possible(
                         errors,
-                        &final_arg_types,
                         call_expr,
                         call_span,
                         &provided_args,
+                        &expected_input_tys,
                     );
                 })
             }
@@ -392,9 +335,9 @@ pub(in super::super) fn check_argument_types(
                     continue;
                 }
 
-                let compatible = demand_compatible(idx, &mut final_arg_types);
+                let compatible = demand_compatible(idx);
                 let is_compatible = matches!(compatible, Compatibility::Compatible);
-                compatibility[idx] = compatible;
+                compatibility_diagonal[idx] = compatible;
 
                 if !is_compatible {
                     call_appears_satisfied = false;
@@ -402,70 +345,54 @@ pub(in super::super) fn check_argument_types(
             }
         }
 
-        // 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,556 +427,648 @@ pub(in super::super) fn check_argument_types(
                 Some(CtorOf::Variant) => "enum variant",
                 None => "function",
             };
-            if c_variadic && provided_arg_count < minimum_input_count {
-                err_code = "E0060";
+
+            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,
+            );
+        }
+    }
+
+    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>,
+    ) {
+        // 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();
             }
 
-            // 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;
+            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);
+            }
+
+            // Using probe here, since we don't want this subtyping to affect inference.
+            let subtyping_error = self.probe(|_| {
+                self.at(&self.misc(provided_arg.span), self.param_env)
+                    .sup(formal_input_ty, coerced_ty)
+                    .err()
+            });
+
+            // 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_error) {
+                (false, None) => Compatibility::Compatible,
+                (_, subtyping_error) => Compatibility::Incompatible(subtyping_error),
+            }
+        };
+
+        // 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
+                    .typeck_results
+                    .borrow()
+                    .expr_ty_adjusted_opt(*expr)
+                    .unwrap_or_else(|| tcx.ty_error());
+                (self.resolve_vars_if_possible(ty), expr.span)
+            })
+            .collect();
+
+        // First, check if we just need to wrap some arguments in a tuple.
+        if let Some((mismatch_idx, terr)) =
+            compatibility_diagonal.iter().enumerate().find_map(|(i, c)| {
+                if let Compatibility::Incompatible(Some(terr)) = c { Some((i, terr)) } else { None }
+            })
+        {
+            // Is the first bad expected argument a tuple?
+            // Do we have as many extra provided arguments as the tuple's length?
+            // If so, we might have just forgotten to wrap some args in a tuple.
+            if let Some(ty::Tuple(tys)) =
+                formal_and_expected_inputs.get(mismatch_idx.into()).map(|tys| tys.1.kind())
+                && provided_arg_tys.len() == formal_and_expected_inputs.len() - 1 + tys.len()
+            {
+                // Wrap up the N provided arguments starting at this position in a tuple.
+                let provided_as_tuple = tcx.mk_tup(
+                    provided_arg_tys.iter().map(|(ty, _)| *ty).skip(mismatch_idx).take(tys.len()),
+                );
+
+                let mut satisfied = true;
+                // Check if the newly wrapped tuple + rest of the arguments are compatible.
+                for ((_, expected_ty), provided_ty) in std::iter::zip(
+                    formal_and_expected_inputs.iter().skip(mismatch_idx),
+                    [provided_as_tuple].into_iter().chain(
+                        provided_arg_tys.iter().map(|(ty, _)| *ty).skip(mismatch_idx + tys.len()),
+                    ),
+                ) {
+                    if !self.can_coerce(provided_ty, *expected_ty) {
+                        satisfied = false;
+                        break;
+                    }
                 }
-                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
+
+                // If they're compatible, suggest wrapping in an arg, and we're done!
+                // Take some care with spans, so we don't suggest wrapping a macro's
+                // innards in parenthesis, for example.
+                if satisfied
+                    && let Some(lo) =
+                        provided_args[mismatch_idx.into()].span.find_ancestor_inside(error_span)
+                    && let Some(hi) = provided_args[(mismatch_idx + tys.len() - 1).into()]
+                        .span
+                        .find_ancestor_inside(error_span)
+                {
+                    let mut err;
+                    if tys.len() == 1 {
+                        // A tuple wrap suggestion actually occurs within,
+                        // so don't do anything special here.
+                        err = self.report_and_explain_type_error(
+                            TypeTrace::types(
+                                &self.misc(lo),
+                                true,
+                                formal_and_expected_inputs[mismatch_idx.into()].1,
+                                provided_arg_tys[mismatch_idx.into()].0,
+                            ),
+                            terr,
+                        );
+                        err.span_label(
+                            full_call_span,
+                            format!("arguments to this {} are incorrect", call_name),
+                        );
+                    } else {
+                        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(
+                                    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()),
+                        );
+                        err.multipart_suggestion_verbose(
+                            "wrap these arguments in parentheses to construct a tuple",
+                            vec![
+                                (lo.shrink_to_lo(), "(".to_string()),
+                                (hi.shrink_to_hi(), ")".to_string()),
+                            ],
+                            Applicability::MachineApplicable,
+                        );
+                    };
                     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;
+                    return;
                 }
             }
+        }
+
+        // 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/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;
+        }
+
+        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)
-                        } else {
-                            "/* value */".to_string()
-                        }
+                        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()
                     };
-                    suggestion += &suggestion_text;
-                    if arg_index < minimum_input_count - 1 {
-                        suggestion += ", ";
+                    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 {
+                            String::new()
+                        };
+                        labels.push((
+                            provided_span,
+                            format!("expected `{}`{}", expected_ty, provided_ty_name),
+                        ));
                     }
+
+                    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,
+            );
         }
-    }
-
-    fn suggested_tuple_wrap(
-        &self,
-        expected_input_tys: &[Ty<'tcx>],
-        provided_args: &'tcx [hir::Expr<'tcx>],
-    ) -> TupleMatchFound {
-        // Only handle the case where we expect only one tuple arg
-        let [expected_arg_type] = expected_input_tys[..] else { return TupleMatchFound::None };
-        let &ty::Tuple(expected_types) = self.resolve_vars_if_possible(expected_arg_type).kind()
-            else { return TupleMatchFound::None };
-
-        // First check that there are the same number of types.
-        if expected_types.len() != provided_args.len() {
-            return TupleMatchFound::None;
-        }
-
-        let supplied_types: Vec<_> = provided_args.iter().map(|arg| self.check_expr(arg)).collect();
-
-        let all_match = iter::zip(expected_types, supplied_types)
-            .all(|(expected, supplied)| self.can_eq(self.param_env, expected, supplied).is_ok());
 
-        if !all_match {
-            return TupleMatchFound::None;
-        }
-        match provided_args {
-            [] => TupleMatchFound::None,
-            [_] => TupleMatchFound::Single,
-            [first, .., last] => {
-                TupleMatchFound::Multiple(first.span.shrink_to_lo(), last.span.shrink_to_hi())
-            }
-        }
+        err.emit();
     }
 
     // AST fragment checking
@@ -1599,10 +1618,10 @@ fn finish_resolving_struct_path(
     fn point_at_arg_instead_of_call_if_possible(
         &self,
         errors: &mut Vec<traits::FulfillmentError<'tcx>>,
-        final_arg_types: &[Option<(Ty<'tcx>, Ty<'tcx>)>],
         expr: &'tcx hir::Expr<'tcx>,
         call_sp: Span,
         args: &'tcx [hir::Expr<'tcx>],
+        expected_tys: &[Ty<'tcx>],
     ) {
         // We *do not* do this for desugared call spans to keep good diagnostics when involving
         // the `?` operator.
@@ -1610,7 +1629,7 @@ fn point_at_arg_instead_of_call_if_possible(
             return;
         }
 
-        for error in errors {
+        'outer: for error in errors {
             // Only if the cause is somewhere inside the expression we want try to point at arg.
             // Otherwise, it means that the cause is somewhere else and we should not change
             // anything because we can break the correct span.
@@ -1635,39 +1654,65 @@ fn unpeel_to_top<'a, 'tcx>(
                     (result_code, code) = (code, parent);
                 }
             }
-            let self_: ty::subst::GenericArg<'_> = match unpeel_to_top(error.obligation.cause.code()) {
-                ObligationCauseCode::BuiltinDerivedObligation(code) |
-                ObligationCauseCode::DerivedObligation(code) => {
-                    code.parent_trait_pred.self_ty().skip_binder().into()
-                }
-                ObligationCauseCode::ImplDerivedObligation(code) => {
-                    code.derived.parent_trait_pred.self_ty().skip_binder().into()
-                }
-                _ if let ty::PredicateKind::Trait(predicate) =
-                    error.obligation.predicate.kind().skip_binder() => {
+            let self_: ty::subst::GenericArg<'_> =
+                match unpeel_to_top(error.obligation.cause.code()) {
+                    ObligationCauseCode::BuiltinDerivedObligation(code)
+                    | ObligationCauseCode::DerivedObligation(code) => {
+                        code.parent_trait_pred.self_ty().skip_binder().into()
+                    }
+                    ObligationCauseCode::ImplDerivedObligation(code) => {
+                        code.derived.parent_trait_pred.self_ty().skip_binder().into()
+                    }
+                    _ if let ty::PredicateKind::Trait(predicate) =
+                        error.obligation.predicate.kind().skip_binder() =>
+                    {
                         predicate.self_ty().into()
                     }
-                _ =>  continue,
-            };
+                    _ => continue,
+                };
             let self_ = self.resolve_vars_if_possible(self_);
+            let ty_matches_self = |ty: Ty<'tcx>| ty.walk().any(|arg| arg == self_);
+
+            let typeck_results = self.typeck_results.borrow();
+
+            for (idx, arg) in args.iter().enumerate() {
+                // Don't adjust the span if we already have a more precise span
+                // within one of the args.
+                if arg.span.contains(error.obligation.cause.span) {
+                    let references_arg =
+                        typeck_results.expr_ty_opt(arg).map_or(false, &ty_matches_self)
+                            || expected_tys.get(idx).copied().map_or(false, &ty_matches_self);
+                    if references_arg && !arg.span.from_expansion() {
+                        error.obligation.cause.map_code(|parent_code| {
+                            ObligationCauseCode::FunctionArgumentObligation {
+                                arg_hir_id: args[idx].hir_id,
+                                call_hir_id: expr.hir_id,
+                                parent_code,
+                            }
+                        })
+                    }
+                    continue 'outer;
+                }
+            }
 
             // Collect the argument position for all arguments that could have caused this
             // `FulfillmentError`.
-            let mut referenced_in = final_arg_types
-                .iter()
+            let mut referenced_in: Vec<_> = std::iter::zip(expected_tys, args)
                 .enumerate()
-                .filter_map(|(i, arg)| match arg {
-                    Some((checked_ty, coerce_ty)) => Some([(i, *checked_ty), (i, *coerce_ty)]),
-                    _ => None,
+                .flat_map(|(idx, (expected_ty, arg))| {
+                    if let Some(arg_ty) = typeck_results.expr_ty_opt(arg) {
+                        vec![(idx, arg_ty), (idx, *expected_ty)]
+                    } else {
+                        vec![]
+                    }
                 })
-                .flatten()
-                .flat_map(|(i, ty)| {
+                .filter_map(|(i, ty)| {
                     let ty = self.resolve_vars_if_possible(ty);
                     // We walk the argument type because the argument's type could have
                     // been `Option<T>`, but the `FulfillmentError` references `T`.
-                    if ty.walk().any(|arg| arg == self_) { Some(i) } else { None }
+                    if ty_matches_self(ty) { Some(i) } else { None }
                 })
-                .collect::<Vec<usize>>();
+                .collect();
 
             // Both checked and coerced types could have matched, thus we need to remove
             // duplicates.
@@ -1676,18 +1721,18 @@ fn unpeel_to_top<'a, 'tcx>(
             referenced_in.sort_unstable();
             referenced_in.dedup();
 
-            if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
+            if let &[idx] = &referenced_in[..] {
                 // Do not point at the inside of a macro.
                 // That would often result in poor error messages.
-                if args[ref_in].span.from_expansion() {
-                    return;
+                if args[idx].span.from_expansion() {
+                    continue;
                 }
                 // We make sure that only *one* argument matches the obligation failure
                 // and we assign the obligation's span to its expression's.
-                error.obligation.cause.span = args[ref_in].span;
+                error.obligation.cause.span = args[idx].span;
                 error.obligation.cause.map_code(|parent_code| {
                     ObligationCauseCode::FunctionArgumentObligation {
-                        arg_hir_id: args[ref_in].hir_id,
+                        arg_hir_id: args[idx].hir_id,
                         call_hir_id: expr.hir_id,
                         parent_code,
                     }
index e622192f2c94dab0b2fb10010938780275e3b509..82103c5a03b6e04fe52fcf2ba3ba2af3ed57b1f5 100644 (file)
@@ -37,6 +37,11 @@ fn crate_variances(tcx: TyCtxt<'_>, (): ()) -> CrateVariancesMap<'_> {
 }
 
 fn variances_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[ty::Variance] {
+    // Skip items with no generics - there's nothing to infer in them.
+    if tcx.generics_of(item_def_id).count() == 0 {
+        return &[];
+    }
+
     match tcx.def_kind(item_def_id) {
         DefKind::Fn
         | DefKind::AssocFn
index 203e5dff0c77fad78eac07b673ab97306098f550..09308d4d0906d3e1abcd7d5403e728477f52906f 100644 (file)
@@ -3,7 +3,9 @@
 // by matthieu-m
 use crate::alloc::{self, Layout, LayoutError};
 use core::fmt::{self, Debug, Display, Formatter};
-use core::marker::{PhantomData, Unsize};
+use core::marker::PhantomData;
+#[cfg(not(no_global_oom_handling))]
+use core::marker::Unsize;
 use core::mem;
 use core::ops::{Deref, DerefMut};
 use core::ptr::Pointee;
index 4be5f6cf9ca514773cf8857dce2058e43c46b5fd..b0f4529abdfa5eb0f48727edb02952895c91d9b2 100644 (file)
@@ -421,6 +421,7 @@ fn grow_exact(&mut self, len: usize, additional: usize) -> Result<(), TryReserve
         Ok(())
     }
 
+    #[cfg(not(no_global_oom_handling))]
     fn shrink(&mut self, cap: usize) -> Result<(), TryReserveError> {
         assert!(cap <= self.capacity(), "Tried to shrink to a larger capacity");
 
index 8883880726594f29fbbfc9296642001a90971db1..b1513e5e0f31c50db71835ad98ebc723e571a961 100644 (file)
@@ -46,9 +46,9 @@
 use core::char::{decode_utf16, REPLACEMENT_CHARACTER};
 use core::fmt;
 use core::hash;
+use core::iter::FusedIterator;
 #[cfg(not(no_global_oom_handling))]
-use core::iter::FromIterator;
-use core::iter::{from_fn, FusedIterator};
+use core::iter::{from_fn, FromIterator};
 #[cfg(not(no_global_oom_handling))]
 use core::ops::Add;
 #[cfg(not(no_global_oom_handling))]
index 9b84a1d9b4b641594887d028c961a35e77632e2d..28979457b7fd389049ee21ef83308be1264949c5 100644 (file)
@@ -9,6 +9,7 @@
 };
 use core::marker::PhantomData;
 use core::mem::{self, ManuallyDrop};
+#[cfg(not(no_global_oom_handling))]
 use core::ops::Deref;
 use core::ptr::{self, NonNull};
 use core::slice::{self};
@@ -123,6 +124,7 @@ pub(super) fn forget_allocation_drop_remaining(&mut self) {
     }
 
     /// Forgets to Drop the remaining elements while still allowing the backing allocation to be freed.
+    #[cfg(not(no_global_oom_handling))]
     pub(crate) fn forget_remaining_elements(&mut self) {
         self.ptr = self.end;
     }
index 93cdf121fbe0f742a7c7270c2f5e6c36f1f7de01..43e4b7f08e22d37c96f173b39e09685bd37f9453 100644 (file)
@@ -231,7 +231,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),
     target_family = "wasm",
     target_arch = "asmjs",
-    windows
+    target_os = "uefi",
+    windows,
 ))]
 #[repr(transparent)]
 #[unstable(
@@ -254,7 +255,8 @@ pub struct VaListImpl<'f> {
     all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),
     target_family = "wasm",
     target_arch = "asmjs",
-    windows
+    target_os = "uefi",
+    windows,
 ))]
 #[unstable(
     feature = "c_variadic",
@@ -276,7 +278,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 #[cfg(all(
     target_arch = "aarch64",
     not(any(target_os = "macos", target_os = "ios")),
-    not(windows)
+    not(target_os = "uefi"),
+    not(windows),
 ))]
 #[repr(C)]
 #[derive(Debug)]
@@ -297,7 +300,7 @@ pub struct VaListImpl<'f> {
 }
 
 /// PowerPC ABI implementation of a `va_list`.
-#[cfg(all(target_arch = "powerpc", not(windows)))]
+#[cfg(all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)))]
 #[repr(C)]
 #[derive(Debug)]
 #[unstable(
@@ -317,7 +320,7 @@ pub struct VaListImpl<'f> {
 }
 
 /// x86_64 ABI implementation of a `va_list`.
-#[cfg(all(target_arch = "x86_64", not(windows)))]
+#[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)))]
 #[repr(C)]
 #[derive(Debug)]
 #[unstable(
@@ -354,7 +357,8 @@ pub struct VaList<'a, 'f: 'a> {
         all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),
         target_family = "wasm",
         target_arch = "asmjs",
-        windows
+        target_os = "uefi",
+        windows,
     ))]
     inner: VaListImpl<'f>,
 
@@ -363,7 +367,8 @@ pub struct VaList<'a, 'f: 'a> {
         any(not(target_arch = "aarch64"), not(any(target_os = "macos", target_os = "ios"))),
         not(target_family = "wasm"),
         not(target_arch = "asmjs"),
-        not(windows)
+        not(target_os = "uefi"),
+        not(windows),
     ))]
     inner: &'a mut VaListImpl<'f>,
 
@@ -375,7 +380,8 @@ pub struct VaList<'a, 'f: 'a> {
     all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")),
     target_family = "wasm",
     target_arch = "asmjs",
-    windows
+    target_os = "uefi",
+    windows,
 ))]
 #[unstable(
     feature = "c_variadic",
@@ -396,7 +402,8 @@ pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
     any(not(target_arch = "aarch64"), not(any(target_os = "macos", target_os = "ios"))),
     not(target_family = "wasm"),
     not(target_arch = "asmjs"),
-    not(windows)
+    not(target_os = "uefi"),
+    not(windows),
 ))]
 #[unstable(
     feature = "c_variadic",
index 2f9afbec91e98686c2b649e6f5fe62f1d7a0af80..d230c06a2112f87251f8063d95c3c0806cddc360 100644 (file)
@@ -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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     ///
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// [`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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// 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 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     /// [`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.
index a66ecc35bbdb105290b517430b7840056eeb1ac2..90e2dfd5d3d9ba788721df524b7ef723b49c53e6 100644 (file)
@@ -854,6 +854,42 @@ pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
         unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 }
     }
 
+    /// Logical "not" with a boolean value.
+    ///
+    /// Performs a logical "not" operation on the current value, and sets
+    /// the new value to the result.
+    ///
+    /// Returns the previous value.
+    ///
+    /// `fetch_not` takes an [`Ordering`] argument which describes the memory ordering
+    /// of this operation. All ordering modes are possible. Note that using
+    /// [`Acquire`] makes the store part of this operation [`Relaxed`], and
+    /// using [`Release`] makes the load part [`Relaxed`].
+    ///
+    /// **Note:** This method is only available on platforms that support atomic
+    /// operations on `u8`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(atomic_bool_fetch_not)]
+    /// use std::sync::atomic::{AtomicBool, Ordering};
+    ///
+    /// let foo = AtomicBool::new(true);
+    /// assert_eq!(foo.fetch_not(Ordering::SeqCst), true);
+    /// assert_eq!(foo.load(Ordering::SeqCst), false);
+    ///
+    /// let foo = AtomicBool::new(false);
+    /// assert_eq!(foo.fetch_not(Ordering::SeqCst), false);
+    /// assert_eq!(foo.load(Ordering::SeqCst), true);
+    /// ```
+    #[inline]
+    #[unstable(feature = "atomic_bool_fetch_not", issue = "98485")]
+    #[cfg(target_has_atomic = "8")]
+    pub fn fetch_not(&self, order: Ordering) -> bool {
+        self.fetch_xor(true, order)
+    }
+
     /// Returns a mutable pointer to the underlying [`bool`].
     ///
     /// Doing non-atomic reads and writes on the resulting integer can be a data race.
@@ -2575,11 +2611,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 +2625,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 +2640,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 +2656,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 +2672,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 +2693,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 +2728,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 +2757,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 +2772,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 +2787,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 +2802,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 +2818,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 +2834,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 +2850,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 +2866,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 +2956,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 +3038,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"),
         }
     }
index dca782c29c252f72ac6087787ac559541ff28cd2..759a99c330c279d1aec9714b7eaae757908a315b 100644 (file)
@@ -61,6 +61,30 @@ fn cc2ar(cc: &Path, target: TargetSelection) -> Option<PathBuf> {
     }
 }
 
+fn new_cc_build(build: &Build, target: TargetSelection) -> cc::Build {
+    let mut cfg = cc::Build::new();
+    cfg.cargo_metadata(false)
+        .opt_level(2)
+        .warnings(false)
+        .debug(false)
+        .target(&target.triple)
+        .host(&build.build.triple);
+    match build.crt_static(target) {
+        Some(a) => {
+            cfg.static_crt(a);
+        }
+        None => {
+            if target.contains("msvc") {
+                cfg.static_crt(true);
+            }
+            if target.contains("musl") {
+                cfg.static_flag(true);
+            }
+        }
+    }
+    cfg
+}
+
 pub fn find(build: &mut Build) {
     // For all targets we're going to need a C compiler for building some shims
     // and such as well as for being a linker for Rust code.
@@ -72,27 +96,7 @@ pub fn find(build: &mut Build) {
         .chain(iter::once(build.build))
         .collect::<HashSet<_>>();
     for target in targets.into_iter() {
-        let mut cfg = cc::Build::new();
-        cfg.cargo_metadata(false)
-            .opt_level(2)
-            .warnings(false)
-            .debug(false)
-            .target(&target.triple)
-            .host(&build.build.triple);
-        match build.crt_static(target) {
-            Some(a) => {
-                cfg.static_crt(a);
-            }
-            None => {
-                if target.contains("msvc") {
-                    cfg.static_crt(true);
-                }
-                if target.contains("musl") {
-                    cfg.static_flag(true);
-                }
-            }
-        }
-
+        let mut cfg = new_cc_build(build, target);
         let config = build.config.target_config.get(&target);
         if let Some(cc) = config.and_then(|c| c.cc.as_ref()) {
             cfg.compiler(cc);
@@ -112,15 +116,8 @@ pub fn find(build: &mut Build) {
 
         // If we use llvm-libunwind, we will need a C++ compiler as well for all targets
         // We'll need one anyways if the target triple is also a host triple
-        let mut cfg = cc::Build::new();
-        cfg.cargo_metadata(false)
-            .opt_level(2)
-            .warnings(false)
-            .debug(false)
-            .cpp(true)
-            .target(&target.triple)
-            .host(&build.build.triple);
-
+        let mut cfg = new_cc_build(build, target);
+        cfg.cpp(true);
         let cxx_configured = if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) {
             cfg.compiler(cxx);
             true
index 78470e8deb342567c5251285498a572f7a56f7bd..0bd72625f150989e21579681e2e6b98ad3277518 100644 (file)
@@ -14,7 +14,7 @@ pulldown-cmark = { version = "0.9", default-features = false }
 minifier = "0.2.1"
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
-smallvec = "1.6.1"
+smallvec = "1.8.1"
 tempfile = "3"
 itertools = "0.10.1"
 regex = "1"
index 70dbfd444254070184ee241350caeaf3ce7b83bb..c33e2727744384c7defdde3679032d739525c0e1 100644 (file)
@@ -412,14 +412,15 @@ function loadCss(cssFileName) {
         window.hidePopoverMenus();
     }
 
-    const disableShortcuts = getSettingValue("disable-shortcuts") === "true";
     function handleShortcut(ev) {
         // Don't interfere with browser shortcuts
+        const disableShortcuts = getSettingValue("disable-shortcuts") === "true";
         if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts) {
             return;
         }
 
-        if (document.activeElement.tagName === "INPUT") {
+        if (document.activeElement.tagName === "INPUT" &&
+            document.activeElement.type !== "checkbox") {
             switch (getVirtualKey(ev)) {
             case "Escape":
                 handleEscape(ev);
@@ -926,6 +927,7 @@ function loadCss(cssFileName) {
     function showHelp() {
         const menu = getHelpMenu(true);
         if (menu.style.display === "none") {
+            window.hidePopoverMenus();
             menu.style.display = "";
         }
     }
@@ -939,6 +941,8 @@ function loadCss(cssFileName) {
         const shouldShowHelp = menu.style.display === "none";
         if (shouldShowHelp) {
             showHelp();
+        } else {
+            window.hidePopoverMenus();
         }
     });
 
index 69742d6bc3b6a324f9ef2818a85e1ba97ecd07d2..c8c45da19137fb20ee213f7815402a6e3ad7a567 100644 (file)
@@ -129,6 +129,7 @@ fn array_casts() -> () {
         _18 = &(*_35);                   // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
         Retag(_18);                      // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
         _13 = (move _14, move _18);      // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+        Retag(_13);                      // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
         StorageDead(_18);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
         StorageDead(_14);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
         StorageLive(_20);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
@@ -171,6 +172,7 @@ fn array_casts() -> () {
         Retag(_32);                      // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
         StorageLive(_34);                // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
         _34 = Option::<Arguments>::None; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
+        Retag(_34);                      // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
         _28 = core::panicking::assert_failed::<usize, usize>(move _29, move _30, move _32, move _34); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
                                          // mir::Constant
                                          // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
index 6e25eb7e459454516a0411e31716a57850764316..eb6ad9bd1a7dab999a56517be4dccf1e6763bea7 100644 (file)
@@ -1,4 +1,4 @@
 -include ../tools.mk
 
 all:
-       $(RUSTC) --edition=2021 --crate-type=rlib ../../../../library/alloc/src/lib.rs --cfg no_global_oom_handling
+       $(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../../library/alloc/src/lib.rs --cfg no_global_oom_handling
index e9b28504a907a4c5fa02769f49ab0d15180b89e9..47d90b1856be51ad7701c19df3a798b451cd6083 100644 (file)
@@ -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);
 }
index ba2986e969a3506d0adf8601fa8b31cd736a6b29..54f3790a7652198942d963d2bc8778c7a1db89d4 100644 (file)
@@ -24,6 +24,11 @@ click: "#help-button"
 assert-css: ("#help-button .popover", {"display": "block"})
 assert-css: ("#settings-menu .popover", {"display": "none"})
 
+// Now verify that clicking the help menu again closes it.
+click: "#help-button"
+assert-css: ("#help-button .popover", {"display": "none"})
+assert-css: ("#settings-menu .popover", {"display": "none"})
+
 // We check the borders color now:
 
 // Ayu theme
index 237a4751a8d6677c669d7c14ac91e4976e5dc783..c402c7991c8bbe6f1bb39d564ea2d05ec1a9588e 100644 (file)
@@ -121,6 +121,20 @@ local-storage: {"rustdoc-disable-shortcuts": "false"}
 click: ".setting-line:last-child .toggle .label"
 assert-local-storage: {"rustdoc-disable-shortcuts": "true"}
 
+// Make sure that "Disable keyboard shortcuts" actually took effect.
+press-key: "Escape"
+press-key: "?"
+assert-false: "#help-button .popover"
+wait-for-css: ("#settings-menu .popover", {"display": "block"})
+
+// Now turn keyboard shortcuts back on, and see if they work.
+click: ".setting-line:last-child .toggle .label"
+assert-local-storage: {"rustdoc-disable-shortcuts": "false"}
+press-key: "Escape"
+press-key: "?"
+wait-for-css: ("#help-button .popover", {"display": "block"})
+assert-css: ("#settings-menu .popover", {"display": "none"})
+
 // Now we go to the settings page to check that the CSS is loaded as expected.
 goto: file://|DOC_PATH|/settings.html
 wait-for: "#settings"
index dd4812b5b258985dd603b9eb3c8555a543f5dee5..c495ad6b842f8bb8056b819e23b3e0869e0ff7c1 100644 (file)
@@ -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
index 9b63f9bcbfae4c1e404ad071ab72b75f86613570..32b1e15737ab9370bc007fd78b5fe2ffa9e61efd 100644 (file)
@@ -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
index 2af24d521f380e9fa48d9c12646587ef4b1eec58..9589e919c0a1f15f0ad9359949eb8f75f92d35bd 100644 (file)
@@ -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);
index 3fe4473a594e03d7abe25fde8f71596a72376686..a52a30d7884f899f2ea3c8be9aa17444fd9962ab 100644 (file)
@@ -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
    |
index f1dcd34066dbc6bfda6d3db2cf565f5029f53ef2..f40e6585b38b1e4fd9356378b0c5a30ab7a4c17d 100644 (file)
@@ -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
 
index 521907a60445c4c1c423935c5f16e9524d7443bf..bed63a5e6df03d20aabd3eaa00a673777e137d8d 100644 (file)
@@ -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
 
index 9f1abf2a6c4b60a3990d6c63c353e9877797ef2c..dbd9a44ed97743769c32d37bb19b086f0be6ecb6 100644 (file)
@@ -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
 
index e468a1b3ba4842568b2b8443dc07f613af311c7c..419de689c52da9206a8ae88da10ee81ef3134cc5 100644 (file)
@@ -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
 
index 4cef4db4698a711d278ae0d4c061127c1ca4c577..c22302cdc2626b502646d8cf5cc2ff9d0101e1e8 100644 (file)
@@ -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
 
index e0818337d203915f6331f43da805997eaabe05c4..e5887689690e76fd5066d2193ae5613782cfe0b2 100644 (file)
@@ -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
index 5bbc20359c64a09f3c1fd762dbc50a0369bc077d..0e21dba980debf96e87594ac89a2370198a9619b 100644 (file)
@@ -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)
index 2cd6d1abfdcdb2385c6e271f695aa1e3938ea3d6..695b01d5ee3ad7798092c953c21d9c3283cd4088 100644 (file)
@@ -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
index 0866f54b9fab6237b1ab07ed15ba9860d5579868..c99c0f77982edecf4a03edc402f7f8afb3526755 100644 (file)
@@ -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
index 2b1ab2f705057cc4da4c307cbc9e9f1cfd95d702..1598cd5d3c86fa98c005b47f2f725775a809d0f6 100644 (file)
@@ -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
index 80acaa7d21c52dcb3c18fe8de398b70db7009fbc..13033962142fa51583cd5065639db7221824a981 100644 (file)
@@ -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
index 3b1fbf4b69902828b695ec08fca20bdc6bac12c7..67407c1eae3cfe2bf2144e0e97609146d26de3b2 100644 (file)
@@ -9,7 +9,8 @@ fn get_inner_ref(&self) -> &Vec<usize> {
 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
 }
index 535d247452a59a21d47474e0cffa653735fdf02d..12d8d27c5f0264906276f2753ff25ce4260e8d4e 100644 (file)
@@ -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
index 32a65d3b5bb0f472b341a95cfeb90c9a064abd66..62b1183e71b4beb03ce8fa9de7fc83b69533cbd5 100644 (file)
@@ -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 (file)
index 0000000..1dcf046
--- /dev/null
@@ -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 (file)
index 0000000..af26169
--- /dev/null
@@ -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`.
index 3350d1efb53182bb9220f24abbdff33afb66e827..980da536034327a835894f851eca4c78250aec07 100644 (file)
@@ -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
 
index fcd2d7f78ff75fb2d756ae3d818faf52be07ac37..322681b97bccb0c516d5140ebca68dba8be503b3 100644 (file)
@@ -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
 
index 60dc96f675a8b680893c4f84f48d5bf42a12b50e..da85b2059f0a390d6d2e401bf2f6a4021c73cc6d 100644 (file)
@@ -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/const-generics/issue-66451.rs b/src/test/ui/const-generics/issue-66451.rs
new file mode 100644 (file)
index 0000000..3335f7d
--- /dev/null
@@ -0,0 +1,28 @@
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
+
+#[derive(Debug, PartialEq, Eq)]
+struct Foo {
+    value: i32,
+    nested: &'static Bar<i32>,
+}
+
+#[derive(Debug, PartialEq, Eq)]
+struct Bar<T>(T);
+
+struct Test<const F: Foo>;
+
+fn main() {
+    let x: Test<{
+        Foo {
+            value: 3,
+            nested: &Bar(4),
+        }
+    }> = Test;
+    let y: Test<{
+        Foo {
+            value: 3,
+            nested: &Bar(5),
+        }
+    }> = x; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/const-generics/issue-66451.stderr b/src/test/ui/const-generics/issue-66451.stderr
new file mode 100644 (file)
index 0000000..b691eac
--- /dev/null
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-66451.rs:27:10
+   |
+LL |       let y: Test<{
+   |  ____________-
+LL | |         Foo {
+LL | |             value: 3,
+LL | |             nested: &Bar(5),
+LL | |         }
+LL | |     }> = x;
+   | |      -   ^ expected `Foo { value: 3_i32, nested: &Bar::<i32>(5_i32) }`, found `Foo { value: 3_i32, nested: &Bar::<i32>(4_i32) }`
+   | |______|
+   |        expected due to this
+   |
+   = note: expected struct `Test<Foo { value: 3_i32, nested: &Bar::<i32>(5_i32) }>`
+              found struct `Test<Foo { value: 3_i32, nested: &Bar::<i32>(4_i32) }>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/try_unify_ignore_lifetimes.rs b/src/test/ui/const-generics/try_unify_ignore_lifetimes.rs
new file mode 100644 (file)
index 0000000..2ae0ae7
--- /dev/null
@@ -0,0 +1,33 @@
+// check-pass
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+struct Num<const N: usize>;
+
+trait NumT {
+    const VALUE: usize;
+}
+
+impl<const N: usize> NumT for Num<N> {
+    const VALUE: usize = N;
+}
+
+struct Foo<'a, N: NumT>(&'a [u32; N::VALUE]) where [(); N::VALUE]:;
+
+trait Bar {
+    type Size: NumT;
+
+    fn bar<'a>(foo: &Foo<'a, Self::Size>) where [(); Self::Size::VALUE]: {
+        todo!();
+    }
+}
+
+trait Baz<'a> {
+    type Size: NumT;
+
+    fn baz(foo: &Foo<'a, Self::Size>) where [(); Self::Size::VALUE]: {
+        todo!();
+    }
+}
+
+fn main() {}
index e848ddc55b7dff8be1152ab5cbfdef8a7dc9bebd..61061ae529d1275939a7870d33751aec94c34e40 100644 (file)
@@ -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
index 121c76a01a5de19b83e5ae4dd8644d45cbed8431..594acff853a0eb5b805917f162ffa8f0c489aff6 100644 (file)
@@ -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
 
index 6bcd70cbaad4571710d5c4d28fc23d018b64a21d..d38af3f89c21b84d8d400375ad8e8b1dd3234ed0 100644 (file)
@@ -1,14 +1,14 @@
-error[E0161]: cannot move a value of type str: the size of str cannot be statically determined
+error[E0161]: cannot move a value of type `str`
   --> $DIR/dst-index.rs:31:5
    |
 LL |     S[0];
-   |     ^^^^
+   |     ^^^^ the size of `str` cannot be statically determined
 
-error[E0161]: cannot move a value of type dyn Debug: the size of dyn Debug cannot be statically determined
+error[E0161]: cannot move a value of type `dyn Debug`
   --> $DIR/dst-index.rs:34:5
    |
 LL |     T[0];
-   |     ^^^^
+   |     ^^^^ the size of `dyn Debug` cannot be statically determined
 
 error[E0507]: cannot move out of index of `S`
   --> $DIR/dst-index.rs:31:5
index 5bd47736626da0ff49523f7c8740f44ad88d3f1b..e24c96ebed63354936d9684b11dd0eede763d84e 100644 (file)
@@ -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
 
index 3697b5fcf154d04ae460efc70bb86f68960e359a..2307f52c93bceb8aa8f0fffab4c8806998ed0092 100644 (file)
@@ -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
index fb578cda17e9f3b6fce0e9a14c51639e9eb0f999..15d98b657a262a01a79937fba825a375d16cc57d 100644 (file)
@@ -1,8 +1,8 @@
-error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined
+error[E0161]: cannot move a value of type `dyn Bar`
   --> $DIR/E0161.rs:16:5
    |
 LL |     x.f();
-   |     ^^^^^
+   |     ^^^^^ the size of `dyn Bar` cannot be statically determined
 
 error: aborting due to previous error
 
index 9478fc897921121405f0776b02353e0b811c03ec..9bcbd74716845fcac8462c76c3538e64037f52cf 100644 (file)
@@ -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
 
index 15e83ab5a347dfa72ed6971a59661b101fa7e97c..43e609cc59efb0eddd9b52e21acf8621ad23573e 100644 (file)
@@ -4,7 +4,7 @@ error: higher-ranked lifetime error
 LL |     v.t(|| {});
    |     ^^^^^^^^^^
    |
-   = note: could not prove [closure@$DIR/issue-59311.rs:17:9: 17:14] well-formed
+   = note: could not prove `[closure@$DIR/issue-59311.rs:17:9: 17:14] well-formed`
 
 error: higher-ranked lifetime error
   --> $DIR/issue-59311.rs:17:9
@@ -12,7 +12,7 @@ error: higher-ranked lifetime error
 LL |     v.t(|| {});
    |         ^^^^^
    |
-   = note: could not prove for<'a> &'a V: 'static
+   = note: could not prove `for<'a> &'a V: 'static`
 
 error: aborting due to 2 previous errors
 
index f65f359875bfddc3c7fbf9609619a3db54e0ae9e..f3b9d569ce3b1977a4d87a0690b529de67cb571c 100644 (file)
@@ -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)
     }
 }
index 52e891da9ba7708c3b8e2c9eea4b57ddefeea139..ce3fa7b0c05e68a7652a046ff100a63045d53b3d 100644 (file)
@@ -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);
 }
index c6e48e8b5afbabe46dac3c4666ff3195f0cc419f..b17f4347be31cce7dd97c0f4614e021e64b4f0f5 100644 (file)
@@ -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;
index 00a7f368a0fa8e290a86c4e49d38f14e4e01c7c3..85ea81ba67961e116765b353888adb88f657bb1f 100644 (file)
 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]`
 }
index ee485c21cd6969e5c892948307d72bba440b5d99..32791a8e8b7f1c870fe357c19817046327025fd7 100644 (file)
@@ -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
 
index b96b07c91a1feb9630824f6086f6b0958cfb5ac2..10a73b245ac570e6b40854f8a04b91cdbda78823 100644 (file)
@@ -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);
index edcd21ebd6b9b6b9dd2198129d92626035e172b5..b32de5b24b924f7eb74e8be819b28684c1353aec 100644 (file)
@@ -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
 
index cd96646d751f20a607346526e8841483f1bb4243..a84cb7d8c5922a4f75ee1c9dc7c4cb473966abb3 100644 (file)
@@ -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 {
index 981c3abb4bae0379ab83f451f423d7f18823b389..df8c2f739108db485ed7b8a1ed782e532fd4a545 100644 (file)
@@ -1,6 +1,6 @@
 macro_rules! some_macro {
     ($other: expr) => ({
-        $other(None) //~ NOTE argument unexpected
+        $other(None) //~ NOTE argument of type `Option<_>` unexpected
     })
 }
 
index 1013518e1dad3f6b5161a1f3e446de848cf99c35..881a6e538ee44621b9d6b7e23f9d671498a264e2 100644 (file)
@@ -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);
    |                 ^^^^^^^^^^^^^
index b4cebe2a68b5756d9f55805cf457c5b59e89a5c8..aab19a699ace08770c7e3b89e40cf6fa2d1a80a0 100644 (file)
@@ -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
index 54fd176de75f033f20935e787431d6a88d3be638..797c1085d517b1b44b9159f6252a29399d92c328 100644 (file)
@@ -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
 }
index 62bb462faa208b8ae61890000cdb7c0b2b159d33..067bdef8b6746c73a645eda9e50115ebbae0ebac 100644 (file)
@@ -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
 
index 98ed67507b1d847433ce20bf2afc5239b633b71d..f6cb1cbdc11c677df8fd6d9616a7e7c72c73ac71 100644 (file)
@@ -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
 
index 32759d2fa0ebda7b656a310f9beb685f26b4798d..902349135c549f1718ccdb6425ebd2bb7fc8fb5d 100644 (file)
@@ -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)]
index 3a5ab62ab96f6297f30326dde234260706b6d0db..72bb0782f4b4f2170b0532f1fde4e24ec4e6200b 100644 (file)
@@ -4,7 +4,7 @@ error: higher-ranked lifetime error
 LL |     foo(&10);
    |     ^^^^^^^^
    |
-   = note: could not prove for<'b, 'r> &'b (): 'r
+   = note: could not prove `for<'b, 'r> &'b (): 'r`
 
 error: aborting due to previous error
 
index 77308a2c5215a4fd95d48d5ccb940d1c29eddc1c..57662e1e265aec21e69880ffe6211b59168b8c6e 100644 (file)
@@ -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
index 79e75e655ff1f4574420dd0db7319984ef5c7bf2..f73d38f80426f551b39c177b1503345795b1b98b 100644 (file)
@@ -1,6 +1,6 @@
 struct Bug {
     A: [(); { *"" }.len()],
-    //~^ ERROR: cannot move a value of type str
+    //~^ ERROR: cannot move a value of type `str`
     //~| ERROR: cannot move out of a shared reference
 }
 
index d5262181620762c461f2b62ad2af0a35ef4dd5e1..7697a411eb481975c78efa65e13d42a844fe6226 100644 (file)
@@ -1,8 +1,8 @@
-error[E0161]: cannot move a value of type str: the size of str cannot be statically determined
+error[E0161]: cannot move a value of type `str`
   --> $DIR/issue-67947.rs:2:13
    |
 LL |     A: [(); { *"" }.len()],
-   |             ^^^^^^^
+   |             ^^^^^^^ the size of `str` cannot be statically determined
 
 error[E0507]: cannot move out of a shared reference
   --> $DIR/issue-67947.rs:2:15
index e63ca6e11de59f31bcdb5f33f0b14f4836efb691..eab8e8e80c424234eea1b862ab531d227cb9cafd 100644 (file)
@@ -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;
index 4000b2ba312455c2555613add9698829bfdae58c..cb93a7ad9008d871314e3364cd02d3ce9fd3ef37 100644 (file)
@@ -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`
    |
index 78d1a3caf4a30e379e01860e4b3fb3a65535aa4a..6b9635d4a60bcd889b794d08db7625fbf898b597 100644 (file)
@@ -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
 
index f903f26c0901dbc7af648f026080d3ade319ec5b..8e93c538217bbd2e4ec90cabd41e0b03d192fbc1 100644 (file)
@@ -12,7 +12,7 @@ trait Baz {
 }
 
 fn use_bar(t: Box<dyn Bar>) {
-    t.bar() //~ ERROR cannot move a value of type dyn Bar
+    t.bar() //~ ERROR cannot move a value of type `dyn Bar`
 }
 
 fn main() { }
index 7ccc0cbdd576bb225608fdf75289f7b0918989b0..94fdcdf263ae08843249df4f7d229f8c2181b64a 100644 (file)
@@ -1,8 +1,8 @@
-error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined
+error[E0161]: cannot move a value of type `dyn Bar`
   --> $DIR/object-safety-by-value-self-use.rs:15:5
    |
 LL |     t.bar()
-   |     ^^^^^^^
+   |     ^^^^^^^ the size of `dyn Bar` cannot be statically determined
 
 error: aborting due to previous error
 
index ecbb6ebf55b9a4ba5cb9294dd6ba47db7b823194..fdf3ca2e261b61f1fa123c5e5cac14ced80788bf 100644 (file)
@@ -1,17 +1,9 @@
 // aux-build:invalid-punct-ident.rs
-// rustc-env:RUST_BACKTRACE=0
-
-// FIXME https://github.com/rust-lang/rust/issues/59998
-// normalize-stderr-test "thread.*panicked.*proc_macro.*lib.rs.*\n" -> ""
-// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
-// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
-// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
-// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
-// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
-// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
-// normalize-stderr-test "query stack during panic:\n" -> ""
-// normalize-stderr-test "we're just showing a limited slice of the query stack\n" -> ""
-// normalize-stderr-test "end of query stack\n" -> ""
+// ignore-stage1
+// only-linux
+//
+// FIXME: This should be a normal (stage1, all platforms) test in
+// src/test/ui/proc-macro once issue #59998 is fixed.
 
 #[macro_use]
 extern crate invalid_punct_ident;
index eaf41c080faf45f1f71192e9630aa17ce47c5052..bb0a48cb16b8dc5629fb5e8faa491b559f7945eb 100644 (file)
@@ -1,5 +1,5 @@
 error: proc macro panicked
-  --> $DIR/invalid-punct-ident-1.rs:19:1
+  --> $DIR/invalid-punct-ident-1.rs:11:1
    |
 LL | invalid_punct!();
    | ^^^^^^^^^^^^^^^^
index 78b0beff0da39d6aae0af07deafac0e05ce2b58f..a6bd98ddb1977881ceb3a7d5d6ca5476e6a0258a 100644 (file)
@@ -5,10 +5,7 @@ LL | / pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 {
 LL | |
 LL | |     loop {}
 LL | | }
-   | | ^
-   | | |
-   | |_call the function in a closure: `|| unsafe { /* code */ }`
-   |   required by a bound introduced by this call
+   | |_^ call the function in a closure: `|| unsafe { /* code */ }`
    |
    = help: the trait `Fn<(proc_macro::TokenStream,)>` is not implemented for `unsafe extern "C" fn(i32, u32) -> u32 {foo}`
    = note: unsafe function cannot be called generically without an unsafe block
index 68da9f0dc88ba2f7f8923092a0cfdc3a1da61182..e676d7372e89133121c2128a816623b963703b49 100644 (file)
@@ -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 (file)
index 0000000..408732f
--- /dev/null
@@ -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 (file)
index 0000000..44c6ec1
--- /dev/null
@@ -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`.
index 3d367eca707f41dc7222bcbbb3b205fd6b10a1ea..805c75f464cd558200b0ec23d388fddd8cbd890a 100644 (file)
@@ -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
    |
index f6d158782dad2b02fdd9ec87864c4fd6d58a92ce..2448a5149654d318ef4067e2177a5e08815e4608 100644 (file)
@@ -9,7 +9,7 @@ note: tuple variant defined here
    |
 LL |     Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
    |     ^^
-help: use parentheses to construct a tuple
+help: wrap these arguments in parentheses to construct a tuple
    |
 LL |     let _: Result<(i32, i8), ()> = Ok((1, 2));
    |                                       +    +
@@ -25,7 +25,7 @@ note: tuple variant defined here
    |
 LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
    |     ^^^^
-help: use parentheses to construct a tuple
+help: wrap these arguments in parentheses to construct a tuple
    |
 LL |     let _: Option<(i32, i8, &'static str)> = Some((1, 2, "hi"));
    |                                                   +          +
@@ -97,7 +97,7 @@ note: function defined here
    |
 LL | fn two_ints(_: (i32, i32)) {
    |    ^^^^^^^^ -------------
-help: use parentheses to construct a tuple
+help: wrap these arguments in parentheses to construct a tuple
    |
 LL |     two_ints((1, 2));
    |              +    +
@@ -113,7 +113,7 @@ note: function defined here
    |
 LL | fn with_generic<T: Copy + Send>((a, b): (i32, T)) {
    |    ^^^^^^^^^^^^                 ----------------
-help: use parentheses to construct a tuple
+help: wrap these arguments in parentheses to construct a tuple
    |
 LL |     with_generic((3, 4));
    |                  +    +
@@ -129,7 +129,7 @@ note: function defined here
    |
 LL | fn with_generic<T: Copy + Send>((a, b): (i32, T)) {
    |    ^^^^^^^^^^^^                 ----------------
-help: use parentheses to construct a tuple
+help: wrap these arguments in parentheses to construct a tuple
    |
 LL |         with_generic((a, b));
    |                      +    +
index 501d083e2bc608edbdba9a0314a004b4d7fbed26..4186dc7cb35ae51a349ddb7af70931217a157d84 100644 (file)
@@ -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`
    |
index a9e540084e590445f0c78884006c1a0e696bf9b8..fccfbe1d744c2054159e72ad87afd1d27a073229 100644 (file)
@@ -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 (file)
index 0000000..120fc53
--- /dev/null
@@ -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 (file)
index 0000000..6b6e406
--- /dev/null
@@ -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`.
index b213ee635df59f6c2be7048ee89dffcaa230ff57..93d6770eb47d177975bbd96a67cba312575fa406 100644 (file)
@@ -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
 
index a4686edb7175745ecab4d93a0ce30c3d60fb045c..f685c50b07d5b439e8a7542ec26618df141d877c 100644 (file)
@@ -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
 
index 44f32e0cec91ced2dedb7b3271b36fe4932fdb2a..3985372119e886a98443f00bc890f08aa370f8bc 100644 (file)
@@ -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
 
index 4ae4c8552c16130523c4071ba8dfb0a578e7999d..93c71f54eb53a6b6ddad16edff44b18ea83144eb 100644 (file)
@@ -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/add-tuple-within-arguments.rs b/src/test/ui/tuple/add-tuple-within-arguments.rs
new file mode 100644 (file)
index 0000000..089c703
--- /dev/null
@@ -0,0 +1,10 @@
+fn foo(s: &str, a: (i32, i32), s2: &str) {}
+
+fn bar(s: &str, a: (&str,), s2: &str) {}
+
+fn main() {
+    foo("hi", 1, 2, "hi");
+    //~^ ERROR this function takes 3 arguments but 4 arguments were supplied
+    bar("hi", "hi", "hi");
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/tuple/add-tuple-within-arguments.stderr b/src/test/ui/tuple/add-tuple-within-arguments.stderr
new file mode 100644 (file)
index 0000000..95df96c
--- /dev/null
@@ -0,0 +1,40 @@
+error[E0061]: this function takes 3 arguments but 4 arguments were supplied
+  --> $DIR/add-tuple-within-arguments.rs:6:5
+   |
+LL |     foo("hi", 1, 2, "hi");
+   |     ^^^
+   |
+note: function defined here
+  --> $DIR/add-tuple-within-arguments.rs:1:4
+   |
+LL | fn foo(s: &str, a: (i32, i32), s2: &str) {}
+   |    ^^^ -------  -------------  --------
+help: wrap these arguments in parentheses to construct a tuple
+   |
+LL |     foo("hi", (1, 2), "hi");
+   |               +    +
+
+error[E0308]: mismatched types
+  --> $DIR/add-tuple-within-arguments.rs:8:15
+   |
+LL |     bar("hi", "hi", "hi");
+   |     ---       ^^^^ expected tuple, found `&str`
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note:  expected tuple `(&str,)`
+           found reference `&'static str`
+note: function defined here
+  --> $DIR/add-tuple-within-arguments.rs:3:4
+   |
+LL | fn bar(s: &str, a: (&str,), s2: &str) {}
+   |    ^^^ -------  ----------  --------
+help: use a trailing comma to create a tuple with one element
+   |
+LL |     bar("hi", ("hi",), "hi");
+   |               +    ++
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0061, E0308.
+For more information about an error, try `rustc --explain E0061`.
index c704ae9934b1c5602647f8faebf07ef1ae18e445..0c2a4c41461fc4d108f5656c5bb8917e899df08a 100644 (file)
@@ -9,7 +9,7 @@ note: function defined here
    |
 LL | fn test(t: (i32, i32)) {}
    |    ^^^^ -------------
-help: use parentheses to construct a tuple
+help: wrap these arguments in parentheses to construct a tuple
    |
 LL |     test((x.qux(), x.qux()));
    |          +                +
index 667b15776efd300bdc5b3c610a65505b9bf7b2aa..2733fb3149b55d1f8fcf87d9ca62091987fb4c6f 100644 (file)
@@ -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`
    |
index f8dfc4cd043cd07c4310b7c14575f14c7cbe3620..3645d11842f7d4dc605dd34f067cb0ea01837975 100644 (file)
@@ -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
index 2b4cb669f5c7d7f04f9484ddfa33c59950972962..ec07f1e70cff6a135376c7f51c3529237dfdd66c 100644 (file)
@@ -9,7 +9,7 @@ note: associated function defined here
    |
 LL |     pub fn push_back(&mut self, value: T) {
    |            ^^^^^^^^^
-help: use parentheses to construct a tuple
+help: wrap these arguments in parentheses to construct a tuple
    |
 LL |         self.acc.push_back((self.current_provides, self.current_requires));
    |                            +                                            +
index 18ed4986f89312ba9aee248d56e623683ac3d051..fcac6c495c4b2705eeb71a01775c56bcc789eca3 100644 (file)
@@ -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/issue-98260.rs b/src/test/ui/typeck/issue-98260.rs
new file mode 100644 (file)
index 0000000..cf48294
--- /dev/null
@@ -0,0 +1,9 @@
+fn main() {}
+trait A {
+    fn a(aa: B) -> Result<_, B> {
+    //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for return types [E0121]
+        Ok(())
+    }
+}
+
+enum B {}
diff --git a/src/test/ui/typeck/issue-98260.stderr b/src/test/ui/typeck/issue-98260.stderr
new file mode 100644 (file)
index 0000000..08a1d17
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+  --> $DIR/issue-98260.rs:3:27
+   |
+LL |     fn a(aa: B) -> Result<_, B> {
+   |                    -------^----
+   |                    |      |
+   |                    |      not allowed in type signatures
+   |                    help: replace with the correct return type: `Result<(), B>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0121`.
index 815297765c18ccdcfaa9e8302cf0f9a8c5ecfa5d..703032a83223154ff916a6292876b5497bae7819 100644 (file)
@@ -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
index 2ea822df2750966a6558731043cf2c015e2f0ec8..f72082d53016729e3b45b3f68205382ac45b016e 100644 (file)
@@ -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
index 14052486cbbc97158d53be07c7ae0529c38321f1..65d866c716e0e01049bd00b514915b708b5b5e4f 100644 (file)
@@ -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
 
index ebe6edd1010147844ecf7c56426ac7744437838f..f053f4b0af89c0de9b720c382ea1c910a4341fba 100644 (file)
@@ -7,7 +7,7 @@ trait Foo {
 fn foo(f: Option<&dyn Foo>) {
     if let Some(f) = f {
         let _ = f.foo();
-        //~^ ERROR cannot move a value of type [u8]: the size of [u8] cannot be statically determined
+        //~^ ERROR cannot move a value of type `[u8]`
     }
 }
 
index 4dd7cf5e02fc27f7156f9e66ef497f3e8959c492..671d409937cac0083eeab0c727455905bb38af81 100644 (file)
@@ -1,8 +1,8 @@
-error[E0161]: cannot move a value of type [u8]: the size of [u8] cannot be statically determined
+error[E0161]: cannot move a value of type `[u8]`
   --> $DIR/return-unsized-from-trait-method.rs:9:17
    |
 LL |         let _ = f.foo();
-   |                 ^^^^^^^
+   |                 ^^^^^^^ the size of `[u8]` cannot be statically determined
 
 error: aborting due to previous error
 
index 3eecca0fa09d9c7483dcc3f8af69b4db6568762d..0221ef16b4965f30eb121b81b0b3843c40e6f42e 100644 (file)
@@ -2,10 +2,12 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
   --> $DIR/unsized-fn-param.rs:11:11
    |
 LL |     foo11("bar", &"baz");
-   |           ^^^^^ doesn't have a size known at compile-time
+   |     ----- ^^^^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
    |
    = 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");
@@ -15,10 +17,12 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
   --> $DIR/unsized-fn-param.rs:13:19
    |
 LL |     foo12(&"bar", "baz");
-   |                   ^^^^^ doesn't have a size known at compile-time
+   |     -----         ^^^^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
    |
    = 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");
@@ -28,10 +32,12 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
   --> $DIR/unsized-fn-param.rs:16:11
    |
 LL |     foo21("bar", &"baz");
-   |           ^^^^^ doesn't have a size known at compile-time
+   |     ----- ^^^^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
    |
    = 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");
@@ -41,10 +47,12 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
   --> $DIR/unsized-fn-param.rs:18:19
    |
 LL |     foo22(&"bar", "baz");
-   |                   ^^^^^ doesn't have a size known at compile-time
+   |     -----         ^^^^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
    |
    = 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");
index 39b6583bc4ec4123d915ad1372e47022b1c6973e..af76aca2c295803a25e0ab072dfd67f837a3ed62 100644 (file)
@@ -44,6 +44,7 @@ fn f9<X: ?Sized>(x1: Box<S<X>>) {
 fn f10<X: ?Sized>(x1: Box<S<X>>) {
     f5(&(32, *x1));
     //~^ ERROR the size for values of type
+    //~| ERROR the size for values of type
 }
 
 pub fn main() {}
index 65bdc4c2ea35292f4c984c8063ea79cedbbcfb1a..d64091b15eb1fc2c747980353ca77551e9d41dea 100644 (file)
@@ -100,6 +100,29 @@ LL - fn f9<X: ?Sized>(x1: Box<S<X>>) {
 LL + fn f9<X>(x1: Box<S<X>>) {
    |
 
+error[E0277]: the size for values of type `X` cannot be known at compilation time
+  --> $DIR/unsized3.rs:45:9
+   |
+LL | fn f10<X: ?Sized>(x1: Box<S<X>>) {
+   |        - this type parameter needs to be `std::marker::Sized`
+LL |     f5(&(32, *x1));
+   |     --  ^^^^^^^^^ doesn't have a size known at compile-time
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required because it appears within the type `S<X>`
+  --> $DIR/unsized3.rs:28:8
+   |
+LL | struct S<X: ?Sized> {
+   |        ^
+   = note: required because it appears within the type `({integer}, S<X>)`
+   = note: tuples must have a statically known size to be initialized
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL - fn f10<X: ?Sized>(x1: Box<S<X>>) {
+LL + fn f10<X>(x1: Box<S<X>>) {
+   |
+
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized3.rs:45:8
    |
@@ -116,13 +139,21 @@ note: required because it appears within the type `S<X>`
 LL | struct S<X: ?Sized> {
    |        ^
    = note: required because it appears within the type `({integer}, S<X>)`
-   = note: tuples must have a statically known size to be initialized
+note: required by a bound in `f5`
+  --> $DIR/unsized3.rs:24:7
+   |
+LL | fn f5<Y>(x: &Y) {}
+   |       ^ required by this bound in `f5`
 help: consider removing the `?Sized` bound to make the type parameter `Sized`
    |
 LL - fn f10<X: ?Sized>(x1: Box<S<X>>) {
 LL + fn f10<X>(x1: Box<S<X>>) {
    |
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | fn f5<Y: ?Sized>(x: &Y) {}
+   |        ++++++++
 
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
index a5e08c4703f202e30cdaf80ca3e7c00baa59c496..dbff32b27893b899ae2397f3d56d1be111041d56 160000 (submodule)
@@ -1 +1 @@
-Subproject commit a5e08c4703f202e30cdaf80ca3e7c00baa59c496
+Subproject commit dbff32b27893b899ae2397f3d56d1be111041d56
index 40aa0e8f715af0191a37cd3f0c26f2ebd796d2ef..d7acae2ff2a88abe53d4c2545c57040622c4aefc 100644 (file)
@@ -84,7 +84,7 @@ quote = { version = "1", features = ["default"] }
 rand_core_0_5 = { package = "rand_core", version = "0.5.1", features = ["getrandom", "alloc", "std"] }
 serde = { version = "1.0.82", features = ['derive'] }
 serde_json = { version = "1.0.31", features = ["raw_value", "unbounded_depth"] }
-smallvec = { version = "1.6.1", features = ['union', 'may_dangle'] }
+smallvec = { version = "1.8.1", features = ['union', 'may_dangle'] }
 syn = { version = "1", features = ['fold', 'full', 'extra-traits', 'visit', 'visit-mut'] }
 url = { version = "2.0", features = ['serde'] }
 
index 100dfd613f0cb5878633d33c1bc5c4c7e477c363..bebb583e100a4c44772e5223adfc960a2fd1cce4 100644 (file)
@@ -219,7 +219,7 @@ changelog-branch = "master"
 
 [mentions."compiler/rustc_apfloat"]
 message = """
-Changes rustc_apfloat. rustc_apfloat is currently in limbo and you almost
+Changes rustc_apfloat. rustc_apfloat is currently in limbo and you almost \
 certainly don't want to change it (see #55993).
 """
 cc = ["@eddyb"]
@@ -258,22 +258,22 @@ cc = ["@GuillaumeGomez"]
 message = """
 Hey! It looks like you've submitted a new PR for the library teams!
 
-If this PR contains changes to any `rust-lang/rust` public library APIs then
-please comment with `@rustbot label +T-libs-api -T-libs` to tag it
-appropriately. If this PR contains changes to any unstable APIs please edit
-the PR description to add a link to the relevant [API Change
-Proposal](https://std-dev-guide.rust-lang.org/feature-lifecycle/api-change-proposals.html)
-or [create one](https://github.com/rust-lang/libs-team/issues/new?assignees=&labels=api-change-proposal%2C+T-libs-api&template=api-change-proposal.md&title=%28My+API+Change+Proposal%29)
-if you haven't already. If you're unsure where your change falls no worries,
-just leave it as is and the reviewer will take a look and make a decision to
+If this PR contains changes to any `rust-lang/rust` public library APIs then \
+please comment with `@rustbot label +T-libs-api -T-libs` to tag it \
+appropriately. If this PR contains changes to any unstable APIs please edit \
+the PR description to add a link to the relevant [API Change \
+Proposal](https://std-dev-guide.rust-lang.org/feature-lifecycle/api-change-proposals.html) \
+or [create one](https://github.com/rust-lang/libs-team/issues/new?assignees=&labels=api-change-proposal%2C+T-libs-api&template=api-change-proposal.md&title=%28My+API+Change+Proposal%29) \
+if you haven't already. If you're unsure where your change falls no worries, \
+just leave it as is and the reviewer will take a look and make a decision to \
 forward on if necessary.
 
 Examples of `T-libs-api` changes:
 
 * Stabilizing library features
-* Introducing insta-stable changes such as new implementations of existing
+* Introducing insta-stable changes such as new implementations of existing \
   stable traits on existing stable types
-* Introducing new or changing existing unstable library APIs (excluding
+* Introducing new or changing existing unstable library APIs (excluding \
   permanently unstable features / features without a tracking issue)
 * Changing public documentation in ways that create new stability guarantees
 * Changing observable runtime behavior of library APIs
@@ -300,8 +300,8 @@ cc = ["@Cldfire"]
 
 [mentions."src/rustdoc-json-types"]
 message = """
-rustdoc-json-types is a **public** (although nightly-only) API.
-If possible, consider changing `src/librustdoc/json/conversions.rs`;
+rustdoc-json-types is a **public** (although nightly-only) API. \
+If possible, consider changing `src/librustdoc/json/conversions.rs`; \
 otherwise, make sure you bump the `FORMAT_VERSION` constant.
 """
 cc = [