@@ -354,6 +354,12 @@ impl<'tcx> std::fmt::Debug for ScalarTy<'tcx> {
354354 }
355355}
356356
357+ impl < ' tcx > ScalarTy < ' tcx > {
358+ pub fn can_const_prop ( & self ) -> bool {
359+ self . 0 . try_to_int ( ) . is_ok ( )
360+ }
361+ }
362+
357363impl < ' a , ' m , ' tcx > ConstAnalysis < ' a , ' m , ' tcx > {
358364 pub fn new ( tcx : TyCtxt < ' tcx > , body : & ' a Body < ' tcx > , map : & ' m Map ) -> Self {
359365 let param_env = tcx. param_env_reveal_all_normalized ( body. source . def_id ( ) ) ;
@@ -527,14 +533,10 @@ impl<'mir, 'tcx>
527533 // Don't overwrite the assignment if it already uses a constant (to keep the span).
528534 }
529535 StatementKind :: Assign ( box ( place, _) ) => {
530- match state. get ( place. as_ref ( ) , & results. analysis . 0 . map ) {
531- FlatSet :: Top => ( ) ,
532- FlatSet :: Elem ( value) => {
533- self . assignments . insert ( location, value) ;
534- }
535- FlatSet :: Bottom => {
536- // This assignment is either unreachable, or an uninitialized value is assigned.
537- }
536+ if let FlatSet :: Elem ( value) = state. get ( place. as_ref ( ) , results. analysis . 0 . map )
537+ && value. can_const_prop ( )
538+ {
539+ self . assignments . insert ( location, value) ;
538540 }
539541 }
540542 _ => ( ) ,
@@ -560,6 +562,7 @@ impl<'tcx> MutVisitor<'tcx> for CollectAndPatch<'tcx> {
560562
561563 fn visit_statement ( & mut self , statement : & mut Statement < ' tcx > , location : Location ) {
562564 if let Some ( value) = self . assignments . get ( & location) {
565+ assert ! ( value. can_const_prop( ) , "trying to propagate a pointer" ) ;
563566 match & mut statement. kind {
564567 StatementKind :: Assign ( box ( _, rvalue) ) => {
565568 if !matches ! ( rvalue, Rvalue :: Use ( Operand :: Constant ( _) ) ) {
@@ -578,6 +581,7 @@ impl<'tcx> MutVisitor<'tcx> for CollectAndPatch<'tcx> {
578581 match operand {
579582 Operand :: Copy ( place) | Operand :: Move ( place) => {
580583 if let Some ( value) = self . before_effect . get ( & ( location, * place) ) {
584+ assert ! ( value. can_const_prop( ) , "trying to propagate a pointer" ) ;
581585 * operand = self . make_operand ( value. clone ( ) ) ;
582586 } else if !place. projection . is_empty ( ) {
583587 self . super_operand ( operand, location)
@@ -613,7 +617,9 @@ pub(crate) struct OperandCollector<'tcx, 'map, 'a> {
613617impl < ' tcx , ' map , ' a > Visitor < ' tcx > for OperandCollector < ' tcx , ' map , ' a > {
614618 fn visit_operand ( & mut self , operand : & Operand < ' tcx > , location : Location ) {
615619 if let Some ( place) = operand. place ( ) {
616- if let FlatSet :: Elem ( value) = self . state . get ( place. as_ref ( ) , self . map ) {
620+ if let FlatSet :: Elem ( value) = self . state . get ( place. as_ref ( ) , self . map )
621+ && value. can_const_prop ( )
622+ {
617623 self . visitor . before_effect . insert ( ( location, place) , value) ;
618624 } else if !place. projection . is_empty ( ) {
619625 // Try to propagate into `Index` projections.
@@ -625,6 +631,7 @@ impl<'tcx, 'map, 'a> Visitor<'tcx> for OperandCollector<'tcx, 'map, 'a> {
625631 fn visit_local ( & mut self , local : Local , ctxt : PlaceContext , location : Location ) {
626632 if let PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Copy | NonMutatingUseContext :: Move ) = ctxt
627633 && let FlatSet :: Elem ( value) = self . state . get ( local. into ( ) , self . map )
634+ && value. can_const_prop ( )
628635 {
629636 self . visitor . before_effect . insert ( ( location, local. into ( ) ) , value) ;
630637 }
0 commit comments