diff options
| author | Ralf Jung <post@ralfj.de> | 2022-06-04 15:29:51 -0400 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2022-06-04 15:59:24 -0400 |
| commit | 9ab4f876a1c5321fe451bf691eb28d87dbf5ff84 (patch) | |
| tree | c93f6c07ee3c2e8ec13d2c5ca6704cf423ce99e8 /compiler | |
| parent | 7892e1cedb0b1fe8d924516425481654b89ba834 (diff) | |
| download | rust-9ab4f876a1c5321fe451bf691eb28d87dbf5ff84.tar.gz rust-9ab4f876a1c5321fe451bf691eb28d87dbf5ff84.zip | |
const_prop_lint: ensure we have up-to-date cur_span()
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/eval_context.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/const_prop_lint.rs | 29 |
2 files changed, 23 insertions, 11 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 0c954ac6e5f..a82ddfb5ac5 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -126,7 +126,9 @@ pub struct Frame<'mir, 'tcx, Tag: Provenance = AllocId, Extra = ()> { /// this frame (can happen e.g. during frame initialization, and during unwinding on /// frames without cleanup code). /// We basically abuse `Result` as `Either`. - pub(super) loc: Result<mir::Location, Span>, + /// + /// Needs to be public because ConstProp does unspeakable things to it. + pub loc: Result<mir::Location, Span>, } /// What we store about a frame in an interpreter backtrace. @@ -320,6 +322,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> LayoutOfHelpers<'tcx> for InterpC #[inline] fn layout_tcx_at_span(&self) -> Span { + // Using the cheap root span for performance. self.tcx.span } diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 5fd9db3989d..84fdb136bd4 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -437,10 +437,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { source_info.scope.lint_root(self.source_scopes) } - fn use_ecx<F, T>(&mut self, f: F) -> Option<T> + fn use_ecx<F, T>(&mut self, source_info: SourceInfo, f: F) -> Option<T> where F: FnOnce(&mut Self) -> InterpResult<'tcx, T>, { + // Overwrite the PC -- whatever the interpreter does to it does not make any sense anyway. + self.ecx.frame_mut().loc = Err(source_info.span); match f(self) { Ok(val) => Some(val), Err(error) => { @@ -501,9 +503,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } /// Returns the value, if any, of evaluating `place`. - fn eval_place(&mut self, place: Place<'tcx>) -> Option<OpTy<'tcx>> { + fn eval_place(&mut self, place: Place<'tcx>, source_info: SourceInfo) -> Option<OpTy<'tcx>> { trace!("eval_place(place={:?})", place); - self.use_ecx(|this| this.ecx.eval_place_to_op(place, None)) + self.use_ecx(source_info, |this| this.ecx.eval_place_to_op(place, None)) } /// Returns the value, if any, of evaluating `op`. Calls upon `eval_constant` @@ -511,7 +513,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option<OpTy<'tcx>> { match *op { Operand::Constant(ref c) => self.eval_constant(c, source_info), - Operand::Move(place) | Operand::Copy(place) => self.eval_place(place), + Operand::Move(place) | Operand::Copy(place) => self.eval_place(place, source_info), } } @@ -537,7 +539,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { arg: &Operand<'tcx>, source_info: SourceInfo, ) -> Option<()> { - if let (val, true) = self.use_ecx(|this| { + if let (val, true) = self.use_ecx(source_info, |this| { let val = this.ecx.read_immediate(&this.ecx.eval_operand(arg, None)?)?; let (_res, overflow, _ty) = this.ecx.overflowing_unary_op(op, &val)?; Ok((val, overflow)) @@ -564,8 +566,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { right: &Operand<'tcx>, source_info: SourceInfo, ) -> Option<()> { - let r = self.use_ecx(|this| this.ecx.read_immediate(&this.ecx.eval_operand(right, None)?)); - let l = self.use_ecx(|this| this.ecx.read_immediate(&this.ecx.eval_operand(left, None)?)); + let r = self.use_ecx(source_info, |this| { + this.ecx.read_immediate(&this.ecx.eval_operand(right, None)?) + }); + let l = self.use_ecx(source_info, |this| { + this.ecx.read_immediate(&this.ecx.eval_operand(left, None)?) + }); // Check for exceeding shifts *even if* we cannot evaluate the LHS. if op == BinOp::Shr || op == BinOp::Shl { let r = r?; @@ -602,7 +608,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { if let (Some(l), Some(r)) = (&l, &r) { // The remaining operators are handled through `overflowing_binary_op`. - if self.use_ecx(|this| { + if self.use_ecx(source_info, |this| { let (_res, overflow, _ty) = this.ecx.overflowing_binary_op(op, l, r)?; Ok(overflow) })? { @@ -690,7 +696,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } - self.use_ecx(|this| this.ecx.eval_rvalue_into_place(rvalue, place)) + self.use_ecx(source_info, |this| this.ecx.eval_rvalue_into_place(rvalue, place)) } } @@ -890,7 +896,10 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { StatementKind::SetDiscriminant { ref place, .. } => { match self.ecx.machine.can_const_prop[place.local] { ConstPropMode::FullConstProp | ConstPropMode::OnlyInsideOwnBlock => { - if self.use_ecx(|this| this.ecx.statement(statement)).is_some() { + if self + .use_ecx(source_info, |this| this.ecx.statement(statement)) + .is_some() + { trace!("propped discriminant into {:?}", place); } else { Self::remove_const(&mut self.ecx, place.local); |
