@@ -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,28 @@ 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- _ => "" ,
90+ let parent = if let Some ( param) = tcx. generics_of ( body_owner_def_id)
91+ . opt_type_param ( p, tcx)
92+ {
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 ( p_span, format ! ( "{expected}this type parameter" ) ) ;
102+ }
103+ p_def_id. as_local ( ) . and_then ( |id| {
104+ let local_id = tcx. hir ( ) . local_def_id_to_hir_id ( id) ;
105+ let generics = tcx. hir ( ) . find_parent ( local_id) ?. generics ( ) ?;
106+ Some ( ( id, generics) )
107+ } )
108+ } else {
109+ None
92110 } ;
93- if !sp. contains ( p_span) {
94- diag. span_label ( p_span, format ! ( "{expected}this type parameter" ) ) ;
95- }
96- let hir = tcx. hir ( ) ;
97111 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- } ) ;
103112 if let Some ( ( local_id, generics) ) = parent {
104113 // Synthesize the associated type restriction `Add<Output = Expected>`.
105114 // FIXME: extract this logic for use in other diagnostics.
@@ -172,14 +181,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
172181 ( ty:: Param ( p) , ty:: Dynamic ( ..) | ty:: Alias ( ty:: Opaque , ..) )
173182 | ( ty:: Dynamic ( ..) | ty:: Alias ( ty:: Opaque , ..) , ty:: Param ( p) ) => {
174183 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" ) ) ;
184+ if let Some ( param) = generics. opt_type_param ( p, tcx) {
185+ let p_span = tcx. def_span ( param. def_id ) ;
186+ let expected = match ( values. expected . kind ( ) , values. found . kind ( ) ) {
187+ ( ty:: Param ( _) , _) => "expected " ,
188+ ( _, ty:: Param ( _) ) => "found " ,
189+ _ => "" ,
190+ } ;
191+ if !sp. contains ( p_span) {
192+ diag. span_label ( p_span, format ! ( "{expected}this type parameter" ) ) ;
193+ }
183194 }
184195 diag. help ( "type parameters must be constrained to match other types" ) ;
185196 if tcx. sess . teach ( & diag. get_code ( ) . unwrap ( ) ) {
@@ -217,9 +228,11 @@ impl<T> Trait<T> for X {
217228 }
218229 ( ty:: Param ( p) , ty:: Closure ( ..) | ty:: Coroutine ( ..) ) => {
219230 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" ) ;
231+ if let Some ( param) = generics. opt_type_param ( p, tcx) {
232+ let p_span = tcx. def_span ( param. def_id ) ;
233+ if !sp. contains ( p_span) {
234+ diag. span_label ( p_span, "expected this type parameter" ) ;
235+ }
223236 }
224237 diag. help ( format ! (
225238 "every closure has a distinct type and so could not always match the \
@@ -228,14 +241,16 @@ impl<T> Trait<T> for X {
228241 }
229242 ( ty:: Param ( p) , _) | ( _, ty:: Param ( p) ) => {
230243 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" ) ) ;
244+ if let Some ( param) = generics. opt_type_param ( p, tcx) {
245+ let p_span = tcx. def_span ( param. def_id ) ;
246+ let expected = match ( values. expected . kind ( ) , values. found . kind ( ) ) {
247+ ( ty:: Param ( _) , _) => "expected " ,
248+ ( _, ty:: Param ( _) ) => "found " ,
249+ _ => "" ,
250+ } ;
251+ if !sp. contains ( p_span) {
252+ diag. span_label ( p_span, format ! ( "{expected}this type parameter" ) ) ;
253+ }
239254 }
240255 }
241256 ( ty:: Alias ( ty:: Projection | ty:: Inherent , proj_ty) , _)
@@ -368,8 +383,10 @@ impl<T> Trait<T> for X {
368383 return false ;
369384 } ;
370385 let generics = tcx. generics_of ( body_owner_def_id) ;
371- let def_id = generics. type_param ( param_ty, tcx) . def_id ;
372- let Some ( def_id) = def_id. as_local ( ) else {
386+ let Some ( param) = generics. opt_type_param ( param_ty, tcx) else {
387+ return false ;
388+ } ;
389+ let Some ( def_id) = param. def_id . as_local ( ) else {
373390 return false ;
374391 } ;
375392
0 commit comments