@@ -437,10 +437,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
437437 source_info. scope . lint_root ( self . source_scopes )
438438 }
439439
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 >
441441 where
442442 F : FnOnce ( & mut Self ) -> InterpResult < ' tcx , T > ,
443443 {
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 ) ;
444446 match f ( self ) {
445447 Ok ( val) => Some ( val) ,
446448 Err ( error) => {
@@ -501,17 +503,17 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
501503 }
502504
503505 /// 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 > > {
505507 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 ) )
507509 }
508510
509511 /// Returns the value, if any, of evaluating `op`. Calls upon `eval_constant`
510512 /// or `eval_place`, depending on the variant of `Operand` used.
511513 fn eval_operand ( & mut self , op : & Operand < ' tcx > , source_info : SourceInfo ) -> Option < OpTy < ' tcx > > {
512514 match * op {
513515 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 ) ,
515517 }
516518 }
517519
@@ -537,7 +539,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
537539 arg : & Operand < ' tcx > ,
538540 source_info : SourceInfo ,
539541 ) -> Option < ( ) > {
540- if let ( val, true ) = self . use_ecx ( |this| {
542+ if let ( val, true ) = self . use_ecx ( source_info , |this| {
541543 let val = this. ecx . read_immediate ( & this. ecx . eval_operand ( arg, None ) ?) ?;
542544 let ( _res, overflow, _ty) = this. ecx . overflowing_unary_op ( op, & val) ?;
543545 Ok ( ( val, overflow) )
@@ -564,8 +566,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
564566 right : & Operand < ' tcx > ,
565567 source_info : SourceInfo ,
566568 ) -> 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+ } ) ;
569575 // Check for exceeding shifts *even if* we cannot evaluate the LHS.
570576 if op == BinOp :: Shr || op == BinOp :: Shl {
571577 let r = r?;
@@ -602,7 +608,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
602608
603609 if let ( Some ( l) , Some ( r) ) = ( & l, & r) {
604610 // The remaining operators are handled through `overflowing_binary_op`.
605- if self . use_ecx ( |this| {
611+ if self . use_ecx ( source_info , |this| {
606612 let ( _res, overflow, _ty) = this. ecx . overflowing_binary_op ( op, l, r) ?;
607613 Ok ( overflow)
608614 } ) ? {
@@ -690,7 +696,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
690696 return None ;
691697 }
692698
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) )
694700 }
695701}
696702
@@ -890,7 +896,10 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
890896 StatementKind :: SetDiscriminant { ref place, .. } => {
891897 match self . ecx . machine . can_const_prop [ place. local ] {
892898 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+ {
894903 trace ! ( "propped discriminant into {:?}" , place) ;
895904 } else {
896905 Self :: remove_const ( & mut self . ecx , place. local ) ;
0 commit comments