@@ -63,7 +63,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, Mul
63
63
use rustc_hir as hir;
64
64
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
65
65
use rustc_hir:: lang_items:: LangItem ;
66
- use rustc_hir:: { Item , ItemKind , Node } ;
66
+ use rustc_hir:: Node ;
67
67
use rustc_middle:: dep_graph:: DepContext ;
68
68
use rustc_middle:: ty:: print:: with_no_trimmed_paths;
69
69
use rustc_middle:: ty:: {
@@ -348,7 +348,11 @@ pub fn same_type_modulo_infer<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
348
348
}
349
349
350
350
impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
351
- pub fn report_region_errors ( & self , errors : & [ RegionResolutionError < ' tcx > ] ) {
351
+ pub fn report_region_errors (
352
+ & self ,
353
+ generic_param_scope : LocalDefId ,
354
+ errors : & [ RegionResolutionError < ' tcx > ] ,
355
+ ) {
352
356
debug ! ( "report_region_errors(): {} errors to start" , errors. len( ) ) ;
353
357
354
358
// try to pre-process the errors, which will group some of them
@@ -379,6 +383,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
379
383
380
384
RegionResolutionError :: GenericBoundFailure ( origin, param_ty, sub) => {
381
385
self . report_generic_bound_failure (
386
+ generic_param_scope,
382
387
origin. span ( ) ,
383
388
Some ( origin) ,
384
389
param_ty,
@@ -2269,56 +2274,30 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2269
2274
2270
2275
pub fn report_generic_bound_failure (
2271
2276
& self ,
2277
+ generic_param_scope : LocalDefId ,
2272
2278
span : Span ,
2273
2279
origin : Option < SubregionOrigin < ' tcx > > ,
2274
2280
bound_kind : GenericKind < ' tcx > ,
2275
2281
sub : Region < ' tcx > ,
2276
2282
) {
2277
- let owner =
2278
- self . in_progress_typeck_results . map ( |typeck_results| typeck_results. borrow ( ) . hir_owner ) ;
2279
- self . construct_generic_bound_failure ( span, origin, bound_kind, sub, owner) . emit ( ) ;
2283
+ self . construct_generic_bound_failure ( generic_param_scope, span, origin, bound_kind, sub)
2284
+ . emit ( ) ;
2280
2285
}
2281
2286
2282
2287
pub fn construct_generic_bound_failure (
2283
2288
& self ,
2289
+ generic_param_scope : LocalDefId ,
2284
2290
span : Span ,
2285
2291
origin : Option < SubregionOrigin < ' tcx > > ,
2286
2292
bound_kind : GenericKind < ' tcx > ,
2287
2293
sub : Region < ' tcx > ,
2288
- owner : Option < LocalDefId > ,
2289
2294
) -> DiagnosticBuilder < ' a , ErrorGuaranteed > {
2290
- let hir = self . tcx . hir ( ) ;
2291
2295
// Attempt to obtain the span of the parameter so we can
2292
2296
// suggest adding an explicit lifetime bound to it.
2293
- let generics = owner. map ( |owner| {
2294
- let hir_id = hir. local_def_id_to_hir_id ( owner) ;
2295
- let parent_id = hir. get_parent_item ( hir_id) ;
2296
- (
2297
- // Parent item could be a `mod`, so we check the HIR before calling:
2298
- if let Some ( Node :: Item ( Item {
2299
- kind : ItemKind :: Trait ( ..) | ItemKind :: Impl { .. } ,
2300
- ..
2301
- } ) ) = hir. find_by_def_id ( parent_id)
2302
- {
2303
- Some ( self . tcx . generics_of ( parent_id) )
2304
- } else {
2305
- None
2306
- } ,
2307
- self . tcx . generics_of ( owner. to_def_id ( ) ) ,
2308
- hir. span ( hir_id) ,
2309
- )
2310
- } ) ;
2311
-
2312
- let span = match generics {
2313
- // This is to get around the trait identity obligation, that has a `DUMMY_SP` as signal
2314
- // for other diagnostics, so we need to recover it here.
2315
- Some ( ( _, _, node) ) if span. is_dummy ( ) => node,
2316
- _ => span,
2317
- } ;
2318
-
2297
+ let generics = self . tcx . generics_of ( generic_param_scope) ;
2319
2298
// type_param_span is (span, has_bounds)
2320
- let type_param_span = match ( generics , bound_kind) {
2321
- ( Some ( ( _ , ref generics , _ ) ) , GenericKind :: Param ( ref param) ) => {
2299
+ let type_param_span = match bound_kind {
2300
+ GenericKind :: Param ( ref param) => {
2322
2301
// Account for the case where `param` corresponds to `Self`,
2323
2302
// which doesn't have the expected type argument.
2324
2303
if !( generics. has_self && param. index == 0 ) {
@@ -2346,30 +2325,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2346
2325
}
2347
2326
_ => None ,
2348
2327
} ;
2349
- let new_lt = generics
2350
- . as_ref ( )
2351
- . and_then ( |( parent_g, g, _) | {
2352
- let mut possible = ( b'a' ..=b'z' ) . map ( |c| format ! ( "'{}" , c as char ) ) ;
2353
- let mut lts_names = g
2354
- . params
2355
- . iter ( )
2328
+
2329
+ let new_lt = {
2330
+ let mut possible = ( b'a' ..=b'z' ) . map ( |c| format ! ( "'{}" , c as char ) ) ;
2331
+ let lts_names =
2332
+ iter:: successors ( Some ( generics) , |g| g. parent . map ( |p| self . tcx . generics_of ( p) ) )
2333
+ . flat_map ( |g| & g. params )
2356
2334
. filter ( |p| matches ! ( p. kind, ty:: GenericParamDefKind :: Lifetime ) )
2357
2335
. map ( |p| p. name . as_str ( ) )
2358
2336
. collect :: < Vec < _ > > ( ) ;
2359
- if let Some ( g) = parent_g {
2360
- lts_names. extend (
2361
- g. params
2362
- . iter ( )
2363
- . filter ( |p| matches ! ( p. kind, ty:: GenericParamDefKind :: Lifetime ) )
2364
- . map ( |p| p. name . as_str ( ) ) ,
2365
- ) ;
2366
- }
2367
- possible. find ( |candidate| !lts_names. contains ( & & candidate[ ..] ) )
2368
- } )
2369
- . unwrap_or ( "'lt" . to_string ( ) ) ;
2337
+ possible
2338
+ . find ( |candidate| !lts_names. contains ( & & candidate[ ..] ) )
2339
+ . unwrap_or ( "'lt" . to_string ( ) )
2340
+ } ;
2341
+
2370
2342
let add_lt_sugg = generics
2371
- . as_ref ( )
2372
- . and_then ( | ( _ , g , _ ) | g . params . first ( ) )
2343
+ . params
2344
+ . first ( )
2373
2345
. and_then ( |param| param. def_id . as_local ( ) )
2374
2346
. map ( |def_id| ( self . tcx . def_span ( def_id) . shrink_to_lo ( ) , format ! ( "{}, " , new_lt) ) ) ;
2375
2347
@@ -2571,7 +2543,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
2571
2543
) ;
2572
2544
if let Some ( infer:: RelateParamBound ( _, t, _) ) = origin {
2573
2545
let return_impl_trait =
2574
- owner . and_then ( |owner| self . tcx . return_type_impl_trait ( owner ) ) . is_some ( ) ;
2546
+ self . tcx . return_type_impl_trait ( generic_param_scope ) . is_some ( ) ;
2575
2547
let t = self . resolve_vars_if_possible ( t) ;
2576
2548
match t. kind ( ) {
2577
2549
// We've got:
0 commit comments