summaryrefslogtreecommitdiff
path: root/compiler/rustc_mir_transform
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2023-04-28 16:57:40 +0000
committerCamille GILLOT <gillot.camille@gmail.com>2023-05-04 21:51:44 +0000
commit1ffe9059c31d17ea1b22099b0f64de0232ebadd5 (patch)
tree8d83e17c2fb766e01967e6e09f849405edb7b934 /compiler/rustc_mir_transform
parente2caebc4a61a39e6e618129f312bc4be174fb7be (diff)
downloadrust-1ffe9059c31d17ea1b22099b0f64de0232ebadd5.tar.gz
Reject borrows of projections in ConstProp.
Diffstat (limited to 'compiler/rustc_mir_transform')
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs20
1 files changed, 15 insertions, 5 deletions
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index b3a3a25ebe8..7f995c69a48 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -714,13 +714,22 @@ impl CanConstProp {
}
}
-impl Visitor<'_> for CanConstProp {
+impl<'tcx> Visitor<'tcx> for CanConstProp {
+ fn visit_place(&mut self, place: &Place<'tcx>, mut context: PlaceContext, loc: Location) {
+ use rustc_middle::mir::visit::PlaceContext::*;
+
+ // Dereferencing just read the addess of `place.local`.
+ if place.projection.first() == Some(&PlaceElem::Deref) {
+ context = NonMutatingUse(NonMutatingUseContext::Copy);
+ }
+
+ self.visit_local(place.local, context, loc);
+ self.visit_projection(place.as_ref(), context, loc);
+ }
+
fn visit_local(&mut self, local: Local, context: PlaceContext, _: Location) {
use rustc_middle::mir::visit::PlaceContext::*;
match context {
- // Projections are fine, because `&mut foo.x` will be caught by
- // `MutatingUseContext::Borrow` elsewhere.
- MutatingUse(MutatingUseContext::Projection)
// These are just stores, where the storing is not propagatable, but there may be later
// mutations of the same local via `Store`
| MutatingUse(MutatingUseContext::Call)
@@ -751,7 +760,6 @@ impl Visitor<'_> for CanConstProp {
NonMutatingUse(NonMutatingUseContext::Copy)
| NonMutatingUse(NonMutatingUseContext::Move)
| NonMutatingUse(NonMutatingUseContext::Inspect)
- | NonMutatingUse(NonMutatingUseContext::Projection)
| NonMutatingUse(NonMutatingUseContext::PlaceMention)
| NonUse(_) => {}
@@ -771,6 +779,8 @@ impl Visitor<'_> for CanConstProp {
trace!("local {:?} can't be propagated because it's used: {:?}", local, context);
self.can_const_prop[local] = ConstPropMode::NoPropagation;
}
+ MutatingUse(MutatingUseContext::Projection)
+ | NonMutatingUse(NonMutatingUseContext::Projection) => bug!("visit_place should not pass {context:?} for {local:?}"),
}
}
}