@@ -10,7 +10,7 @@ use rustc_middle::mir::interpret::{AllocId, ConstAllocation, ConstValue, InterpR
1010use rustc_middle:: mir:: visit:: { MutVisitor , NonMutatingUseContext , PlaceContext , Visitor } ;
1111use rustc_middle:: mir:: * ;
1212use rustc_middle:: ty:: layout:: TyAndLayout ;
13- use rustc_middle:: ty:: { self , ScalarInt , Ty , TyCtxt } ;
13+ use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
1414use rustc_mir_dataflow:: value_analysis:: {
1515 Map , PlaceIndex , State , TrackElem , ValueAnalysis , ValueAnalysisWrapper , ValueOrPlace ,
1616} ;
@@ -524,10 +524,10 @@ struct CollectAndPatch<'tcx, 'locals> {
524524 /// For a given MIR location, this stores the values of the operands used by that location. In
525525 /// particular, this is before the effect, such that the operands of `_1 = _1 + _2` are
526526 /// 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 > > ,
528528
529529 /// Stores the assigned values for assignments where the Rvalue is constant.
530- assignments : FxHashMap < Location , ScalarInt > ,
530+ assignments : FxHashMap < Location , ConstantKind < ' tcx > > ,
531531}
532532
533533impl < ' tcx , ' locals > CollectAndPatch < ' tcx , ' locals > {
@@ -540,12 +540,21 @@ impl<'tcx, 'locals> CollectAndPatch<'tcx, 'locals> {
540540 }
541541 }
542542
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 } ) )
549558 }
550559}
551560
@@ -583,9 +592,7 @@ impl<'mir, 'tcx>
583592 // Don't overwrite the assignment if it already uses a constant (to keep the span).
584593 }
585594 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 ) {
589596 self . assignments . insert ( location, value) ;
590597 }
591598 }
@@ -614,8 +621,7 @@ impl<'tcx> MutVisitor<'tcx> for CollectAndPatch<'tcx, '_> {
614621 if let Some ( value) = self . assignments . get ( & location) {
615622 match & mut statement. kind {
616623 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) ) ;
619625 }
620626 _ => bug ! ( "found assignment info for non-assign statement" ) ,
621627 }
@@ -628,8 +634,7 @@ impl<'tcx> MutVisitor<'tcx> for CollectAndPatch<'tcx, '_> {
628634 match operand {
629635 Operand :: Copy ( place) | Operand :: Move ( place) => {
630636 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) ;
633638 } else if !place. projection . is_empty ( ) {
634639 self . super_operand ( operand, location)
635640 }
@@ -643,11 +648,11 @@ impl<'tcx> MutVisitor<'tcx> for CollectAndPatch<'tcx, '_> {
643648 elem : PlaceElem < ' tcx > ,
644649 location : Location ,
645650 ) -> 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 ) ? ;
651656 Some ( PlaceElem :: ConstantIndex { offset, min_length, from_end : false } )
652657 } else {
653658 None
@@ -664,7 +669,7 @@ struct OperandCollector<'tcx, 'map, 'locals, 'a> {
664669impl < ' tcx > Visitor < ' tcx > for OperandCollector < ' tcx , ' _ , ' _ , ' _ > {
665670 fn visit_operand ( & mut self , operand : & Operand < ' tcx > , location : Location ) {
666671 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 ) {
668673 self . visitor . before_effect . insert ( ( location, place) , value) ;
669674 } else if !place. projection . is_empty ( ) {
670675 // Try to propagate into `Index` projections.
@@ -675,7 +680,7 @@ impl<'tcx> Visitor<'tcx> for OperandCollector<'tcx, '_, '_, '_> {
675680
676681 fn visit_local ( & mut self , local : Local , ctxt : PlaceContext , location : Location ) {
677682 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 )
679684 {
680685 self . visitor . before_effect . insert ( ( location, local. into ( ) ) , value) ;
681686 }
0 commit comments