@@ -22,12 +22,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
2222 err : TypeError < ' tcx > ,
2323 cause : & ObligationCause < ' tcx > ,
2424 sp : Span ,
25- body_owner_def_id : DefId ,
25+ body_owner_def_id : Option < DefId > ,
2626 ) {
2727 debug ! ( "note_and_explain_type_err err={:?} cause={:?}" , err, cause) ;
2828
2929 let tcx = self . tcx ;
3030
31+ let body_generics = body_owner_def_id. map ( |def_id| tcx. generics_of ( def_id) ) ;
32+
3133 match err {
3234 TypeError :: ArgumentSorts ( values, _) | TypeError :: Sorts ( values) => {
3335 match ( * values. expected . kind ( ) , * values. found . kind ( ) ) {
@@ -64,14 +66,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
6466 }
6567 }
6668 ( ty:: Param ( expected) , ty:: Param ( found) ) => {
67- let generics = tcx. generics_of ( body_owner_def_id) ;
68- let e_span = tcx. def_span ( generics. type_param ( expected, tcx) . def_id ) ;
69- if !sp. contains ( e_span) {
70- diag. span_label ( e_span, "expected type parameter" ) ;
71- }
72- let f_span = tcx. def_span ( generics. type_param ( found, tcx) . def_id ) ;
73- if !sp. contains ( f_span) {
74- diag. span_label ( f_span, "found type parameter" ) ;
69+ if let Some ( generics) = body_generics {
70+ let e_span = tcx. def_span ( generics. type_param ( expected, tcx) . def_id ) ;
71+ if !sp. contains ( e_span) {
72+ diag. span_label ( e_span, "expected type parameter" ) ;
73+ }
74+ let f_span = tcx. def_span ( generics. type_param ( found, tcx) . def_id ) ;
75+ if !sp. contains ( f_span) {
76+ diag. span_label ( f_span, "found type parameter" ) ;
77+ }
7578 }
7679 diag. note (
7780 "a type parameter was expected, but a different one was found; \
@@ -92,9 +95,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
9295 // FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too.
9396 ( ty:: Param ( p) , ty:: Alias ( ty:: Projection , proj) )
9497 | ( ty:: Alias ( ty:: Projection , proj) , ty:: Param ( p) )
95- if !tcx. is_impl_trait_in_trait ( proj. def_id ) =>
98+ if !tcx. is_impl_trait_in_trait ( proj. def_id )
99+ && let Some ( generics) = body_generics =>
96100 {
97- let param = tcx . generics_of ( body_owner_def_id ) . type_param ( p, tcx) ;
101+ let param = generics . type_param ( p, tcx) ;
98102 let p_def_id = param. def_id ;
99103 let p_span = tcx. def_span ( p_def_id) ;
100104 let expected = match ( values. expected . kind ( ) , values. found . kind ( ) ) {
@@ -106,9 +110,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
106110 diag. span_label ( p_span, format ! ( "{expected}this type parameter" ) ) ;
107111 }
108112 let param_def_id = match * proj. self_ty ( ) . kind ( ) {
109- ty:: Param ( param) => {
110- tcx. generics_of ( body_owner_def_id) . type_param ( param, tcx) . def_id
111- }
113+ ty:: Param ( param) => generics. type_param ( param, tcx) . def_id ,
112114 _ => p_def_id,
113115 } ;
114116 let parent = param_def_id. as_local ( ) . and_then ( |id| {
@@ -188,15 +190,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
188190 }
189191 ( ty:: Param ( p) , ty:: Dynamic ( ..) | ty:: Alias ( ty:: Opaque , ..) )
190192 | ( ty:: Dynamic ( ..) | ty:: Alias ( ty:: Opaque , ..) , ty:: Param ( p) ) => {
191- let generics = tcx. generics_of ( body_owner_def_id) ;
192- let p_span = tcx. def_span ( generics. type_param ( p, tcx) . def_id ) ;
193- let expected = match ( values. expected . kind ( ) , values. found . kind ( ) ) {
194- ( ty:: Param ( _) , _) => "expected " ,
195- ( _, ty:: Param ( _) ) => "found " ,
196- _ => "" ,
197- } ;
198- if !sp. contains ( p_span) {
199- diag. span_label ( p_span, format ! ( "{expected}this type parameter" ) ) ;
193+ if let Some ( generics) = body_generics {
194+ let p_span = tcx. def_span ( generics. type_param ( p, tcx) . def_id ) ;
195+ let expected = match ( values. expected . kind ( ) , values. found . kind ( ) ) {
196+ ( ty:: Param ( _) , _) => "expected " ,
197+ ( _, ty:: Param ( _) ) => "found " ,
198+ _ => "" ,
199+ } ;
200+ if !sp. contains ( p_span) {
201+ diag. span_label ( p_span, format ! ( "{expected}this type parameter" ) ) ;
202+ }
200203 }
201204 diag. help ( "type parameters must be constrained to match other types" ) ;
202205 if diag. code . is_some_and ( |code| tcx. sess . teach ( code) ) {
@@ -236,18 +239,18 @@ impl<T> Trait<T> for X {
236239 ty:: Param ( p) ,
237240 ty:: Closure ( ..) | ty:: CoroutineClosure ( ..) | ty:: Coroutine ( ..) ,
238241 ) => {
239- let generics = tcx. generics_of ( body_owner_def_id) ;
240- let p_span = tcx. def_span ( generics. type_param ( p, tcx) . def_id ) ;
241- if !sp. contains ( p_span) {
242- diag. span_label ( p_span, "expected this type parameter" ) ;
242+ if let Some ( generics) = body_generics {
243+ let p_span = tcx. def_span ( generics. type_param ( p, tcx) . def_id ) ;
244+ if !sp. contains ( p_span) {
245+ diag. span_label ( p_span, "expected this type parameter" ) ;
246+ }
243247 }
244248 diag. help ( format ! (
245249 "every closure has a distinct type and so could not always match the \
246250 caller-chosen type of parameter `{p}`"
247251 ) ) ;
248252 }
249- ( ty:: Param ( p) , _) | ( _, ty:: Param ( p) ) => {
250- let generics = tcx. generics_of ( body_owner_def_id) ;
253+ ( ty:: Param ( p) , _) | ( _, ty:: Param ( p) ) if let Some ( generics) = body_generics => {
251254 let p_span = tcx. def_span ( generics. type_param ( p, tcx) . def_id ) ;
252255 let expected = match ( values. expected . kind ( ) , values. found . kind ( ) ) {
253256 ( ty:: Param ( _) , _) => "expected " ,
@@ -366,7 +369,8 @@ impl<T> Trait<T> for X {
366369 }
367370 ( _, ty:: Alias ( ty:: Opaque , opaque_ty) )
368371 | ( ty:: Alias ( ty:: Opaque , opaque_ty) , _) => {
369- if opaque_ty. def_id . is_local ( )
372+ if let Some ( body_owner_def_id) = body_owner_def_id
373+ && opaque_ty. def_id . is_local ( )
370374 && matches ! (
371375 tcx. def_kind( body_owner_def_id) ,
372376 DefKind :: Fn
@@ -560,11 +564,14 @@ impl<T> Trait<T> for X {
560564 & self ,
561565 diag : & mut Diag < ' _ > ,
562566 msg : impl Fn ( ) -> String ,
563- body_owner_def_id : DefId ,
567+ body_owner_def_id : Option < DefId > ,
564568 proj_ty : ty:: AliasTy < ' tcx > ,
565569 ty : Ty < ' tcx > ,
566570 ) -> bool {
567571 let tcx = self . tcx ;
572+ let Some ( body_owner_def_id) = body_owner_def_id else {
573+ return false ;
574+ } ;
568575 let assoc = tcx. associated_item ( proj_ty. def_id ) ;
569576 let ( trait_ref, assoc_args) = proj_ty. trait_ref_and_own_args ( tcx) ;
570577 let Some ( item) = tcx. hir_get_if_local ( body_owner_def_id) else {
@@ -611,7 +618,7 @@ impl<T> Trait<T> for X {
611618 _ => return false ,
612619 } ;
613620 let parent = tcx. hir_get_parent_item ( hir_id) . def_id ;
614- self . suggest_constraint ( diag, msg, parent. into ( ) , proj_ty, ty)
621+ self . suggest_constraint ( diag, msg, Some ( parent. into ( ) ) , proj_ty, ty)
615622 }
616623
617624 /// An associated type was expected and a different type was found.
@@ -632,7 +639,7 @@ impl<T> Trait<T> for X {
632639 diag : & mut Diag < ' _ > ,
633640 proj_ty : ty:: AliasTy < ' tcx > ,
634641 values : ExpectedFound < Ty < ' tcx > > ,
635- body_owner_def_id : DefId ,
642+ body_owner_def_id : Option < DefId > ,
636643 cause_code : & ObligationCauseCode < ' _ > ,
637644 ) {
638645 let tcx = self . tcx ;
@@ -653,7 +660,7 @@ impl<T> Trait<T> for X {
653660 )
654661 } ;
655662
656- let body_owner = tcx. hir_get_if_local ( body_owner_def_id ) ;
663+ let body_owner = body_owner_def_id . and_then ( |id| tcx. hir_get_if_local ( id ) ) ;
657664 let current_method_ident = body_owner. and_then ( |n| n. ident ( ) ) . map ( |i| i. name ) ;
658665
659666 // We don't want to suggest calling an assoc fn in a scope where that isn't feasible.
@@ -835,12 +842,12 @@ fn foo(&self) -> Self::T { String::new() }
835842 fn point_at_associated_type (
836843 & self ,
837844 diag : & mut Diag < ' _ > ,
838- body_owner_def_id : DefId ,
845+ body_owner_def_id : Option < DefId > ,
839846 found : Ty < ' tcx > ,
840847 ) -> bool {
841848 let tcx = self . tcx ;
842849
843- let Some ( def_id) = body_owner_def_id. as_local ( ) else {
850+ let Some ( def_id) = body_owner_def_id. and_then ( |id| id . as_local ( ) ) else {
844851 return false ;
845852 } ;
846853
@@ -852,7 +859,7 @@ fn foo(&self) -> Self::T { String::new() }
852859
853860 debug ! ( "expected_projection parent item {:?}" , item) ;
854861
855- let param_env = tcx. param_env ( body_owner_def_id ) ;
862+ let param_env = tcx. param_env ( def_id ) ;
856863
857864 if let DefKind :: Trait | DefKind :: Impl { .. } = tcx. def_kind ( parent_id) {
858865 let assoc_items = tcx. associated_items ( parent_id) ;
0 commit comments