From aebe8a7ed3f6b915170df8e9056f2bdbaac4de00 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 27 May 2024 08:22:32 +0000 Subject: [PATCH 1/9] Add regression test --- tests/ui/lifetimes/noisy-follow-up-erro.rs | 23 ++++++++++++++++ .../ui/lifetimes/noisy-follow-up-erro.stderr | 27 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 tests/ui/lifetimes/noisy-follow-up-erro.rs create mode 100644 tests/ui/lifetimes/noisy-follow-up-erro.stderr 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 0000000000000..47a87068d8fbf --- /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 0000000000000..f549009a87c12 --- /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`. From 61c4b7f1a701798f01df7a685ee3bb515cb7d9f9 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 27 May 2024 09:45:40 +0000 Subject: [PATCH 2/9] Hide some follow-up errors --- compiler/rustc_hir_analysis/src/impl_wf_check.rs | 2 ++ tests/ui/traits/issue-78372.stderr | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 002be61196aa8..5cc1ec71757be 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/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr index 58a4c229e5e64..cdcb0cdf2593d 100644 --- a/tests/ui/traits/issue-78372.stderr +++ b/tests/ui/traits/issue-78372.stderr @@ -55,12 +55,6 @@ LL | impl DispatchFromDyn> 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 DispatchFromDyn> 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); = 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: Rc`, `self: Arc`, or `self: Pin

` (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 DispatchFromDyn> for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 8 previous errors Some errors have detailed explanations: E0038, E0307, E0378, E0412, E0658. From 4dec6bbcb3b8cae2e35de8b23652be75ac320be1 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 3 Jun 2024 12:56:47 +0000 Subject: [PATCH 3/9] Avoid an `Option` that is always `Some` --- .../src/hir_ty_lowering/generics.rs | 2 +- .../src/hir_ty_lowering/mod.rs | 18 ++++++------- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 25 +++++++++++-------- 3 files changed, 22 insertions(+), 23 deletions(-) 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 d641e33b299ed..ea6841f9a8235 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -610,7 +610,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 54b7f7f36ed2e..4ffc8e5abd86d 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -215,10 +215,9 @@ 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, + pub reported: ErrorGuaranteed, /// A list of spans of arguments provided that were not valid. pub invalid_args: Vec, } @@ -404,10 +403,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. @@ -584,13 +581,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { && generics.has_self && !tcx.has_attr(def_id, sym::const_trait) { - let e = tcx.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait { + let reported = 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![] }); + self.set_tainted_by_errors(reported); + arg_count.correct = Err(GenericArgCountMismatch { reported, invalid_args: vec![] }); } let args = lower_generic_args( tcx, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 0c10c67db8c38..bae99fe797730 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, From 24af952ef7bf02501bf7a991c1c2feb110c77a7f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 3 Jun 2024 13:06:59 +0000 Subject: [PATCH 4/9] Store indices of generic args instead of spans, as the actual entries are unused, just the number of entries is checked. The indices will be used in a follow-up commit --- .../src/hir_ty_lowering/errors.rs | 2 +- .../src/hir_ty_lowering/generics.rs | 15 ++------------- .../rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 4 ++-- 3 files changed, 5 insertions(+), 16 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 821c56530407d..8ea27d0947d5d 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>, - potential_assoc_types: Vec, + potential_assoc_types: Vec, 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 ea6841f9a8235..4ec2aa6c6262c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -474,16 +474,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 +531,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. 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 4ffc8e5abd86d..7aa01b85028c6 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -218,8 +218,8 @@ pub(crate) enum GenericArgPosition { #[derive(Clone, Debug)] pub struct GenericArgCountMismatch { pub reported: ErrorGuaranteed, - /// A list of spans of arguments provided that were not valid. - pub invalid_args: Vec, + /// A list of indices of arguments provided that were not valid. + pub invalid_args: Vec, } /// Decorates the result of a generic argument count mismatch From 2e3842b6d024943dfb06c73dd15e980f6e69fcb7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 3 Jun 2024 13:16:56 +0000 Subject: [PATCH 5/9] Mark all missing generic args as errors --- .../src/hir_ty_lowering/mod.rs | 39 ++++++++++++++---- tests/crashes/123917.rs | 41 ------------------- .../transmutable-ice-110969.rs | 1 - .../transmutable-ice-110969.stderr | 19 +-------- tests/ui/polymorphization/abi_mismatch.rs | 20 +++++++++ tests/ui/polymorphization/abi_mismatch.stderr | 11 +++++ 6 files changed, 63 insertions(+), 68 deletions(-) delete mode 100644 tests/crashes/123917.rs create mode 100644 tests/ui/polymorphization/abi_mismatch.rs create mode 100644 tests/ui/polymorphization/abi_mismatch.stderr 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 7aa01b85028c6..a18164ec74056 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -422,6 +422,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span: Span, inferred_params: Vec, infer_args: bool, + incorrect_args: &'a Result<(), GenericArgCountMismatch>, } impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> { @@ -508,6 +509,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { 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 match param.kind { + GenericParamDefKind::Lifetime => { + ty::Region::new_error(tcx, incorrect.reported).into() + } + GenericParamDefKind::Type { .. } => { + Ty::new_error(tcx, incorrect.reported).into() + } + GenericParamDefKind::Const { .. } => ty::Const::new_error( + tcx, + incorrect.reported, + Ty::new_error(tcx, incorrect.reported), + ) + .into(), + }; + } + } match param.kind { GenericParamDefKind::Lifetime => self .lowerer @@ -568,15 +588,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } } - - let mut args_ctx = GenericArgsCtxt { - lowerer: self, - def_id, - span, - generic_args: segment.args(), - inferred_params: vec![], - infer_args: segment.infer_args, - }; if let ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst = constness && generics.has_self && !tcx.has_attr(def_id, sym::const_trait) @@ -588,6 +599,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.set_tainted_by_errors(reported); arg_count.correct = Err(GenericArgCountMismatch { reported, invalid_args: vec![] }); } + + let mut args_ctx = GenericArgsCtxt { + lowerer: self, + def_id, + span, + generic_args: segment.args(), + inferred_params: vec![], + infer_args: segment.infer_args, + incorrect_args: &arg_count.correct, + }; let args = lower_generic_args( tcx, def_id, diff --git a/tests/crashes/123917.rs b/tests/crashes/123917.rs deleted file mode 100644 index 66e754606622c..0000000000000 --- 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 ::Tokenized, - ptr: core::ptr::NonNull, - _phantom: PhantomData>, -} - -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 68b8b48981680..569e57fa3262a 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::(); //~^ 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 1dbacaee3c2d8..a8fc742e89f54 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::(); | ^^ 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::(); - | ^^^ `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() - | --------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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/polymorphization/abi_mismatch.rs b/tests/ui/polymorphization/abi_mismatch.rs new file mode 100644 index 0000000000000..22c2c162d1c16 --- /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(*mut T); + +struct Token { + ptr: *mut T, + ptr: NonNull, + //~^ ERROR: `ptr` is already declared + _extra_field: (), +} + +fn tokenize(item: *mut T) -> Token { + 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 0000000000000..e96c737f77731 --- /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, + | ^^^^^^^^^^^^^^^ field already declared + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0124`. From adb2ac01657d8c0e972d641b6d22cc9b98ae217a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 3 Jun 2024 13:21:17 +0000 Subject: [PATCH 6/9] Mark all extraneous generic args as errors --- .../src/hir_ty_lowering/mod.rs | 19 +++++++++++ tests/crashes/121134.rs | 20 ------------ ...lid-assoc-type-suggestion-in-trait-impl.rs | 2 -- ...assoc-type-suggestion-in-trait-impl.stderr | 32 ++++++------------- ...aram_mismatch_in_unsatisfied_projection.rs | 27 ++++++++++++++++ ..._mismatch_in_unsatisfied_projection.stderr | 19 +++++++++++ tests/ui/transmutability/issue-101739-2.rs | 1 - .../ui/transmutability/issue-101739-2.stderr | 20 ++---------- 8 files changed, 77 insertions(+), 63 deletions(-) delete mode 100644 tests/crashes/121134.rs create mode 100644 tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.rs create mode 100644 tests/ui/traits/generic_param_mismatch_in_unsatisfied_projection.stderr 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 a18164ec74056..d26ebe9881b85 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -442,6 +442,25 @@ impl<'tcx> dyn HirTyLowerer<'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 match param.kind { + GenericParamDefKind::Lifetime => { + ty::Region::new_error(tcx, incorrect.reported).into() + } + GenericParamDefKind::Type { .. } => { + Ty::new_error(tcx, incorrect.reported).into() + } + GenericParamDefKind::Const { .. } => ty::Const::new_error( + tcx, + incorrect.reported, + Ty::new_error(tcx, incorrect.reported), + ) + .into(), + }; + } + } + let mut handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| { if has_default { tcx.check_optional_stability( diff --git a/tests/crashes/121134.rs b/tests/crashes/121134.rs deleted file mode 100644 index 36397d4ec3c0d..0000000000000 --- 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(&mut self, do_something_wrapper: F) - where - FnOnce:, - F: for<'a> FnOnce(>::Type), - { - } -} - -fn main() { - let mut wrapper = Wrapper; - wrapper.do_something_wrapper::(|value| ()); -} 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 cab484a120c33..445ea2de610fd 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 Trait for i32 { // Should not not trigger suggestion here... impl Trait 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: 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 99e81a9039e73..06e2fa5d4d1fd 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 { | ^^^^^ - -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 Trait 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: T) -> impl Trait<(), i32> { | ^^^^^ expected 1 generic argument @@ -39,7 +33,7 @@ LL | fn func>(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: T) -> impl Trait<(), i32> { | ^^^^^ expected 1 generic argument @@ -55,7 +49,7 @@ LL | fn func>(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: 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: 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: 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> { | ^^^^^ expected 1 generic argument @@ -94,7 +82,7 @@ LL | struct Struct> { | +++++++ 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> {} | ^^^^^ expected 1 generic argument @@ -110,7 +98,7 @@ LL | trait AnotherTrait> {} | +++++++ 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> Struct {} | ^^^^^ expected 1 generic argument @@ -126,7 +114,7 @@ LL | impl> Struct {} | +++++++ 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, U> YetAnotherTrait for Struct {} | ^^^^^^ - help: remove this generic argument @@ -134,12 +122,12 @@ LL | impl, U> YetAnotherTrait for Struct {} | 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> { | ^^^^^^ - -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 0000000000000..bf1278f992b60 --- /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(&mut self, _: F) + where + F: for<'a> FnOnce(>::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 0000000000000..acda3418894d6 --- /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(>::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(>::Type), + | ++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/transmutability/issue-101739-2.rs b/tests/ui/transmutability/issue-101739-2.rs index e2cec24aac147..1c0bd29d70791 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 639b446089248..38912696c18e3 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`. From 063b26af6bf7973768d2616eb4f79fc9b91ee11c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 3 Jun 2024 13:28:49 +0000 Subject: [PATCH 7/9] Explain some code duplication --- compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) 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 d26ebe9881b85..4b8e12a489c53 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -444,6 +444,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if let Err(incorrect) = self.incorrect_args { if incorrect.invalid_args.contains(&(param.index as usize)) { + // FIXME: use `param.to_error` once `provided_kind` is supplied a list of + // all previous generic args. return match param.kind { GenericParamDefKind::Lifetime => { ty::Region::new_error(tcx, incorrect.reported).into() @@ -531,6 +533,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if let Err(incorrect) = self.incorrect_args { if incorrect.invalid_args.contains(&(param.index as usize)) { + // FIXME: use `param.to_error` once `inferred_kind` is supplied a list of + // all previous generic args. return match param.kind { GenericParamDefKind::Lifetime => { ty::Region::new_error(tcx, incorrect.reported).into() From 108a1e5f4be6a9184dee6957bdaa81c0454fb4fd Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 3 Jun 2024 13:45:36 +0000 Subject: [PATCH 8/9] Always provide previous generic arguments --- .../src/hir_ty_lowering/generics.rs | 9 ++-- .../src/hir_ty_lowering/mod.rs | 41 +++++++------------ .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 6 +-- .../rustc_hir_typeck/src/method/confirm.rs | 2 +- 4 files changed, 24 insertions(+), 34 deletions(-) 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 4ec2aa6c6262c..72e03ead76b0e 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(¶m) = 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, _) @@ -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(¶m)) => { // 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(); } 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 4b8e12a489c53..f073d92a1b91b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -245,7 +245,7 @@ pub trait GenericArgsLowerer<'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>; @@ -525,7 +525,7 @@ 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> { @@ -533,22 +533,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if let Err(incorrect) = self.incorrect_args { if incorrect.invalid_args.contains(&(param.index as usize)) { - // FIXME: use `param.to_error` once `inferred_kind` is supplied a list of - // all previous generic args. - return match param.kind { - GenericParamDefKind::Lifetime => { - ty::Region::new_error(tcx, incorrect.reported).into() - } - GenericParamDefKind::Type { .. } => { - Ty::new_error(tcx, incorrect.reported).into() - } - GenericParamDefKind::Const { .. } => ty::Const::new_error( - tcx, - incorrect.reported, - Ty::new_error(tcx, incorrect.reported), - ) - .into(), - }; + return param.to_error(tcx, preceding_args); } } match param.kind { @@ -569,15 +554,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 { @@ -597,7 +586,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 { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index bae99fe797730..5edbf584b2e24 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1317,7 +1317,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> { @@ -1331,7 +1331,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. @@ -1356,7 +1356,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 9c64f9475cf14..cde5c71966cd4 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -419,7 +419,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> { From d498eb59373a71a166f31b1a9b70a7d8ac9cd4a3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 3 Jun 2024 13:48:54 +0000 Subject: [PATCH 9/9] Provide previous generic arguments to `provided_kind` --- .../src/hir_ty_lowering/generics.rs | 2 +- .../src/hir_ty_lowering/mod.rs | 19 +++---------------- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 1 + .../rustc_hir_typeck/src/method/confirm.rs | 1 + 4 files changed, 6 insertions(+), 17 deletions(-) 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 72e03ead76b0e..26cabb69d25c7 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -282,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(); } 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 f073d92a1b91b..56e2a05214eaf 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -239,6 +239,7 @@ pub trait GenericArgsLowerer<'a, 'tcx> { fn provided_kind( &mut self, + preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx>; @@ -437,6 +438,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn provided_kind( &mut self, + preceding_args: &[ty::GenericArg<'tcx>], param: &ty::GenericParamDef, arg: &GenericArg<'tcx>, ) -> ty::GenericArg<'tcx> { @@ -444,22 +446,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if let Err(incorrect) = self.incorrect_args { if incorrect.invalid_args.contains(&(param.index as usize)) { - // FIXME: use `param.to_error` once `provided_kind` is supplied a list of - // all previous generic args. - return match param.kind { - GenericParamDefKind::Lifetime => { - ty::Region::new_error(tcx, incorrect.reported).into() - } - GenericParamDefKind::Type { .. } => { - Ty::new_error(tcx, incorrect.reported).into() - } - GenericParamDefKind::Const { .. } => ty::Const::new_error( - tcx, - incorrect.reported, - Ty::new_error(tcx, incorrect.reported), - ) - .into(), - }; + return param.to_error(tcx, preceding_args); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 5edbf584b2e24..58eb0c2817987 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1275,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> { diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index cde5c71966cd4..0825e66137303 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> {