diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index e1980f4d7bb..9ce640ea0f9 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -1,4 +1,4 @@ -use crate::traits::specialization_graph; +use crate::traits::{check_args_compatible, specialization_graph}; use super::assembly::{self, structural_traits}; use super::EvalCtxt; @@ -190,11 +190,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); }; - if !assoc_def.item.defaultness(tcx).has_value() { - let guar = tcx.sess.delay_span_bug( - tcx.def_span(assoc_def.item.def_id), - "missing value for assoc item in impl", - ); + let error_response = |ecx: &mut EvalCtxt<'_, 'tcx>, reason| { + let guar = tcx.sess.delay_span_bug(tcx.def_span(assoc_def.item.def_id), reason); let error_term = match assoc_def.item.kind { ty::AssocKind::Const => ty::Const::new_error( tcx, @@ -208,7 +205,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { }; ecx.eq(goal.param_env, goal.predicate.term, error_term) .expect("expected goal term to be fully unconstrained"); - return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }; + + if !assoc_def.item.defaultness(tcx).has_value() { + return error_response(ecx, "missing value for assoc item in impl"); } // Getting the right args here is complex, e.g. given: @@ -233,6 +234,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { assoc_def.defining_node, ); + if !check_args_compatible(tcx, assoc_def.item, args) { + return error_response( + ecx, + "associated item has mismatched generic item arguments", + ); + } + // Finally we construct the actual value of the associated type. let term = match assoc_def.item.kind { ty::AssocKind::Type => tcx.type_of(assoc_def.item.def_id).map_bound(|ty| ty.into()), diff --git a/tests/ui/generic-associated-types/issue-102114.stderr b/tests/ui/generic-associated-types/issue-102114.current.stderr similarity index 91% rename from tests/ui/generic-associated-types/issue-102114.stderr rename to tests/ui/generic-associated-types/issue-102114.current.stderr index 8e41dee54d7..6e7a0b1f67f 100644 --- a/tests/ui/generic-associated-types/issue-102114.stderr +++ b/tests/ui/generic-associated-types/issue-102114.current.stderr @@ -1,5 +1,5 @@ error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters - --> $DIR/issue-102114.rs:11:12 + --> $DIR/issue-102114.rs:14:12 | LL | type B<'b>; | -- expected 0 type parameters diff --git a/tests/ui/generic-associated-types/issue-102114.next.stderr b/tests/ui/generic-associated-types/issue-102114.next.stderr new file mode 100644 index 00000000000..6e7a0b1f67f --- /dev/null +++ b/tests/ui/generic-associated-types/issue-102114.next.stderr @@ -0,0 +1,12 @@ +error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters + --> $DIR/issue-102114.rs:14:12 + | +LL | type B<'b>; + | -- expected 0 type parameters +... +LL | type B = Wrapper; + | ^ found 1 type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/generic-associated-types/issue-102114.rs b/tests/ui/generic-associated-types/issue-102114.rs index de31737efef..bb6622c0a5f 100644 --- a/tests/ui/generic-associated-types/issue-102114.rs +++ b/tests/ui/generic-associated-types/issue-102114.rs @@ -1,3 +1,6 @@ +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next + trait A { type B<'b>; fn a() -> Self::B<'static>;