about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs28
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs78
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs32
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs3
-rw-r--r--tests/crashes/121134.rs20
-rw-r--r--tests/crashes/123917.rs41
-rw-r--r--tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs1
-rw-r--r--tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr19
-rw-r--r--tests/ui/lifetimes/noisy-follow-up-erro.rs23
-rw-r--r--tests/ui/lifetimes/noisy-follow-up-erro.stderr27
-rw-r--r--tests/ui/polymorphization/abi_mismatch.rs20
-rw-r--r--tests/ui/polymorphization/abi_mismatch.stderr11
-rw-r--r--tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs2
-rw-r--r--tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr32
-rw-r--r--tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.rs27
-rw-r--r--tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.stderr19
-rw-r--r--tests/ui/traits/issue-78372.stderr12
-rw-r--r--tests/ui/transmutability/issue-101739-2.rs1
-rw-r--r--tests/ui/transmutability/issue-101739-2.stderr20
21 files changed, 226 insertions, 194 deletions
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index f646e7de26b..3a9ef244fd3 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -702,7 +702,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     pub(crate) fn complain_about_missing_assoc_tys(
         &self,
         associated_types: FxIndexMap<Span, FxIndexSet<DefId>>,
-        potential_assoc_types: Vec<Span>,
+        potential_assoc_types: Vec<usize>,
         trait_bounds: &[hir::PolyTraitRef<'_>],
     ) {
         if associated_types.values().all(|v| v.is_empty()) {
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
index d641e33b299..26cabb69d25 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
@@ -214,10 +214,11 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
             if let Some(&param) = params.peek() {
                 if param.index == 0 {
                     if let GenericParamDefKind::Type { .. } = param.kind {
+                        assert_eq!(&args[..], &[]);
                         args.push(
                             self_ty
                                 .map(|ty| ty.into())
-                                .unwrap_or_else(|| ctx.inferred_kind(None, param, true)),
+                                .unwrap_or_else(|| ctx.inferred_kind(&args, param, true)),
                         );
                         params.next();
                     }
@@ -267,7 +268,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
                             // Since this is a const impl, we need to insert a host arg at the end of
                             // `PartialEq`'s generics, but this errors since `Rhs` isn't specified.
                             // To work around this, we infer all arguments until we reach the host param.
-                            args.push(ctx.inferred_kind(Some(&args), param, infer_args));
+                            args.push(ctx.inferred_kind(&args, param, infer_args));
                             params.next();
                         }
                         (GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _)
@@ -281,7 +282,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
                             GenericParamDefKind::Const { .. },
                             _,
                         ) => {
-                            args.push(ctx.provided_kind(param, arg));
+                            args.push(ctx.provided_kind(&args, param, arg));
                             args_iter.next();
                             params.next();
                         }
@@ -292,7 +293,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
                         ) => {
                             // We expected a lifetime argument, but got a type or const
                             // argument. That means we're inferring the lifetimes.
-                            args.push(ctx.inferred_kind(None, param, infer_args));
+                            args.push(ctx.inferred_kind(&args, param, infer_args));
                             force_infer_lt = Some((arg, param));
                             params.next();
                         }
@@ -388,7 +389,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
                 (None, Some(&param)) => {
                     // If there are fewer arguments than parameters, it means
                     // we're inferring the remaining arguments.
-                    args.push(ctx.inferred_kind(Some(&args), param, infer_args));
+                    args.push(ctx.inferred_kind(&args, param, infer_args));
                     params.next();
                 }
 
@@ -474,16 +475,9 @@ pub(crate) fn check_generic_arg_count(
             return Ok(());
         }
 
-        if provided_args > max_expected_args {
-            invalid_args.extend(
-                gen_args.args[max_expected_args..provided_args].iter().map(|arg| arg.span()),
-            );
-        };
+        invalid_args.extend(min_expected_args..provided_args);
 
         let gen_args_info = if provided_args > min_expected_args {
-            invalid_args.extend(
-                gen_args.args[min_expected_args..provided_args].iter().map(|arg| arg.span()),
-            );
             let num_redundant_args = provided_args - min_expected_args;
             GenericArgsInfo::ExcessLifetimes { num_redundant_args }
         } else {
@@ -538,11 +532,7 @@ pub(crate) fn check_generic_arg_count(
         let num_default_params = expected_max - expected_min;
 
         let gen_args_info = if provided > expected_max {
-            invalid_args.extend(
-                gen_args.args[args_offset + expected_max..args_offset + provided]
-                    .iter()
-                    .map(|arg| arg.span()),
-            );
+            invalid_args.extend((expected_max..provided).map(|i| i + args_offset));
             let num_redundant_args = provided - expected_max;
 
             // Provide extra note if synthetic arguments like `impl Trait` are specified.
@@ -610,7 +600,7 @@ pub(crate) fn check_generic_arg_count(
         explicit_late_bound,
         correct: lifetimes_correct
             .and(args_correct)
-            .map_err(|reported| GenericArgCountMismatch { reported: Some(reported), invalid_args }),
+            .map_err(|reported| GenericArgCountMismatch { reported, invalid_args }),
     }
 }
 
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index e385716fbfb..2f54349d267 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -215,12 +215,11 @@ pub(crate) enum GenericArgPosition {
 
 /// A marker denoting that the generic arguments that were
 /// provided did not match the respective generic parameters.
-#[derive(Clone, Default, Debug)]
+#[derive(Clone, Debug)]
 pub struct GenericArgCountMismatch {
-    /// Indicates whether a fatal error was reported (`Some`), or just a lint (`None`).
-    pub reported: Option<ErrorGuaranteed>,
-    /// A list of spans of arguments provided that were not valid.
-    pub invalid_args: Vec<Span>,
+    pub reported: ErrorGuaranteed,
+    /// A list of indices of arguments provided that were not valid.
+    pub invalid_args: Vec<usize>,
 }
 
 /// Decorates the result of a generic argument count mismatch
@@ -240,13 +239,14 @@ pub trait GenericArgsLowerer<'a, 'tcx> {
 
     fn provided_kind(
         &mut self,
+        preceding_args: &[ty::GenericArg<'tcx>],
         param: &ty::GenericParamDef,
         arg: &GenericArg<'tcx>,
     ) -> ty::GenericArg<'tcx>;
 
     fn inferred_kind(
         &mut self,
-        args: Option<&[ty::GenericArg<'tcx>]>,
+        preceding_args: &[ty::GenericArg<'tcx>],
         param: &ty::GenericParamDef,
         infer_args: bool,
     ) -> ty::GenericArg<'tcx>;
@@ -404,10 +404,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             self_ty.is_some(),
         );
 
-        if let Err(err) = &arg_count.correct
-            && let Some(reported) = err.reported
-        {
-            self.set_tainted_by_errors(reported);
+        if let Err(err) = &arg_count.correct {
+            self.set_tainted_by_errors(err.reported);
         }
 
         // Skip processing if type has no generic parameters.
@@ -425,6 +423,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             span: Span,
             inferred_params: Vec<Span>,
             infer_args: bool,
+            incorrect_args: &'a Result<(), GenericArgCountMismatch>,
         }
 
         impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> {
@@ -439,11 +438,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
             fn provided_kind(
                 &mut self,
+                preceding_args: &[ty::GenericArg<'tcx>],
                 param: &ty::GenericParamDef,
                 arg: &GenericArg<'tcx>,
             ) -> ty::GenericArg<'tcx> {
                 let tcx = self.lowerer.tcx();
 
+                if let Err(incorrect) = self.incorrect_args {
+                    if incorrect.invalid_args.contains(&(param.index as usize)) {
+                        return param.to_error(tcx, preceding_args);
+                    }
+                }
+
                 let mut handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| {
                     if has_default {
                         tcx.check_optional_stability(
@@ -506,11 +512,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
             fn inferred_kind(
                 &mut self,
-                args: Option<&[ty::GenericArg<'tcx>]>,
+                preceding_args: &[ty::GenericArg<'tcx>],
                 param: &ty::GenericParamDef,
                 infer_args: bool,
             ) -> ty::GenericArg<'tcx> {
                 let tcx = self.lowerer.tcx();
+
+                if let Err(incorrect) = self.incorrect_args {
+                    if incorrect.invalid_args.contains(&(param.index as usize)) {
+                        return param.to_error(tcx, preceding_args);
+                    }
+                }
                 match param.kind {
                     GenericParamDefKind::Lifetime => self
                         .lowerer
@@ -529,15 +541,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     GenericParamDefKind::Type { has_default, .. } => {
                         if !infer_args && has_default {
                             // No type parameter provided, but a default exists.
-                            let args = args.unwrap();
-                            if args.iter().any(|arg| match arg.unpack() {
-                                GenericArgKind::Type(ty) => ty.references_error(),
-                                _ => false,
-                            }) {
+                            if let Some(prev) =
+                                preceding_args.iter().find_map(|arg| match arg.unpack() {
+                                    GenericArgKind::Type(ty) => ty.error_reported().err(),
+                                    _ => None,
+                                })
+                            {
                                 // Avoid ICE #86756 when type error recovery goes awry.
-                                return Ty::new_misc_error(tcx).into();
+                                return Ty::new_error(tcx, prev).into();
                             }
-                            tcx.at(self.span).type_of(param.def_id).instantiate(tcx, args).into()
+                            tcx.at(self.span)
+                                .type_of(param.def_id)
+                                .instantiate(tcx, preceding_args)
+                                .into()
                         } else if infer_args {
                             self.lowerer.ty_infer(Some(param), self.span).into()
                         } else {
@@ -557,7 +573,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         // FIXME(effects) see if we should special case effect params here
                         if !infer_args && has_default {
                             tcx.const_param_default(param.def_id)
-                                .instantiate(tcx, args.unwrap())
+                                .instantiate(tcx, preceding_args)
                                 .into()
                         } else {
                             if infer_args {
@@ -571,6 +587,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 }
             }
         }
+        if let ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst = constness
+            && generics.has_self
+            && !tcx.has_attr(def_id, sym::const_trait)
+        {
+            let reported = tcx.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
+                span,
+                modifier: constness.as_str(),
+            });
+            self.set_tainted_by_errors(reported);
+            arg_count.correct = Err(GenericArgCountMismatch { reported, invalid_args: vec![] });
+        }
 
         let mut args_ctx = GenericArgsCtxt {
             lowerer: self,
@@ -579,19 +606,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             generic_args: segment.args(),
             inferred_params: vec![],
             infer_args: segment.infer_args,
+            incorrect_args: &arg_count.correct,
         };
-        if let ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst = constness
-            && generics.has_self
-            && !tcx.has_attr(def_id, sym::const_trait)
-        {
-            let e = tcx.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
-                span,
-                modifier: constness.as_str(),
-            });
-            self.set_tainted_by_errors(e);
-            arg_count.correct =
-                Err(GenericArgCountMismatch { reported: Some(e), invalid_args: vec![] });
-        }
         let args = lower_generic_args(
             tcx,
             def_id,
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index 002be61196a..5cc1ec71757 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -86,6 +86,8 @@ fn enforce_impl_params_are_constrained(
     let impl_predicates = tcx.predicates_of(impl_def_id);
     let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity);
 
+    impl_trait_ref.error_reported()?;
+
     let mut input_parameters = cgp::parameters_for_impl(tcx, impl_self_ty, impl_trait_ref);
     cgp::identify_constrained_generic_params(
         tcx,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 0c10c67db8c..58eb0c28179 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1118,7 +1118,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // to add defaults. If the user provided *too many* types, that's
         // a problem.
 
-        let mut infer_args_for_err = FxHashSet::default();
+        let mut infer_args_for_err = None;
 
         let mut explicit_late_bound = ExplicitLateBound::No;
         for &GenericPathSegment(def_id, index) in &generic_segments {
@@ -1136,9 +1136,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 explicit_late_bound = ExplicitLateBound::Yes;
             }
 
-            if let Err(GenericArgCountMismatch { reported: Some(e), .. }) = arg_count.correct {
-                infer_args_for_err.insert(index);
-                self.set_tainted_by_errors(e); // See issue #53251.
+            if let Err(GenericArgCountMismatch { reported, .. }) = arg_count.correct {
+                infer_args_for_err
+                    .get_or_insert_with(|| (reported, FxHashSet::default()))
+                    .1
+                    .insert(index);
+                self.set_tainted_by_errors(reported); // See issue #53251.
             }
         }
 
@@ -1232,15 +1235,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
         let def_id = res.def_id();
 
-        let arg_count = GenericArgCountResult {
-            explicit_late_bound,
-            correct: if infer_args_for_err.is_empty() {
-                Ok(())
-            } else {
-                Err(GenericArgCountMismatch::default())
-            },
+        let (correct, infer_args_for_err) = match infer_args_for_err {
+            Some((reported, args)) => {
+                (Err(GenericArgCountMismatch { reported, invalid_args: vec![] }), args)
+            }
+            None => (Ok(()), Default::default()),
         };
 
+        let arg_count = GenericArgCountResult { explicit_late_bound, correct };
+
         struct CtorGenericArgsCtxt<'a, 'tcx> {
             fcx: &'a FnCtxt<'a, 'tcx>,
             span: Span,
@@ -1272,6 +1275,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             fn provided_kind(
                 &mut self,
+                _preceding_args: &[ty::GenericArg<'tcx>],
                 param: &ty::GenericParamDef,
                 arg: &GenericArg<'tcx>,
             ) -> ty::GenericArg<'tcx> {
@@ -1314,7 +1318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             fn inferred_kind(
                 &mut self,
-                args: Option<&[ty::GenericArg<'tcx>]>,
+                preceding_args: &[ty::GenericArg<'tcx>],
                 param: &ty::GenericParamDef,
                 infer_args: bool,
             ) -> ty::GenericArg<'tcx> {
@@ -1328,7 +1332,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             // If we have a default, then it doesn't matter that we're not
                             // inferring the type arguments: we provide the default where any
                             // is missing.
-                            tcx.type_of(param.def_id).instantiate(tcx, args.unwrap()).into()
+                            tcx.type_of(param.def_id).instantiate(tcx, preceding_args).into()
                         } else {
                             // If no type arguments were provided, we have to infer them.
                             // This case also occurs as a result of some malformed input, e.g.
@@ -1353,7 +1357,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             } else if !infer_args {
                                 return tcx
                                     .const_param_default(param.def_id)
-                                    .instantiate(tcx, args.unwrap())
+                                    .instantiate(tcx, preceding_args)
                                     .into();
                             }
                         }
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index 9c64f9475cf..0825e661373 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -383,6 +383,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
 
             fn provided_kind(
                 &mut self,
+                _preceding_args: &[ty::GenericArg<'tcx>],
                 param: &ty::GenericParamDef,
                 arg: &GenericArg<'tcx>,
             ) -> ty::GenericArg<'tcx> {
@@ -419,7 +420,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
 
             fn inferred_kind(
                 &mut self,
-                _args: Option<&[ty::GenericArg<'tcx>]>,
+                _preceding_args: &[ty::GenericArg<'tcx>],
                 param: &ty::GenericParamDef,
                 _infer_args: bool,
             ) -> ty::GenericArg<'tcx> {
diff --git a/tests/crashes/121134.rs b/tests/crashes/121134.rs
deleted file mode 100644
index 36397d4ec3c..00000000000
--- a/tests/crashes/121134.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//@ known-bug: #121134
-trait Output<'a> {
-    type Type;
-}
-
-struct Wrapper;
-
-impl Wrapper {
-    fn do_something_wrapper<O, F>(&mut self, do_something_wrapper: F)
-    where
-        FnOnce:,
-        F: for<'a> FnOnce(<F as Output<i32, _>>::Type),
-    {
-    }
-}
-
-fn main() {
-    let mut wrapper = Wrapper;
-    wrapper.do_something_wrapper::<i32, _>(|value| ());
-}
diff --git a/tests/crashes/123917.rs b/tests/crashes/123917.rs
deleted file mode 100644
index 66e75460662..00000000000
--- a/tests/crashes/123917.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-//@ known-bug: #123917
-//@ compile-flags: -Zmir-opt-level=5 -Zpolymorphize=on
-
-use std::marker::PhantomData;
-
-pub struct Id<'id>();
-
-pub struct Item<'life, T> {
-    data: T,
-}
-
-pub struct Token<'life, 'borrow, 'compact, 'reborrow, T>
-where
-    'life: 'reborrow,
-    T: Tokenize,
-{
-    ptr: *mut <T as Tokenize>::Tokenized,
-    ptr: core::ptr::NonNull<T::Tokenized>,
-    _phantom: PhantomData<Id<'life>>,
-}
-
-impl<'life> Arena<'life> {
-    pub fn tokenize<'before, 'compact, 'borrow, 'reborrow, T, U>(
-        item: Item<'life, &'before mut T>,
-    ) -> Token<'life, 'borrow, 'compact, 'reborrow, U>
-    where
-        T: Tokenize<'life, 'borrow, 'compact, 'reborrow, Untokenized = U>,
-        T::Untokenized: Tokenize<'life, 'borrow, 'compact, 'reborrow>,
-    {
-        let dst = item.data as *mut T as *mut T::Tokenized;
-        Token {
-            ptr: core::ptr::NonNull::new(dst as *mut _).unwrap(),
-            _phantom: PhantomData,
-        }
-    }
-}
-
-pub trait Tokenize {
-    type Tokenized;
-    type Untokenized;
-}
diff --git a/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs
index 68b8b489816..569e57fa326 100644
--- a/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs
+++ b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs
@@ -24,7 +24,6 @@ fn via_associated_const() {
     trait Trait {
         const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
         //~^ ERROR mismatched types
-        //~| ERROR `Src` cannot be safely transmuted into `Dst`
         //~| ERROR mismatched types
     }
 }
diff --git a/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr
index 1dbacaee3c2..a8fc742e89f 100644
--- a/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr
+++ b/tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr
@@ -12,28 +12,13 @@ error[E0308]: mismatched types
 LL |         const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
    |                                                                          ^^ expected `Assume`, found `()`
 
-error[E0277]: `Src` cannot be safely transmuted into `Dst`
-  --> $DIR/transmutable-ice-110969.rs:25:60
-   |
-LL |         const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
-   |                                                            ^^^ `Dst` may carry safety invariants
-   |
-note: required by a bound in `is_transmutable`
-  --> $DIR/transmutable-ice-110969.rs:11:14
-   |
-LL |     pub fn is_transmutable<Src, Dst, Context, const ASSUME: std::mem::Assume>()
-   |            --------------- required by a bound in this function
-LL |     where
-LL |         Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME>,
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
-
 error[E0308]: mismatched types
   --> $DIR/transmutable-ice-110969.rs:25:29
    |
 LL |         const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0107, E0277, E0308.
+Some errors have detailed explanations: E0107, E0308.
 For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/lifetimes/noisy-follow-up-erro.rs b/tests/ui/lifetimes/noisy-follow-up-erro.rs
new file mode 100644
index 00000000000..47a87068d8f
--- /dev/null
+++ b/tests/ui/lifetimes/noisy-follow-up-erro.rs
@@ -0,0 +1,23 @@
+struct Foo<'c, 'd>(&'c (), &'d ());
+
+impl<'c, 'd> Foo<'c, 'd> {
+    fn acc(&mut self, _bar: &Bar) -> &'d () {
+        todo!()
+    }
+}
+
+struct Bar;
+
+impl<'a> Bar {
+    fn boom(&self, foo: &mut Foo<'_, '_, 'a>) -> Result<(), &'a ()> {
+        //~^ ERROR: struct takes 2 lifetime arguments but 3 lifetime arguments were supplied
+        self.bar().map_err(|()| foo.acc(self))?;
+        //~^ ERROR: explicit lifetime required in the type of `foo`
+        Ok(())
+    }
+    fn bar(&self) -> Result<(), &'a ()> {
+        todo!()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/noisy-follow-up-erro.stderr b/tests/ui/lifetimes/noisy-follow-up-erro.stderr
new file mode 100644
index 00000000000..f549009a87c
--- /dev/null
+++ b/tests/ui/lifetimes/noisy-follow-up-erro.stderr
@@ -0,0 +1,27 @@
+error[E0107]: struct takes 2 lifetime arguments but 3 lifetime arguments were supplied
+  --> $DIR/noisy-follow-up-erro.rs:12:30
+   |
+LL |     fn boom(&self, foo: &mut Foo<'_, '_, 'a>) -> Result<(), &'a ()> {
+   |                              ^^^         -- help: remove this lifetime argument
+   |                              |
+   |                              expected 2 lifetime arguments
+   |
+note: struct defined here, with 2 lifetime parameters: `'c`, `'d`
+  --> $DIR/noisy-follow-up-erro.rs:1:8
+   |
+LL | struct Foo<'c, 'd>(&'c (), &'d ());
+   |        ^^^ --  --
+
+error[E0621]: explicit lifetime required in the type of `foo`
+  --> $DIR/noisy-follow-up-erro.rs:14:9
+   |
+LL |     fn boom(&self, foo: &mut Foo<'_, '_, 'a>) -> Result<(), &'a ()> {
+   |                         -------------------- help: add explicit lifetime `'a` to the type of `foo`: `&mut Foo<'_, 'a>`
+LL |
+LL |         self.bar().map_err(|()| foo.acc(self))?;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0107, E0621.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/polymorphization/abi_mismatch.rs b/tests/ui/polymorphization/abi_mismatch.rs
new file mode 100644
index 00000000000..22c2c162d1c
--- /dev/null
+++ b/tests/ui/polymorphization/abi_mismatch.rs
@@ -0,0 +1,20 @@
+//! This test used to ICE: #123917
+//! The reason was that while the AST knows about two fields
+//! named `ptr`, only one exists at the layout level, so accessing
+//! `_extra_field` would use an oob index
+//@ compile-flags: -Zmir-opt-level=5 -Zpolymorphize=on
+
+struct NonNull<T>(*mut T);
+
+struct Token<T> {
+    ptr: *mut T,
+    ptr: NonNull<T>,
+    //~^ ERROR: `ptr` is already declared
+    _extra_field: (),
+}
+
+fn tokenize<T>(item: *mut T) -> Token<T> {
+    Token { ptr: NonNull(item), _extra_field: () }
+}
+
+fn main() {}
diff --git a/tests/ui/polymorphization/abi_mismatch.stderr b/tests/ui/polymorphization/abi_mismatch.stderr
new file mode 100644
index 00000000000..e96c737f777
--- /dev/null
+++ b/tests/ui/polymorphization/abi_mismatch.stderr
@@ -0,0 +1,11 @@
+error[E0124]: field `ptr` is already declared
+  --> $DIR/abi_mismatch.rs:11:5
+   |
+LL |     ptr: *mut T,
+   |     ----------- `ptr` first declared here
+LL |     ptr: NonNull<T>,
+   |     ^^^^^^^^^^^^^^^ field already declared
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0124`.
diff --git a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs
index cab484a120c..445ea2de610 100644
--- a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs
+++ b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs
@@ -14,14 +14,12 @@ impl<T, S> Trait<T> for i32 {
 // Should not not trigger suggestion here...
 impl<T, S> Trait<T, S> for () {}
 //~^ ERROR trait takes 1 generic argument but 2 generic arguments were supplied
-//~| ERROR `S` is not constrained
 
 //... but should do so in all of the below cases except the last one
 fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
 //~^ ERROR trait takes 1 generic argument but 2 generic arguments were supplied
 //~| ERROR trait takes 1 generic argument but 2 generic arguments were supplied
 //~| ERROR trait takes 1 generic argument but 2 generic arguments were supplied
-//~| ERROR type annotations needed
     3
 }
 
diff --git a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr
index 99e81a9039e..06e2fa5d4d1 100644
--- a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr
+++ b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr
@@ -16,14 +16,8 @@ note: trait defined here, with 1 generic parameter: `T`
 LL | pub trait Trait<T> {
    |           ^^^^^ -
 
-error[E0207]: the type parameter `S` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:15:9
-   |
-LL | impl<T, S> Trait<T, S> for () {}
-   |         ^ unconstrained type parameter
-
 error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:12
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:19:12
    |
 LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
    |            ^^^^^ expected 1 generic argument
@@ -39,7 +33,7 @@ LL | fn func<T: Trait<u32, Assoc = String>>(t: T) -> impl Trait<(), i32> {
    |                       +++++++
 
 error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:46
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:19:46
    |
 LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
    |                                              ^^^^^ expected 1 generic argument
@@ -55,7 +49,7 @@ LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), Assoc = i32> {
    |                                                        +++++++
 
 error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:46
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:19:46
    |
 LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
    |                                              ^^^^^ expected 1 generic argument
@@ -71,14 +65,8 @@ help: replace the generic bound with the associated type
 LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), Assoc = i32> {
    |                                                        +++++++
 
-error[E0282]: type annotations needed
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:41
-   |
-LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
-   |                                         ^^^^^^^^^^^^^^^^^^^ cannot infer type
-
 error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:28:18
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:26:18
    |
 LL | struct Struct<T: Trait<u32, String>> {
    |                  ^^^^^ expected 1 generic argument
@@ -94,7 +82,7 @@ LL | struct Struct<T: Trait<u32, Assoc = String>> {
    |                             +++++++
 
 error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:33:23
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:31:23
    |
 LL | trait AnotherTrait<T: Trait<T, i32>> {}
    |                       ^^^^^ expected 1 generic argument
@@ -110,7 +98,7 @@ LL | trait AnotherTrait<T: Trait<T, Assoc = i32>> {}
    |                                +++++++
 
 error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:36:9
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:34:9
    |
 LL | impl<T: Trait<u32, String>> Struct<T> {}
    |         ^^^^^ expected 1 generic argument
@@ -126,7 +114,7 @@ LL | impl<T: Trait<u32, Assoc = String>> Struct<T> {}
    |                    +++++++
 
 error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:42:58
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:40:58
    |
 LL | impl<T: Trait<u32, Assoc=String>, U> YetAnotherTrait for Struct<T, U> {}
    |                                                          ^^^^^^    - help: remove this generic argument
@@ -134,12 +122,12 @@ LL | impl<T: Trait<u32, Assoc=String>, U> YetAnotherTrait for Struct<T, U> {}
    |                                                          expected 1 generic argument
    |
 note: struct defined here, with 1 generic parameter: `T`
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:28:8
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:26:8
    |
 LL | struct Struct<T: Trait<u32, String>> {
    |        ^^^^^^ -
 
-error: aborting due to 11 previous errors
+error: aborting due to 9 previous errors
 
-Some errors have detailed explanations: E0107, E0207, E0282.
+Some errors have detailed explanations: E0107, E0207.
 For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.rs b/tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.rs
new file mode 100644
index 00000000000..bf1278f992b
--- /dev/null
+++ b/tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.rs
@@ -0,0 +1,27 @@
+//! This test used to ICE: #121134
+//! The issue is that we're trying to prove a projection, but there's
+//! no bound for the projection's trait, and the projection has the wrong
+//! kind of generic parameter (lifetime vs type).
+//! When actually calling the function with those broken bounds, trying to
+//! instantiate the bounds with inference vars would ICE.
+#![feature(unboxed_closures)]
+
+trait Output<'a> {
+    type Type;
+}
+
+struct Wrapper;
+
+impl Wrapper {
+    fn do_something_wrapper<O, F>(&mut self, _: F)
+    where
+        F: for<'a> FnOnce(<F as Output<i32>>::Type),
+        //~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
+    {
+    }
+}
+
+fn main() {
+    let mut wrapper = Wrapper;
+    wrapper.do_something_wrapper(|value| ());
+}
diff --git a/tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.stderr b/tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.stderr
new file mode 100644
index 00000000000..acda3418894
--- /dev/null
+++ b/tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.stderr
@@ -0,0 +1,19 @@
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/generic_param_mismatch_in_unsatisfied_projection.rs:18:33
+   |
+LL |         F: for<'a> FnOnce(<F as Output<i32>>::Type),
+   |                                 ^^^^^^ expected 0 generic arguments
+   |
+note: trait defined here, with 0 generic parameters
+  --> $DIR/generic_param_mismatch_in_unsatisfied_projection.rs:9:7
+   |
+LL | trait Output<'a> {
+   |       ^^^^^^
+help: replace the generic bound with the associated type
+   |
+LL |         F: for<'a> FnOnce(<F as Output<Type = i32>>::Type),
+   |                                        ++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr
index 58a4c229e5e..cdcb0cdf259 100644
--- a/tests/ui/traits/issue-78372.stderr
+++ b/tests/ui/traits/issue-78372.stderr
@@ -55,12 +55,6 @@ LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
    = help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
-  --> $DIR/issue-78372.rs:3:1
-   |
-LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/issue-78372.rs:12:17
    |
@@ -88,6 +82,12 @@ LL |     fn foo(self: Smaht<Self, T>);
    = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
+error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
+  --> $DIR/issue-78372.rs:3:1
+   |
+LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0038, E0307, E0378, E0412, E0658.
diff --git a/tests/ui/transmutability/issue-101739-2.rs b/tests/ui/transmutability/issue-101739-2.rs
index e2cec24aac1..1c0bd29d707 100644
--- a/tests/ui/transmutability/issue-101739-2.rs
+++ b/tests/ui/transmutability/issue-101739-2.rs
@@ -15,7 +15,6 @@ mod assert {
     >()
     where
         Dst: BikeshedIntrinsicFrom< //~ ERROR trait takes at most 2 generic arguments but 5 generic arguments were supplied
-        //~^ ERROR: the constant `ASSUME_ALIGNMENT` is not of type `Assume`
             Src,
             ASSUME_ALIGNMENT, //~ ERROR: mismatched types
             ASSUME_LIFETIMES,
diff --git a/tests/ui/transmutability/issue-101739-2.stderr b/tests/ui/transmutability/issue-101739-2.stderr
index 639b4460892..38912696c18 100644
--- a/tests/ui/transmutability/issue-101739-2.stderr
+++ b/tests/ui/transmutability/issue-101739-2.stderr
@@ -9,29 +9,13 @@ LL | |             ASSUME_VALIDITY,
 LL | |             ASSUME_VISIBILITY,
    | |_____________________________- help: remove these generic arguments
 
-error: the constant `ASSUME_ALIGNMENT` is not of type `Assume`
-  --> $DIR/issue-101739-2.rs:17:14
-   |
-LL |           Dst: BikeshedIntrinsicFrom<
-   |  ______________^
-LL | |
-LL | |             Src,
-LL | |             ASSUME_ALIGNMENT,
-...  |
-LL | |             ASSUME_VISIBILITY,
-LL | |         >,
-   | |_________^ expected `Assume`, found `bool`
-   |
-note: required by a bound in `BikeshedIntrinsicFrom`
-  --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL
-
 error[E0308]: mismatched types
-  --> $DIR/issue-101739-2.rs:20:13
+  --> $DIR/issue-101739-2.rs:19:13
    |
 LL |             ASSUME_ALIGNMENT,
    |             ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0107, E0308.
 For more information about an error, try `rustc --explain E0107`.