@@ -4,10 +4,13 @@ use rustc_index::interval::IntervalSet;
4
4
use rustc_infer:: infer:: canonical:: QueryRegionConstraints ;
5
5
use rustc_middle:: mir:: { BasicBlock , Body , ConstraintCategory , Local , Location } ;
6
6
use rustc_middle:: traits:: query:: DropckOutlivesResult ;
7
- use rustc_middle:: ty:: { Ty , TyCtxt , TypeVisitable , TypeVisitableExt } ;
7
+ use rustc_middle:: ty:: {
8
+ self , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor ,
9
+ } ;
8
10
use rustc_span:: DUMMY_SP ;
9
11
use rustc_trait_selection:: traits:: query:: type_op:: outlives:: DropckOutlives ;
10
12
use rustc_trait_selection:: traits:: query:: type_op:: { TypeOp , TypeOpOutput } ;
13
+ use std:: ops:: ControlFlow ;
11
14
use std:: rc:: Rc ;
12
15
13
16
use rustc_mir_dataflow:: impls:: MaybeInitializedPlaces ;
@@ -555,16 +558,68 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
555
558
values:: location_set_str( elements, live_at. iter( ) ) ,
556
559
) ;
557
560
558
- let tcx = typeck. tcx ( ) ;
559
- tcx. for_each_free_region ( & value, |live_region| {
560
- let live_region_vid =
561
- typeck. borrowck_context . universal_regions . to_region_vid ( live_region) ;
562
- typeck
563
- . borrowck_context
564
- . constraints
565
- . liveness_constraints
566
- . add_elements ( live_region_vid, live_at) ;
567
- } ) ;
561
+ struct MakeAllRegionsLive < ' a , ' b , ' tcx > {
562
+ typeck : & ' b mut TypeChecker < ' a , ' tcx > ,
563
+ live_at : & ' b IntervalSet < PointIndex > ,
564
+ }
565
+ impl < ' tcx > MakeAllRegionsLive < ' _ , ' _ , ' tcx > {
566
+ fn make_alias_live ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < !> {
567
+ let ty:: Alias ( _kind, alias_ty) = t. kind ( ) else {
568
+ bug ! ( ) ;
569
+ } ;
570
+ let tcx = self . typeck . infcx . tcx ;
571
+ let mut outlives_bounds = tcx
572
+ . item_bounds ( alias_ty. def_id )
573
+ . iter_instantiated ( tcx, alias_ty. args )
574
+ . filter_map ( |clause| {
575
+ if let Some ( outlives) = clause. as_type_outlives_clause ( )
576
+ && outlives. skip_binder ( ) . 0 == t
577
+ {
578
+ Some ( outlives. skip_binder ( ) . 1 )
579
+ } else {
580
+ None
581
+ }
582
+ } ) ;
583
+ if let Some ( r) = outlives_bounds. next ( )
584
+ && !r. is_late_bound ( )
585
+ && outlives_bounds. all ( |other_r| {
586
+ other_r == r
587
+ } )
588
+ {
589
+ r. visit_with ( self )
590
+ } else {
591
+ t. super_visit_with ( self )
592
+ }
593
+ }
594
+ }
595
+ impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for MakeAllRegionsLive < ' _ , ' _ , ' tcx > {
596
+ type BreakTy = !;
597
+
598
+ fn visit_region ( & mut self , r : ty:: Region < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
599
+ if r. is_late_bound ( ) {
600
+ return ControlFlow :: Continue ( ( ) ) ;
601
+ }
602
+ let live_region_vid =
603
+ self . typeck . borrowck_context . universal_regions . to_region_vid ( r) ;
604
+ self . typeck
605
+ . borrowck_context
606
+ . constraints
607
+ . liveness_constraints
608
+ . add_elements ( live_region_vid, self . live_at ) ;
609
+ ControlFlow :: Continue ( ( ) )
610
+ }
611
+
612
+ fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
613
+ if !t. has_free_regions ( ) {
614
+ ControlFlow :: Continue ( ( ) )
615
+ } else if let ty:: Alias ( ..) = t. kind ( ) {
616
+ self . make_alias_live ( t)
617
+ } else {
618
+ t. super_visit_with ( self )
619
+ }
620
+ }
621
+ }
622
+ value. visit_with ( & mut MakeAllRegionsLive { typeck, live_at } ) ;
568
623
}
569
624
570
625
fn compute_drop_data (
0 commit comments