@@ -3,17 +3,13 @@ use rustc_data_structures::graph::WithSuccessors;
3
3
use rustc_index:: bit_set:: { HybridBitSet , SparseBitMatrix } ;
4
4
use rustc_index:: interval:: IntervalSet ;
5
5
use rustc_infer:: infer:: canonical:: QueryRegionConstraints ;
6
- use rustc_infer:: infer:: outlives:: test_type_match;
7
- use rustc_infer:: infer:: region_constraints:: VerifyIfEq ;
6
+ use rustc_infer:: infer:: outlives:: for_liveness;
8
7
use rustc_middle:: mir:: { BasicBlock , Body , ConstraintCategory , Local , Location } ;
9
8
use rustc_middle:: traits:: query:: DropckOutlivesResult ;
10
- use rustc_middle:: ty:: {
11
- self , RegionVid , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor ,
12
- } ;
9
+ use rustc_middle:: ty:: { RegionVid , Ty , TyCtxt , TypeVisitable , TypeVisitableExt } ;
13
10
use rustc_span:: DUMMY_SP ;
14
11
use rustc_trait_selection:: traits:: query:: type_op:: outlives:: DropckOutlives ;
15
12
use rustc_trait_selection:: traits:: query:: type_op:: { TypeOp , TypeOpOutput } ;
16
- use std:: ops:: ControlFlow ;
17
13
use std:: rc:: Rc ;
18
14
19
15
use rustc_mir_dataflow:: impls:: MaybeInitializedPlaces ;
@@ -612,107 +608,25 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
612
608
let num_loans = typeck. borrowck_context . borrow_set . len ( ) ;
613
609
let value_loans = & mut HybridBitSet :: new_empty ( num_loans) ;
614
610
615
- struct MakeAllRegionsLive < ' a , ' b , ' tcx > {
616
- typeck : & ' b mut TypeChecker < ' a , ' tcx > ,
617
- live_at : & ' b IntervalSet < PointIndex > ,
618
- value_loans : & ' b mut HybridBitSet < BorrowIndex > ,
619
- inflowing_loans : & ' b SparseBitMatrix < RegionVid , BorrowIndex > ,
620
- }
621
- impl < ' tcx > MakeAllRegionsLive < ' _ , ' _ , ' tcx > {
622
- /// We can prove that an alias is live two ways:
623
- /// 1. All the components are live.
624
- /// 2. There is a known outlives bound or where-clause, and that
625
- /// region is live.
626
- /// We search through the item bounds and where clauses for
627
- /// either `'static` or a unique outlives region, and if one is
628
- /// found, we just need to prove that that region is still live.
629
- /// If one is not found, then we continue to walk through the alias.
630
- fn make_alias_live ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < !> {
631
- let ty:: Alias ( _kind, alias_ty) = t. kind ( ) else {
632
- bug ! ( "`make_alias_live` only takes alias types" ) ;
633
- } ;
634
- let tcx = self . typeck . infcx . tcx ;
635
- let param_env = self . typeck . param_env ;
636
- let outlives_bounds: Vec < _ > = tcx
637
- . item_bounds ( alias_ty. def_id )
638
- . iter_instantiated ( tcx, alias_ty. args )
639
- . filter_map ( |clause| {
640
- if let Some ( outlives) = clause. as_type_outlives_clause ( )
641
- && outlives. skip_binder ( ) . 0 == t
642
- {
643
- Some ( outlives. skip_binder ( ) . 1 )
644
- } else {
645
- None
646
- }
647
- } )
648
- . chain ( param_env. caller_bounds ( ) . iter ( ) . filter_map ( |clause| {
649
- let outlives = clause. as_type_outlives_clause ( ) ?;
650
- if let Some ( outlives) = outlives. no_bound_vars ( )
651
- && outlives. 0 == t
652
- {
653
- Some ( outlives. 1 )
654
- } else {
655
- test_type_match:: extract_verify_if_eq (
656
- tcx,
657
- param_env,
658
- & outlives. map_bound ( |ty:: OutlivesPredicate ( ty, bound) | {
659
- VerifyIfEq { ty, bound }
660
- } ) ,
661
- t,
662
- )
663
- }
664
- } ) )
665
- . collect ( ) ;
666
- // If we find `'static`, then we know the alias doesn't capture *any* regions.
667
- // Otherwise, all of the outlives regions should be equal -- if they're not,
668
- // we don't really know how to proceed, so we continue recursing through the
669
- // alias.
670
- if outlives_bounds. contains ( & tcx. lifetimes . re_static ) {
671
- ControlFlow :: Continue ( ( ) )
672
- } else if let Some ( r) = outlives_bounds. first ( )
673
- && outlives_bounds[ 1 ..] . iter ( ) . all ( |other_r| other_r == r)
674
- {
675
- r. visit_with ( self )
676
- } else {
677
- t. super_visit_with ( self )
678
- }
679
- }
680
- }
681
- impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for MakeAllRegionsLive < ' _ , ' _ , ' tcx > {
682
- type BreakTy = !;
683
-
684
- fn visit_region ( & mut self , r : ty:: Region < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
685
- if r. is_late_bound ( ) {
686
- return ControlFlow :: Continue ( ( ) ) ;
687
- }
688
- let live_region_vid =
689
- self . typeck . borrowck_context . universal_regions . to_region_vid ( r) ;
611
+ value. visit_with ( & mut for_liveness:: FreeRegionsVisitor {
612
+ tcx : typeck. tcx ( ) ,
613
+ param_env : typeck. param_env ,
614
+ op : |r| {
615
+ let live_region_vid = typeck. borrowck_context . universal_regions . to_region_vid ( r) ;
690
616
691
- self . typeck
617
+ typeck
692
618
. borrowck_context
693
619
. constraints
694
620
. liveness_constraints
695
- . add_elements ( live_region_vid, self . live_at ) ;
621
+ . add_elements ( live_region_vid, live_at) ;
696
622
697
623
// There can only be inflowing loans for this region when we are using
698
624
// `-Zpolonius=next`.
699
- if let Some ( inflowing) = self . inflowing_loans . row ( live_region_vid) {
700
- self . value_loans . union ( inflowing) ;
625
+ if let Some ( inflowing) = inflowing_loans. row ( live_region_vid) {
626
+ value_loans. union ( inflowing) ;
701
627
}
702
- ControlFlow :: Continue ( ( ) )
703
- }
704
-
705
- fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
706
- if !t. has_free_regions ( ) {
707
- ControlFlow :: Continue ( ( ) )
708
- } else if let ty:: Alias ( ..) = t. kind ( ) {
709
- self . make_alias_live ( t)
710
- } else {
711
- t. super_visit_with ( self )
712
- }
713
- }
714
- }
715
- value. visit_with ( & mut MakeAllRegionsLive { typeck, live_at, value_loans, inflowing_loans } ) ;
628
+ } ,
629
+ } ) ;
716
630
717
631
// Record the loans reaching the value.
718
632
if !value_loans. is_empty ( ) {
0 commit comments