@@ -2259,9 +2259,99 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
22592259 }
22602260 } ;
22612261
2262- let mut err = match * sub {
2263- ty:: ReEarlyBound ( ty:: EarlyBoundRegion { name, .. } )
2264- | ty:: ReFree ( ty:: FreeRegion { bound_region : ty:: BrNamed ( _, name) , .. } ) => {
2262+ #[ derive( Debug ) ]
2263+ enum SubOrigin < ' hir > {
2264+ GAT ( & ' hir hir:: Generics < ' hir > ) ,
2265+ Impl ( & ' hir hir:: Generics < ' hir > ) ,
2266+ Trait ( & ' hir hir:: Generics < ' hir > ) ,
2267+ Fn ( & ' hir hir:: Generics < ' hir > ) ,
2268+ Unknown ,
2269+ }
2270+ let sub_origin = ' origin: {
2271+ match * sub {
2272+ ty:: ReEarlyBound ( ty:: EarlyBoundRegion { def_id, .. } ) => {
2273+ let node = self . tcx . hir ( ) . get_if_local ( def_id) . unwrap ( ) ;
2274+ match node {
2275+ Node :: GenericParam ( param) => {
2276+ for h in self . tcx . hir ( ) . parent_iter ( param. hir_id ) {
2277+ break ' origin match h. 1 {
2278+ Node :: ImplItem ( hir:: ImplItem {
2279+ kind : hir:: ImplItemKind :: TyAlias ( ..) ,
2280+ generics,
2281+ ..
2282+ } ) => SubOrigin :: GAT ( generics) ,
2283+ Node :: ImplItem ( hir:: ImplItem {
2284+ kind : hir:: ImplItemKind :: Fn ( ..) ,
2285+ generics,
2286+ ..
2287+ } ) => SubOrigin :: Fn ( generics) ,
2288+ Node :: TraitItem ( hir:: TraitItem {
2289+ kind : hir:: TraitItemKind :: Type ( ..) ,
2290+ generics,
2291+ ..
2292+ } ) => SubOrigin :: GAT ( generics) ,
2293+ Node :: TraitItem ( hir:: TraitItem {
2294+ kind : hir:: TraitItemKind :: Fn ( ..) ,
2295+ generics,
2296+ ..
2297+ } ) => SubOrigin :: Fn ( generics) ,
2298+ Node :: Item ( hir:: Item {
2299+ kind : hir:: ItemKind :: Trait ( _, _, generics, _, _) ,
2300+ ..
2301+ } ) => SubOrigin :: Trait ( generics) ,
2302+ Node :: Item ( hir:: Item {
2303+ kind : hir:: ItemKind :: Impl ( hir:: Impl { generics, .. } ) ,
2304+ ..
2305+ } ) => SubOrigin :: Impl ( generics) ,
2306+ Node :: Item ( hir:: Item {
2307+ kind : hir:: ItemKind :: Fn ( _, generics, _) ,
2308+ ..
2309+ } ) => SubOrigin :: Fn ( generics) ,
2310+ _ => continue ,
2311+ } ;
2312+ }
2313+ }
2314+ _ => { }
2315+ }
2316+ }
2317+ _ => { }
2318+ }
2319+ SubOrigin :: Unknown
2320+ } ;
2321+ debug ! ( ?sub_origin) ;
2322+
2323+ let mut err = match ( * sub, sub_origin) {
2324+ // In the case of GATs, we have to be careful. If we a type parameter `T` on an impl,
2325+ // but a lifetime `'a` on an associated type, then we might need to suggest adding
2326+ // `where T: 'a`. Importantly, this is on the GAT span, not on the `T` declaration.
2327+ ( ty:: ReEarlyBound ( ty:: EarlyBoundRegion { name : _, .. } ) , SubOrigin :: GAT ( generics) ) => {
2328+ // Does the required lifetime have a nice name we can print?
2329+ let mut err = struct_span_err ! (
2330+ self . tcx. sess,
2331+ span,
2332+ E0309 ,
2333+ "{} may not live long enough" ,
2334+ labeled_user_string
2335+ ) ;
2336+ let pred = format ! ( "{}: {}" , bound_kind, sub) ;
2337+ let suggestion = format ! (
2338+ "{} {}" ,
2339+ if !generics. where_clause. predicates. is_empty( ) { "," } else { " where" } ,
2340+ pred,
2341+ ) ;
2342+ err. span_suggestion (
2343+ generics. where_clause . tail_span_for_suggestion ( ) ,
2344+ "consider adding a where clause" . into ( ) ,
2345+ suggestion,
2346+ Applicability :: MaybeIncorrect ,
2347+ ) ;
2348+ err
2349+ }
2350+ (
2351+ ty:: ReEarlyBound ( ty:: EarlyBoundRegion { name, .. } )
2352+ | ty:: ReFree ( ty:: FreeRegion { bound_region : ty:: BrNamed ( _, name) , .. } ) ,
2353+ _,
2354+ ) => {
22652355 // Does the required lifetime have a nice name we can print?
22662356 let mut err = struct_span_err ! (
22672357 self . tcx. sess,
@@ -2278,7 +2368,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
22782368 err
22792369 }
22802370
2281- ty:: ReStatic => {
2371+ ( ty:: ReStatic , _ ) => {
22822372 // Does the required lifetime have a nice name we can print?
22832373 let mut err = struct_span_err ! (
22842374 self . tcx. sess,
0 commit comments