@@ -14,8 +14,9 @@ use rustc_hir::lang_items::LangItem;
14
14
use rustc_hir:: ItemKind ;
15
15
use rustc_infer:: infer:: outlives:: env:: OutlivesEnvironment ;
16
16
use 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 } ;
19
20
use rustc_middle:: hir:: map as hir_map;
20
21
use rustc_middle:: ty:: subst:: { GenericArgKind , InternalSubsts , Subst } ;
21
22
use rustc_middle:: ty:: trait_def:: TraitSpecializationKind ;
@@ -332,6 +333,12 @@ fn check_gat_where_clauses(
332
333
// outlives relationship (`Self: 'a`), then we want to ensure that is
333
334
// reflected in a where clause on the GAT itself.
334
335
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
+ }
335
342
for ( ty, ty_idx) in & types {
336
343
// In our example, requires that Self: 'a
337
344
if ty_known_to_outlive ( tcx, id, param_env, & wf_tys, * ty, * region) {
@@ -371,10 +378,19 @@ fn check_gat_where_clauses(
371
378
// outlives relationship, then we want to ensure that is
372
379
// reflected in a where clause on the GAT itself.
373
380
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
+ }
374
387
for ( region_b, region_b_idx) in & regions {
375
388
if region_a == region_b {
376
389
continue ;
377
390
}
391
+ if let ty:: ReStatic = region_b {
392
+ continue ;
393
+ }
378
394
379
395
if region_known_to_outlive ( tcx, id, param_env, & wf_tys, * region_a, * region_b) {
380
396
debug ! ( ?region_a_idx, ?region_b_idx) ;
@@ -502,8 +518,6 @@ fn check_gat_where_clauses(
502
518
}
503
519
}
504
520
505
- // FIXME(jackh726): refactor some of the shared logic between the two functions below
506
-
507
521
/// Given a known `param_env` and a set of well formed types, can we prove that
508
522
/// `ty` outlives `region`.
509
523
fn ty_known_to_outlive < ' tcx > (
@@ -514,54 +528,49 @@ fn ty_known_to_outlive<'tcx>(
514
528
ty : Ty < ' tcx > ,
515
529
region : ty:: Region < ' tcx > ,
516
530
) -> 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 ) ;
535
533
let outlives = & mut TypeOutlives :: new (
536
- & infcx,
534
+ infcx,
537
535
tcx,
538
- & region_bound_pairs,
536
+ region_bound_pairs,
539
537
Some ( infcx. tcx . lifetimes . re_root_empty ) ,
540
538
param_env,
541
539
) ;
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) ;
555
541
} )
556
542
}
557
543
544
+ /// Given a known `param_env` and a set of well formed types, can we prove that
545
+ /// `region_a` outlives `region_b`
558
546
fn region_known_to_outlive < ' tcx > (
559
547
tcx : TyCtxt < ' tcx > ,
560
548
id : hir:: HirId ,
561
549
param_env : ty:: ParamEnv < ' tcx > ,
562
550
wf_tys : & FxHashSet < Ty < ' tcx > > ,
563
551
region_a : ty:: Region < ' tcx > ,
564
552
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
+ ) ,
565
574
) -> bool {
566
575
// Unfortunately, we have to use a new `InferCtxt` each call, because
567
576
// region constraints get added and solved there and we need to test each
@@ -570,16 +579,9 @@ fn region_known_to_outlive<'tcx>(
570
579
let mut outlives_environment = OutlivesEnvironment :: new ( param_env) ;
571
580
outlives_environment. add_implied_bounds ( & infcx, wf_tys. clone ( ) , id, DUMMY_SP ) ;
572
581
outlives_environment. save_implied_bounds ( id) ;
582
+ let region_bound_pairs = outlives_environment. region_bound_pairs_map ( ) . get ( & id) . unwrap ( ) ;
573
583
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) ;
583
585
584
586
let errors = infcx. resolve_regions (
585
587
id. expect_owner ( ) . to_def_id ( ) ,
0 commit comments