@@ -54,13 +54,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
5454 }
5555 ( ty:: Param ( expected) , ty:: Param ( found) ) => {
5656 let generics = tcx. generics_of ( body_owner_def_id) ;
57- let e_span = tcx. def_span ( generics. type_param ( expected, tcx) . def_id ) ;
58- if !sp. contains ( e_span) {
59- diag. span_label ( e_span, "expected type parameter" ) ;
57+ if let Some ( param) = generics. opt_type_param ( expected, tcx) {
58+ let e_span = tcx. def_span ( param. def_id ) ;
59+ if !sp. contains ( e_span) {
60+ diag. span_label ( e_span, "expected type parameter" ) ;
61+ }
6062 }
61- let f_span = tcx. def_span ( generics. type_param ( found, tcx) . def_id ) ;
62- if !sp. contains ( f_span) {
63- diag. span_label ( f_span, "found type parameter" ) ;
63+ if let Some ( param) = generics. opt_type_param ( found, tcx) {
64+ let f_span = tcx. def_span ( param. def_id ) ;
65+ if !sp. contains ( f_span) {
66+ diag. span_label ( f_span, "found type parameter" ) ;
67+ }
6468 }
6569 diag. note (
6670 "a type parameter was expected, but a different one was found; \
@@ -83,23 +87,29 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
8387 | ( ty:: Alias ( ty:: Projection , proj) , ty:: Param ( p) )
8488 if !tcx. is_impl_trait_in_trait ( proj. def_id ) =>
8589 {
86- let p_def_id = tcx. generics_of ( body_owner_def_id) . type_param ( p, tcx) . def_id ;
87- let p_span = tcx. def_span ( p_def_id) ;
88- let expected = match ( values. expected . kind ( ) , values. found . kind ( ) ) {
89- ( ty:: Param ( _) , _) => "expected " ,
90- ( _, ty:: Param ( _) ) => "found " ,
91- _ => "" ,
92- } ;
93- if !sp. contains ( p_span) {
94- diag. span_label ( p_span, format ! ( "{expected}this type parameter" ) ) ;
95- }
96- let hir = tcx. hir ( ) ;
90+ let parent = tcx. generics_of ( body_owner_def_id)
91+ . opt_type_param ( p, tcx)
92+ . and_then ( |param| {
93+ let p_def_id = param. def_id ;
94+ let p_span = tcx. def_span ( p_def_id) ;
95+ let expected = match ( values. expected . kind ( ) , values. found . kind ( ) ) {
96+ ( ty:: Param ( _) , _) => "expected " ,
97+ ( _, ty:: Param ( _) ) => "found " ,
98+ _ => "" ,
99+ } ;
100+ if !sp. contains ( p_span) {
101+ diag. span_label (
102+ p_span,
103+ format ! ( "{expected}this type parameter" ) ,
104+ ) ;
105+ }
106+ p_def_id. as_local ( ) . and_then ( |id| {
107+ let local_id = tcx. hir ( ) . local_def_id_to_hir_id ( id) ;
108+ let generics = tcx. hir ( ) . find_parent ( local_id) ?. generics ( ) ?;
109+ Some ( ( id, generics) )
110+ } )
111+ } ) ;
97112 let mut note = true ;
98- let parent = p_def_id. as_local ( ) . and_then ( |id| {
99- let local_id = hir. local_def_id_to_hir_id ( id) ;
100- let generics = tcx. hir ( ) . find_parent ( local_id) ?. generics ( ) ?;
101- Some ( ( id, generics) )
102- } ) ;
103113 if let Some ( ( local_id, generics) ) = parent {
104114 // Synthesize the associated type restriction `Add<Output = Expected>`.
105115 // FIXME: extract this logic for use in other diagnostics.
@@ -172,14 +182,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
172182 ( ty:: Param ( p) , ty:: Dynamic ( ..) | ty:: Alias ( ty:: Opaque , ..) )
173183 | ( ty:: Dynamic ( ..) | ty:: Alias ( ty:: Opaque , ..) , ty:: Param ( p) ) => {
174184 let generics = tcx. generics_of ( body_owner_def_id) ;
175- let p_span = tcx. def_span ( generics. type_param ( p, tcx) . def_id ) ;
176- let expected = match ( values. expected . kind ( ) , values. found . kind ( ) ) {
177- ( ty:: Param ( _) , _) => "expected " ,
178- ( _, ty:: Param ( _) ) => "found " ,
179- _ => "" ,
180- } ;
181- if !sp. contains ( p_span) {
182- diag. span_label ( p_span, format ! ( "{expected}this type parameter" ) ) ;
185+ if let Some ( param) = generics. opt_type_param ( p, tcx) {
186+ let p_span = tcx. def_span ( param. def_id ) ;
187+ let expected = match ( values. expected . kind ( ) , values. found . kind ( ) ) {
188+ ( ty:: Param ( _) , _) => "expected " ,
189+ ( _, ty:: Param ( _) ) => "found " ,
190+ _ => "" ,
191+ } ;
192+ if !sp. contains ( p_span) {
193+ diag. span_label ( p_span, format ! ( "{expected}this type parameter" ) ) ;
194+ }
183195 }
184196 diag. help ( "type parameters must be constrained to match other types" ) ;
185197 if tcx. sess . teach ( & diag. get_code ( ) . unwrap ( ) ) {
@@ -217,9 +229,11 @@ impl<T> Trait<T> for X {
217229 }
218230 ( ty:: Param ( p) , ty:: Closure ( ..) | ty:: Coroutine ( ..) ) => {
219231 let generics = tcx. generics_of ( body_owner_def_id) ;
220- let p_span = tcx. def_span ( generics. type_param ( p, tcx) . def_id ) ;
221- if !sp. contains ( p_span) {
222- diag. span_label ( p_span, "expected this type parameter" ) ;
232+ if let Some ( param) = generics. opt_type_param ( p, tcx) {
233+ let p_span = tcx. def_span ( param. def_id ) ;
234+ if !sp. contains ( p_span) {
235+ diag. span_label ( p_span, "expected this type parameter" ) ;
236+ }
223237 }
224238 diag. help ( format ! (
225239 "every closure has a distinct type and so could not always match the \
@@ -228,14 +242,16 @@ impl<T> Trait<T> for X {
228242 }
229243 ( ty:: Param ( p) , _) | ( _, ty:: Param ( p) ) => {
230244 let generics = tcx. generics_of ( body_owner_def_id) ;
231- let p_span = tcx. def_span ( generics. type_param ( p, tcx) . def_id ) ;
232- let expected = match ( values. expected . kind ( ) , values. found . kind ( ) ) {
233- ( ty:: Param ( _) , _) => "expected " ,
234- ( _, ty:: Param ( _) ) => "found " ,
235- _ => "" ,
236- } ;
237- if !sp. contains ( p_span) {
238- diag. span_label ( p_span, format ! ( "{expected}this type parameter" ) ) ;
245+ if let Some ( param) = generics. opt_type_param ( p, tcx) {
246+ let p_span = tcx. def_span ( param. def_id ) ;
247+ let expected = match ( values. expected . kind ( ) , values. found . kind ( ) ) {
248+ ( ty:: Param ( _) , _) => "expected " ,
249+ ( _, ty:: Param ( _) ) => "found " ,
250+ _ => "" ,
251+ } ;
252+ if !sp. contains ( p_span) {
253+ diag. span_label ( p_span, format ! ( "{expected}this type parameter" ) ) ;
254+ }
239255 }
240256 }
241257 ( ty:: Alias ( ty:: Projection | ty:: Inherent , proj_ty) , _)
@@ -364,13 +380,14 @@ impl<T> Trait<T> for X {
364380 } ;
365381 // Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
366382 // This will also work for `impl Trait`.
367- let def_id = if let ty:: Param ( param_ty) = proj_ty. self_ty ( ) . kind ( ) {
368- let generics = tcx. generics_of ( body_owner_def_id) ;
369- generics. type_param ( param_ty, tcx) . def_id
370- } else {
383+ let ty:: Param ( param_ty) = proj_ty. self_ty ( ) . kind ( ) else {
371384 return false ;
372385 } ;
373- let Some ( def_id) = def_id. as_local ( ) else {
386+ let generics = tcx. generics_of ( body_owner_def_id) ;
387+ let Some ( param) = generics. opt_type_param ( param_ty, tcx) else {
388+ return false ;
389+ } ;
390+ let Some ( def_id) = param. def_id . as_local ( ) else {
374391 return false ;
375392 } ;
376393
@@ -390,6 +407,10 @@ impl<T> Trait<T> for X {
390407 return true ;
391408 }
392409 }
410+ if ( param_ty. index as usize ) >= generics. parent_count {
411+ // The param comes from the current item, do not look at the parent. (#117209)
412+ return false ;
413+ }
393414 // If associated item, look to constrain the params of the trait/impl.
394415 let hir_id = match item {
395416 hir:: Node :: ImplItem ( item) => item. hir_id ( ) ,
0 commit comments