@@ -10,7 +10,7 @@ use rustc_middle::mir::interpret::{AllocId, ConstAllocation, ConstValue, InterpR
10
10
use rustc_middle:: mir:: visit:: { MutVisitor , NonMutatingUseContext , PlaceContext , Visitor } ;
11
11
use rustc_middle:: mir:: * ;
12
12
use rustc_middle:: ty:: layout:: TyAndLayout ;
13
- use rustc_middle:: ty:: { self , ScalarInt , Ty , TyCtxt } ;
13
+ use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
14
14
use rustc_mir_dataflow:: value_analysis:: {
15
15
Map , PlaceIndex , State , TrackElem , ValueAnalysis , ValueAnalysisWrapper , ValueOrPlace ,
16
16
} ;
@@ -524,10 +524,10 @@ struct CollectAndPatch<'tcx, 'locals> {
524
524
/// For a given MIR location, this stores the values of the operands used by that location. In
525
525
/// particular, this is before the effect, such that the operands of `_1 = _1 + _2` are
526
526
/// properly captured. (This may become UB soon, but it is currently emitted even by safe code.)
527
- before_effect : FxHashMap < ( Location , Place < ' tcx > ) , ScalarInt > ,
527
+ before_effect : FxHashMap < ( Location , Place < ' tcx > ) , ConstantKind < ' tcx > > ,
528
528
529
529
/// Stores the assigned values for assignments where the Rvalue is constant.
530
- assignments : FxHashMap < Location , ScalarInt > ,
530
+ assignments : FxHashMap < Location , ConstantKind < ' tcx > > ,
531
531
}
532
532
533
533
impl < ' tcx , ' locals > CollectAndPatch < ' tcx , ' locals > {
@@ -540,12 +540,21 @@ impl<'tcx, 'locals> CollectAndPatch<'tcx, 'locals> {
540
540
}
541
541
}
542
542
543
- fn make_operand ( & self , scalar : ScalarInt , ty : Ty < ' tcx > ) -> Operand < ' tcx > {
544
- Operand :: Constant ( Box :: new ( Constant {
545
- span : DUMMY_SP ,
546
- user_ty : None ,
547
- literal : ConstantKind :: Val ( ConstValue :: Scalar ( scalar. into ( ) ) , ty) ,
548
- } ) )
543
+ fn try_make_constant (
544
+ & self ,
545
+ place : Place < ' tcx > ,
546
+ state : & State < FlatSet < Scalar > > ,
547
+ map : & Map ,
548
+ ) -> Option < ConstantKind < ' tcx > > {
549
+ let FlatSet :: Elem ( Scalar :: Int ( value) ) = state. get ( place. as_ref ( ) , & map) else {
550
+ return None ;
551
+ } ;
552
+ let ty = place. ty ( self . local_decls , self . tcx ) . ty ;
553
+ Some ( ConstantKind :: Val ( ConstValue :: Scalar ( value. into ( ) ) , ty) )
554
+ }
555
+
556
+ fn make_operand ( & self , literal : ConstantKind < ' tcx > ) -> Operand < ' tcx > {
557
+ Operand :: Constant ( Box :: new ( Constant { span : DUMMY_SP , user_ty : None , literal } ) )
549
558
}
550
559
}
551
560
@@ -583,9 +592,7 @@ impl<'mir, 'tcx>
583
592
// Don't overwrite the assignment if it already uses a constant (to keep the span).
584
593
}
585
594
StatementKind :: Assign ( box ( place, _) ) => {
586
- if let FlatSet :: Elem ( Scalar :: Int ( value) ) =
587
- state. get ( place. as_ref ( ) , & results. analysis . 0 . map )
588
- {
595
+ if let Some ( value) = self . try_make_constant ( place, state, & results. analysis . 0 . map ) {
589
596
self . assignments . insert ( location, value) ;
590
597
}
591
598
}
@@ -614,8 +621,7 @@ impl<'tcx> MutVisitor<'tcx> for CollectAndPatch<'tcx, '_> {
614
621
if let Some ( value) = self . assignments . get ( & location) {
615
622
match & mut statement. kind {
616
623
StatementKind :: Assign ( box ( _, rvalue) ) => {
617
- let ty = rvalue. ty ( self . local_decls , self . tcx ) ;
618
- * rvalue = Rvalue :: Use ( self . make_operand ( * value, ty) ) ;
624
+ * rvalue = Rvalue :: Use ( self . make_operand ( * value) ) ;
619
625
}
620
626
_ => bug ! ( "found assignment info for non-assign statement" ) ,
621
627
}
@@ -628,8 +634,7 @@ impl<'tcx> MutVisitor<'tcx> for CollectAndPatch<'tcx, '_> {
628
634
match operand {
629
635
Operand :: Copy ( place) | Operand :: Move ( place) => {
630
636
if let Some ( value) = self . before_effect . get ( & ( location, * place) ) {
631
- let ty = place. ty ( self . local_decls , self . tcx ) . ty ;
632
- * operand = self . make_operand ( * value, ty) ;
637
+ * operand = self . make_operand ( * value) ;
633
638
} else if !place. projection . is_empty ( ) {
634
639
self . super_operand ( operand, location)
635
640
}
@@ -643,11 +648,11 @@ impl<'tcx> MutVisitor<'tcx> for CollectAndPatch<'tcx, '_> {
643
648
elem : PlaceElem < ' tcx > ,
644
649
location : Location ,
645
650
) -> Option < PlaceElem < ' tcx > > {
646
- if let PlaceElem :: Index ( local) = elem
647
- && let Some ( value ) = self . before_effect . get ( & ( location, local. into ( ) ) )
648
- && let Ok ( offset) = value . try_to_target_usize ( self . tcx )
649
- && let Some ( min_length ) = offset. checked_add ( 1 )
650
- {
651
+ if let PlaceElem :: Index ( local) = elem {
652
+ let offset = self . before_effect . get ( & ( location, local. into ( ) ) ) ? ;
653
+ let offset = offset . try_to_scalar ( ) ? ;
654
+ let offset = offset. to_target_usize ( & self . tcx ) . ok ( ) ? ;
655
+ let min_length = offset . checked_add ( 1 ) ? ;
651
656
Some ( PlaceElem :: ConstantIndex { offset, min_length, from_end : false } )
652
657
} else {
653
658
None
@@ -664,7 +669,7 @@ struct OperandCollector<'tcx, 'map, 'locals, 'a> {
664
669
impl < ' tcx > Visitor < ' tcx > for OperandCollector < ' tcx , ' _ , ' _ , ' _ > {
665
670
fn visit_operand ( & mut self , operand : & Operand < ' tcx > , location : Location ) {
666
671
if let Some ( place) = operand. place ( ) {
667
- if let FlatSet :: Elem ( Scalar :: Int ( value) ) = self . state . get ( place. as_ref ( ) , self . map ) {
672
+ if let Some ( value) = self . visitor . try_make_constant ( place, self . state , self . map ) {
668
673
self . visitor . before_effect . insert ( ( location, place) , value) ;
669
674
} else if !place. projection . is_empty ( ) {
670
675
// Try to propagate into `Index` projections.
@@ -675,7 +680,7 @@ impl<'tcx> Visitor<'tcx> for OperandCollector<'tcx, '_, '_, '_> {
675
680
676
681
fn visit_local ( & mut self , local : Local , ctxt : PlaceContext , location : Location ) {
677
682
if let PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Copy | NonMutatingUseContext :: Move ) = ctxt
678
- && let FlatSet :: Elem ( Scalar :: Int ( value) ) = self . state . get ( local. into ( ) , self . map )
683
+ && let Some ( value) = self . visitor . try_make_constant ( local. into ( ) , self . state , self . map )
679
684
{
680
685
self . visitor . before_effect . insert ( ( location, local. into ( ) ) , value) ;
681
686
}
0 commit comments