@@ -63,7 +63,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, Mul
6363use rustc_hir as hir;
6464use rustc_hir:: def_id:: { DefId , LocalDefId } ;
6565use rustc_hir:: lang_items:: LangItem ;
66- use rustc_hir:: { Item , ItemKind , Node } ;
66+ use rustc_hir:: Node ;
6767use rustc_middle:: dep_graph:: DepContext ;
6868use rustc_middle:: ty:: print:: with_no_trimmed_paths;
6969use rustc_middle:: ty:: {
@@ -348,7 +348,11 @@ pub fn same_type_modulo_infer<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
348348}
349349
350350impl < ' 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+ ) {
352356 debug ! ( "report_region_errors(): {} errors to start" , errors. len( ) ) ;
353357
354358 // try to pre-process the errors, which will group some of them
@@ -379,6 +383,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
379383
380384 RegionResolutionError :: GenericBoundFailure ( origin, param_ty, sub) => {
381385 self . report_generic_bound_failure (
386+ generic_param_scope,
382387 origin. span ( ) ,
383388 Some ( origin) ,
384389 param_ty,
@@ -2269,56 +2274,30 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
22692274
22702275 pub fn report_generic_bound_failure (
22712276 & self ,
2277+ generic_param_scope : LocalDefId ,
22722278 span : Span ,
22732279 origin : Option < SubregionOrigin < ' tcx > > ,
22742280 bound_kind : GenericKind < ' tcx > ,
22752281 sub : Region < ' tcx > ,
22762282 ) {
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 ( ) ;
22802285 }
22812286
22822287 pub fn construct_generic_bound_failure (
22832288 & self ,
2289+ generic_param_scope : LocalDefId ,
22842290 span : Span ,
22852291 origin : Option < SubregionOrigin < ' tcx > > ,
22862292 bound_kind : GenericKind < ' tcx > ,
22872293 sub : Region < ' tcx > ,
2288- owner : Option < LocalDefId > ,
22892294 ) -> DiagnosticBuilder < ' a , ErrorGuaranteed > {
2290- let hir = self . tcx . hir ( ) ;
22912295 // Attempt to obtain the span of the parameter so we can
22922296 // 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) ;
23192298 // 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) => {
23222301 // Account for the case where `param` corresponds to `Self`,
23232302 // which doesn't have the expected type argument.
23242303 if !( generics. has_self && param. index == 0 ) {
@@ -2346,30 +2325,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
23462325 }
23472326 _ => None ,
23482327 } ;
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 )
23562334 . filter ( |p| matches ! ( p. kind, ty:: GenericParamDefKind :: Lifetime ) )
23572335 . map ( |p| p. name . as_str ( ) )
23582336 . 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+
23702342 let add_lt_sugg = generics
2371- . as_ref ( )
2372- . and_then ( | ( _ , g , _ ) | g . params . first ( ) )
2343+ . params
2344+ . first ( )
23732345 . and_then ( |param| param. def_id . as_local ( ) )
23742346 . map ( |def_id| ( self . tcx . def_span ( def_id) . shrink_to_lo ( ) , format ! ( "{}, " , new_lt) ) ) ;
23752347
@@ -2571,7 +2543,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
25712543 ) ;
25722544 if let Some ( infer:: RelateParamBound ( _, t, _) ) = origin {
25732545 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 ( ) ;
25752547 let t = self . resolve_vars_if_possible ( t) ;
25762548 match t. kind ( ) {
25772549 // We've got:
0 commit comments