@@ -3,17 +3,13 @@ use rustc_data_structures::graph::WithSuccessors;
33use rustc_index:: bit_set:: { HybridBitSet , SparseBitMatrix } ;
44use rustc_index:: interval:: IntervalSet ;
55use 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;
87use rustc_middle:: mir:: { BasicBlock , Body , ConstraintCategory , Local , Location } ;
98use 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 } ;
1310use rustc_span:: DUMMY_SP ;
1411use rustc_trait_selection:: traits:: query:: type_op:: outlives:: DropckOutlives ;
1512use rustc_trait_selection:: traits:: query:: type_op:: { TypeOp , TypeOpOutput } ;
16- use std:: ops:: ControlFlow ;
1713use std:: rc:: Rc ;
1814
1915use rustc_mir_dataflow:: impls:: MaybeInitializedPlaces ;
@@ -612,107 +608,25 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
612608 let num_loans = typeck. borrowck_context . borrow_set . len ( ) ;
613609 let value_loans = & mut HybridBitSet :: new_empty ( num_loans) ;
614610
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) ;
690616
691- self . typeck
617+ typeck
692618 . borrowck_context
693619 . constraints
694620 . liveness_constraints
695- . add_elements ( live_region_vid, self . live_at ) ;
621+ . add_elements ( live_region_vid, live_at) ;
696622
697623 // There can only be inflowing loans for this region when we are using
698624 // `-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) ;
701627 }
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+ } ) ;
716630
717631 // Record the loans reaching the value.
718632 if !value_loans. is_empty ( ) {
0 commit comments