@@ -354,6 +354,12 @@ impl<'tcx> std::fmt::Debug for ScalarTy<'tcx> {
354
354
}
355
355
}
356
356
357
+ impl < ' tcx > ScalarTy < ' tcx > {
358
+ pub fn can_const_prop ( & self ) -> bool {
359
+ self . 0 . try_to_int ( ) . is_ok ( )
360
+ }
361
+ }
362
+
357
363
impl < ' a , ' m , ' tcx > ConstAnalysis < ' a , ' m , ' tcx > {
358
364
pub fn new ( tcx : TyCtxt < ' tcx > , body : & ' a Body < ' tcx > , map : & ' m Map ) -> Self {
359
365
let param_env = tcx. param_env_reveal_all_normalized ( body. source . def_id ( ) ) ;
@@ -527,14 +533,10 @@ impl<'mir, 'tcx>
527
533
// Don't overwrite the assignment if it already uses a constant (to keep the span).
528
534
}
529
535
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) ;
538
540
}
539
541
}
540
542
_ => ( ) ,
@@ -560,6 +562,7 @@ impl<'tcx> MutVisitor<'tcx> for CollectAndPatch<'tcx> {
560
562
561
563
fn visit_statement ( & mut self , statement : & mut Statement < ' tcx > , location : Location ) {
562
564
if let Some ( value) = self . assignments . get ( & location) {
565
+ assert ! ( value. can_const_prop( ) , "trying to propagate a pointer" ) ;
563
566
match & mut statement. kind {
564
567
StatementKind :: Assign ( box ( _, rvalue) ) => {
565
568
if !matches ! ( rvalue, Rvalue :: Use ( Operand :: Constant ( _) ) ) {
@@ -578,6 +581,7 @@ impl<'tcx> MutVisitor<'tcx> for CollectAndPatch<'tcx> {
578
581
match operand {
579
582
Operand :: Copy ( place) | Operand :: Move ( place) => {
580
583
if let Some ( value) = self . before_effect . get ( & ( location, * place) ) {
584
+ assert ! ( value. can_const_prop( ) , "trying to propagate a pointer" ) ;
581
585
* operand = self . make_operand ( value. clone ( ) ) ;
582
586
} else if !place. projection . is_empty ( ) {
583
587
self . super_operand ( operand, location)
@@ -613,7 +617,9 @@ pub(crate) struct OperandCollector<'tcx, 'map, 'a> {
613
617
impl < ' tcx , ' map , ' a > Visitor < ' tcx > for OperandCollector < ' tcx , ' map , ' a > {
614
618
fn visit_operand ( & mut self , operand : & Operand < ' tcx > , location : Location ) {
615
619
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
+ {
617
623
self . visitor . before_effect . insert ( ( location, place) , value) ;
618
624
} else if !place. projection . is_empty ( ) {
619
625
// Try to propagate into `Index` projections.
@@ -625,6 +631,7 @@ impl<'tcx, 'map, 'a> Visitor<'tcx> for OperandCollector<'tcx, 'map, 'a> {
625
631
fn visit_local ( & mut self , local : Local , ctxt : PlaceContext , location : Location ) {
626
632
if let PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Copy | NonMutatingUseContext :: Move ) = ctxt
627
633
&& let FlatSet :: Elem ( value) = self . state . get ( local. into ( ) , self . map )
634
+ && value. can_const_prop ( )
628
635
{
629
636
self . visitor . before_effect . insert ( ( location, local. into ( ) ) , value) ;
630
637
}
0 commit comments