@@ -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