@@ -2259,9 +2259,99 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2259
2259
}
2260
2260
} ;
2261
2261
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
+ ) => {
2265
2355
// Does the required lifetime have a nice name we can print?
2266
2356
let mut err = struct_span_err ! (
2267
2357
self . tcx. sess,
@@ -2278,7 +2368,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2278
2368
err
2279
2369
}
2280
2370
2281
- ty:: ReStatic => {
2371
+ ( ty:: ReStatic , _ ) => {
2282
2372
// Does the required lifetime have a nice name we can print?
2283
2373
let mut err = struct_span_err ! (
2284
2374
self . tcx. sess,
0 commit comments