@@ -437,10 +437,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
437
437
source_info. scope . lint_root ( self . source_scopes )
438
438
}
439
439
440
- fn use_ecx < F , T > ( & mut self , f : F ) -> Option < T >
440
+ fn use_ecx < F , T > ( & mut self , source_info : SourceInfo , f : F ) -> Option < T >
441
441
where
442
442
F : FnOnce ( & mut Self ) -> InterpResult < ' tcx , T > ,
443
443
{
444
+ // Overwrite the PC -- whatever the interpreter does to it does not make any sense anyway.
445
+ self . ecx . frame_mut ( ) . loc = Err ( source_info. span ) ;
444
446
match f ( self ) {
445
447
Ok ( val) => Some ( val) ,
446
448
Err ( error) => {
@@ -501,17 +503,17 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
501
503
}
502
504
503
505
/// Returns the value, if any, of evaluating `place`.
504
- fn eval_place ( & mut self , place : Place < ' tcx > ) -> Option < OpTy < ' tcx > > {
506
+ fn eval_place ( & mut self , place : Place < ' tcx > , source_info : SourceInfo ) -> Option < OpTy < ' tcx > > {
505
507
trace ! ( "eval_place(place={:?})" , place) ;
506
- self . use_ecx ( |this| this. ecx . eval_place_to_op ( place, None ) )
508
+ self . use_ecx ( source_info , |this| this. ecx . eval_place_to_op ( place, None ) )
507
509
}
508
510
509
511
/// Returns the value, if any, of evaluating `op`. Calls upon `eval_constant`
510
512
/// or `eval_place`, depending on the variant of `Operand` used.
511
513
fn eval_operand ( & mut self , op : & Operand < ' tcx > , source_info : SourceInfo ) -> Option < OpTy < ' tcx > > {
512
514
match * op {
513
515
Operand :: Constant ( ref c) => self . eval_constant ( c, source_info) ,
514
- Operand :: Move ( place) | Operand :: Copy ( place) => self . eval_place ( place) ,
516
+ Operand :: Move ( place) | Operand :: Copy ( place) => self . eval_place ( place, source_info ) ,
515
517
}
516
518
}
517
519
@@ -537,7 +539,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
537
539
arg : & Operand < ' tcx > ,
538
540
source_info : SourceInfo ,
539
541
) -> Option < ( ) > {
540
- if let ( val, true ) = self . use_ecx ( |this| {
542
+ if let ( val, true ) = self . use_ecx ( source_info , |this| {
541
543
let val = this. ecx . read_immediate ( & this. ecx . eval_operand ( arg, None ) ?) ?;
542
544
let ( _res, overflow, _ty) = this. ecx . overflowing_unary_op ( op, & val) ?;
543
545
Ok ( ( val, overflow) )
@@ -564,8 +566,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
564
566
right : & Operand < ' tcx > ,
565
567
source_info : SourceInfo ,
566
568
) -> Option < ( ) > {
567
- let r = self . use_ecx ( |this| this. ecx . read_immediate ( & this. ecx . eval_operand ( right, None ) ?) ) ;
568
- let l = self . use_ecx ( |this| this. ecx . read_immediate ( & this. ecx . eval_operand ( left, None ) ?) ) ;
569
+ let r = self . use_ecx ( source_info, |this| {
570
+ this. ecx . read_immediate ( & this. ecx . eval_operand ( right, None ) ?)
571
+ } ) ;
572
+ let l = self . use_ecx ( source_info, |this| {
573
+ this. ecx . read_immediate ( & this. ecx . eval_operand ( left, None ) ?)
574
+ } ) ;
569
575
// Check for exceeding shifts *even if* we cannot evaluate the LHS.
570
576
if op == BinOp :: Shr || op == BinOp :: Shl {
571
577
let r = r?;
@@ -602,7 +608,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
602
608
603
609
if let ( Some ( l) , Some ( r) ) = ( & l, & r) {
604
610
// The remaining operators are handled through `overflowing_binary_op`.
605
- if self . use_ecx ( |this| {
611
+ if self . use_ecx ( source_info , |this| {
606
612
let ( _res, overflow, _ty) = this. ecx . overflowing_binary_op ( op, l, r) ?;
607
613
Ok ( overflow)
608
614
} ) ? {
@@ -690,7 +696,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
690
696
return None ;
691
697
}
692
698
693
- self . use_ecx ( |this| this. ecx . eval_rvalue_into_place ( rvalue, place) )
699
+ self . use_ecx ( source_info , |this| this. ecx . eval_rvalue_into_place ( rvalue, place) )
694
700
}
695
701
}
696
702
@@ -890,7 +896,10 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
890
896
StatementKind :: SetDiscriminant { ref place, .. } => {
891
897
match self . ecx . machine . can_const_prop [ place. local ] {
892
898
ConstPropMode :: FullConstProp | ConstPropMode :: OnlyInsideOwnBlock => {
893
- if self . use_ecx ( |this| this. ecx . statement ( statement) ) . is_some ( ) {
899
+ if self
900
+ . use_ecx ( source_info, |this| this. ecx . statement ( statement) )
901
+ . is_some ( )
902
+ {
894
903
trace ! ( "propped discriminant into {:?}" , place) ;
895
904
} else {
896
905
Self :: remove_const ( & mut self . ecx , place. local ) ;
0 commit comments