about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-11-29 12:34:50 +0100
committerGitHub <noreply@github.com>2023-11-29 12:34:50 +0100
commit434232f7b22141aa82208b4592d30acc302ebb04 (patch)
treebf1bc935d178c22598dc7cd6f363f1b6c8e974ab /compiler/rustc_mir_transform/src
parent911a5ee7ff04bcb6d65c95f14670c81cfbcbdfac (diff)
parent6e956c0a383444a25cc0e690cbc9fa6f859b07b4 (diff)
downloadrust-434232f7b22141aa82208b4592d30acc302ebb04.tar.gz
rust-434232f7b22141aa82208b4592d30acc302ebb04.zip
Rollup merge of #118426 - aDotInTheVoid:const-wat, r=compiler-errors,cjgillot
ConstProp: Correctly remove const if unknown value assigned to it.

Closes #118328

The problematic sequence of MIR is:

```rust
          _1 = const 0_usize;
          _1 = const _; // This is an associated constant we can't know before monomorphization.
          _0 = _1;
```

1. When `ConstProp::visit_assign` happens on `_1 = const 0_usize;`, it records that `0x0usize` is the value for `_1`.
2. Next `visit_assign` happens on `_1 = const _;`. Because the rvalue `.has_param()`, it can't be const evaled.
3. Finaly, `visit_assign` happens on `_0 = _1;`. Here it would think the value of `_1` was `0x0usize` from step 1.

The solution is to remove consts when checking the RValue fails, as they may have contained values that should now be invalidated, as that local was overwritten.

This should probably be back-ported to beta. Stable is more iffy, as it's gone unidentified since 1.70, so I only think it's worthwhile if there's another reason for a 1.74.1 release anyway.
Diffstat (limited to 'compiler/rustc_mir_transform/src')
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs7
1 files changed, 6 insertions, 1 deletions
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index 9a16003bdc9..b96125de95e 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -439,6 +439,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
 
         // FIXME we need to revisit this for #67176
         if rvalue.has_param() {
+            trace!("skipping, has param");
             return None;
         }
         if !rvalue
@@ -707,7 +708,11 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
     fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
         self.super_assign(place, rvalue, location);
 
-        let Some(()) = self.check_rvalue(rvalue) else { return };
+        let Some(()) = self.check_rvalue(rvalue) else {
+            trace!("rvalue check failed, removing const");
+            Self::remove_const(&mut self.ecx, place.local);
+            return;
+        };
 
         match self.ecx.machine.can_const_prop[place.local] {
             // Do nothing if the place is indirect.