@@ -14,8 +14,9 @@ use rustc_hir::lang_items::LangItem;
1414use  rustc_hir:: ItemKind ; 
1515use  rustc_infer:: infer:: outlives:: env:: OutlivesEnvironment ; 
1616use  rustc_infer:: infer:: outlives:: obligations:: TypeOutlives ; 
17- use  rustc_infer:: infer:: TyCtxtInferExt ; 
18- use  rustc_infer:: infer:: { self ,  RegionckMode ,  SubregionOrigin } ; 
17+ use  rustc_infer:: infer:: region_constraints:: GenericKind ; 
18+ use  rustc_infer:: infer:: { self ,  RegionckMode } ; 
19+ use  rustc_infer:: infer:: { InferCtxt ,  TyCtxtInferExt } ; 
1920use  rustc_middle:: hir:: map as  hir_map; 
2021use  rustc_middle:: ty:: subst:: { GenericArgKind ,  InternalSubsts ,  Subst } ; 
2122use  rustc_middle:: ty:: trait_def:: TraitSpecializationKind ; 
@@ -332,6 +333,12 @@ fn check_gat_where_clauses(
332333        // outlives relationship (`Self: 'a`), then we want to ensure that is 
333334        // reflected in a where clause on the GAT itself. 
334335        for  ( region,  region_idx)  in  & regions { 
336+             // Ignore `'static` lifetimes for the purpose of this lint: it's 
337+             // because we know it outlives everything and so doesn't give meaninful 
338+             // clues 
339+             if  let  ty:: ReStatic  = region { 
340+                 continue ; 
341+             } 
335342            for  ( ty,  ty_idx)  in  & types { 
336343                // In our example, requires that Self: 'a 
337344                if  ty_known_to_outlive ( tcx,  id,  param_env,  & wf_tys,  * ty,  * region)  { 
@@ -371,10 +378,19 @@ fn check_gat_where_clauses(
371378        // outlives relationship, then we want to ensure that is 
372379        // reflected in a where clause on the GAT itself. 
373380        for  ( region_a,  region_a_idx)  in  & regions { 
381+             // Ignore `'static` lifetimes for the purpose of this lint: it's 
382+             // because we know it outlives everything and so doesn't give meaninful 
383+             // clues 
384+             if  let  ty:: ReStatic  = region_a { 
385+                 continue ; 
386+             } 
374387            for  ( region_b,  region_b_idx)  in  & regions { 
375388                if  region_a == region_b { 
376389                    continue ; 
377390                } 
391+                 if  let  ty:: ReStatic  = region_b { 
392+                     continue ; 
393+                 } 
378394
379395                if  region_known_to_outlive ( tcx,  id,  param_env,  & wf_tys,  * region_a,  * region_b)  { 
380396                    debug ! ( ?region_a_idx,  ?region_b_idx) ; 
@@ -502,8 +518,6 @@ fn check_gat_where_clauses(
502518    } 
503519} 
504520
505- // FIXME(jackh726): refactor some of the shared logic between the two functions below 
506- 
507521/// Given a known `param_env` and a set of well formed types, can we prove that 
508522/// `ty` outlives `region`. 
509523fn  ty_known_to_outlive < ' tcx > ( 
@@ -514,54 +528,49 @@ fn ty_known_to_outlive<'tcx>(
514528    ty :  Ty < ' tcx > , 
515529    region :  ty:: Region < ' tcx > , 
516530)  -> bool  { 
517-     // Unfortunately, we have to use a new `InferCtxt` each call, because 
518-     // region constraints get added and solved there and we need to test each 
519-     // call individually. 
520-     tcx. infer_ctxt ( ) . enter ( |infcx| { 
521-         let  mut  outlives_environment = OutlivesEnvironment :: new ( param_env) ; 
522-         outlives_environment. add_implied_bounds ( & infcx,  wf_tys. clone ( ) ,  id,  DUMMY_SP ) ; 
523-         outlives_environment. save_implied_bounds ( id) ; 
524-         let  region_bound_pairs = outlives_environment. region_bound_pairs_map ( ) . get ( & id) . unwrap ( ) ; 
525- 
526-         let  cause = ObligationCause :: new ( DUMMY_SP ,  id,  ObligationCauseCode :: MiscObligation ) ; 
527- 
528-         let  sup_type = ty; 
529-         let  sub_region = region; 
530- 
531-         let  origin = SubregionOrigin :: from_obligation_cause ( & cause,  || { 
532-             infer:: RelateParamBound ( cause. span ,  sup_type,  None ) 
533-         } ) ; 
534- 
531+     resolve_regions_with_wf_tys ( tcx,  id,  param_env,  & wf_tys,  |infcx,  region_bound_pairs| { 
532+         let  origin = infer:: RelateParamBound ( DUMMY_SP ,  ty,  None ) ; 
535533        let  outlives = & mut  TypeOutlives :: new ( 
536-             & infcx, 
534+             infcx, 
537535            tcx, 
538-             & region_bound_pairs, 
536+             region_bound_pairs, 
539537            Some ( infcx. tcx . lifetimes . re_root_empty ) , 
540538            param_env, 
541539        ) ; 
542-         outlives. type_must_outlive ( origin,  sup_type,  sub_region) ; 
543- 
544-         let  errors = infcx. resolve_regions ( 
545-             id. expect_owner ( ) . to_def_id ( ) , 
546-             & outlives_environment, 
547-             RegionckMode :: default ( ) , 
548-         ) ; 
549- 
550-         debug ! ( ?errors,  "errors" ) ; 
551- 
552-         // If we were able to prove that the type outlives the region without 
553-         // an error, it must be because of the implied or explicit bounds... 
554-         errors. is_empty ( ) 
540+         outlives. type_must_outlive ( origin,  ty,  region) ; 
555541    } ) 
556542} 
557543
544+ /// Given a known `param_env` and a set of well formed types, can we prove that 
545+ /// `region_a` outlives `region_b` 
558546fn  region_known_to_outlive < ' tcx > ( 
559547    tcx :  TyCtxt < ' tcx > , 
560548    id :  hir:: HirId , 
561549    param_env :  ty:: ParamEnv < ' tcx > , 
562550    wf_tys :  & FxHashSet < Ty < ' tcx > > , 
563551    region_a :  ty:: Region < ' tcx > , 
564552    region_b :  ty:: Region < ' tcx > , 
553+ )  -> bool  { 
554+     resolve_regions_with_wf_tys ( tcx,  id,  param_env,  & wf_tys,  |mut  infcx,  _| { 
555+         use  rustc_infer:: infer:: outlives:: obligations:: TypeOutlivesDelegate ; 
556+         let  origin = infer:: RelateRegionParamBound ( DUMMY_SP ) ; 
557+         // `region_a: region_b` -> `region_b <= region_a` 
558+         infcx. push_sub_region_constraint ( origin,  region_b,  region_a) ; 
559+     } ) 
560+ } 
561+ 
562+ /// Given a known `param_env` and a set of well formed types, set up an 
563+ /// `InferCtxt`, call the passed function (to e.g. set up region constraints 
564+ /// to be tested), then resolve region and return errors 
565+ fn  resolve_regions_with_wf_tys < ' tcx > ( 
566+     tcx :  TyCtxt < ' tcx > , 
567+     id :  hir:: HirId , 
568+     param_env :  ty:: ParamEnv < ' tcx > , 
569+     wf_tys :  & FxHashSet < Ty < ' tcx > > , 
570+     add_constraints :  impl  for < ' a >  FnOnce ( 
571+         & ' a  InferCtxt < ' a ,  ' tcx > , 
572+         & ' a  Vec < ( & ' tcx  ty:: RegionKind ,  GenericKind < ' tcx > ) > , 
573+     ) , 
565574)  -> bool  { 
566575    // Unfortunately, we have to use a new `InferCtxt` each call, because 
567576    // region constraints get added and solved there and we need to test each 
@@ -570,16 +579,9 @@ fn region_known_to_outlive<'tcx>(
570579        let  mut  outlives_environment = OutlivesEnvironment :: new ( param_env) ; 
571580        outlives_environment. add_implied_bounds ( & infcx,  wf_tys. clone ( ) ,  id,  DUMMY_SP ) ; 
572581        outlives_environment. save_implied_bounds ( id) ; 
582+         let  region_bound_pairs = outlives_environment. region_bound_pairs_map ( ) . get ( & id) . unwrap ( ) ; 
573583
574-         let  cause = ObligationCause :: new ( DUMMY_SP ,  id,  ObligationCauseCode :: MiscObligation ) ; 
575- 
576-         let  origin = SubregionOrigin :: from_obligation_cause ( & cause,  || { 
577-             infer:: RelateRegionParamBound ( cause. span ) 
578-         } ) ; 
579- 
580-         use  rustc_infer:: infer:: outlives:: obligations:: TypeOutlivesDelegate ; 
581-         // `region_a: region_b` -> `region_b <= region_a` 
582-         ( & infcx) . push_sub_region_constraint ( origin,  region_b,  region_a) ; 
584+         add_constraints ( & infcx,  region_bound_pairs) ; 
583585
584586        let  errors = infcx. resolve_regions ( 
585587            id. expect_owner ( ) . to_def_id ( ) , 
0 commit comments