about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-05-01 17:10:24 +0200
committerGitHub <noreply@github.com>2023-05-01 17:10:24 +0200
commitf835b13812e505830370f5dde863d4ff9cabe2a6 (patch)
tree6684287fa82beb666a153d7a9e78dd5cb69a133a
parent8a9e696f43aee4b184be2e1e01fa1f6048d7aba1 (diff)
parentc678acd3a275c9acd34c2ecfa9b7b06e2ca7874f (diff)
downloadrust-f835b13812e505830370f5dde863d4ff9cabe2a6.tar.gz
rust-f835b13812e505830370f5dde863d4ff9cabe2a6.zip
Rollup merge of #111038 - tmiasko:untainted-promoteds, r=compiler-errors
Leave promoteds untainted by errors when borrowck fails

Previously, when borrowck failed it would taint all promoteds within the MIR body. An attempt to evaluated the promoteds would subsequently fail with spurious "note: erroneous constant used". For example:

```console
...
note: erroneous constant used
 --> tests/ui/borrowck/tainted-promoteds.rs:7:9
  |
7 |     a = &0 * &1 * &2 * &3;
  |         ^^

note: erroneous constant used
 --> tests/ui/borrowck/tainted-promoteds.rs:7:14
  |
7 |     a = &0 * &1 * &2 * &3;
  |              ^^

note: erroneous constant used
 --> tests/ui/borrowck/tainted-promoteds.rs:7:19
  |
7 |     a = &0 * &1 * &2 * &3;
  |                   ^^

note: erroneous constant used
 --> tests/ui/borrowck/tainted-promoteds.rs:7:24
  |
7 |     a = &0 * &1 * &2 * &3;
  |                        ^^
```

Borrowck failure doesn't indicate that there is anything wrong with promoteds. Leave them untainted.

Fixes #110856.
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs5
-rw-r--r--tests/ui/borrowck/tainted-promoteds.rs12
-rw-r--r--tests/ui/borrowck/tainted-promoteds.stderr14
3 files changed, 27 insertions, 4 deletions
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 25d7db0ee60..8d9a22ea30d 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -616,13 +616,10 @@ fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec<Promoted, Body<'_
         return tcx.arena.alloc(IndexVec::new());
     }
 
-    let tainted_by_errors = tcx.mir_borrowck(def).tainted_by_errors;
+    tcx.ensure_with_value().mir_borrowck(def);
     let mut promoted = tcx.mir_promoted(def).1.steal();
 
     for body in &mut promoted {
-        if let Some(error_reported) = tainted_by_errors {
-            body.tainted_by_errors = Some(error_reported);
-        }
         run_analysis_to_runtime_passes(tcx, body);
     }
 
diff --git a/tests/ui/borrowck/tainted-promoteds.rs b/tests/ui/borrowck/tainted-promoteds.rs
new file mode 100644
index 00000000000..2b6f0ddbd6c
--- /dev/null
+++ b/tests/ui/borrowck/tainted-promoteds.rs
@@ -0,0 +1,12 @@
+// Regression test for issue #110856, where a borrowck error for a MIR tainted
+// all promoteds within. This in turn generated a spurious "erroneous constant
+// used" note when trying to evaluate a promoted.
+
+pub fn f() -> u32 {
+    let a = 0;
+    a = &0 * &1 * &2 * &3;
+    //~^ ERROR: cannot assign twice to immutable variable
+    a
+}
+
+fn main() {}
diff --git a/tests/ui/borrowck/tainted-promoteds.stderr b/tests/ui/borrowck/tainted-promoteds.stderr
new file mode 100644
index 00000000000..b276ea9aceb
--- /dev/null
+++ b/tests/ui/borrowck/tainted-promoteds.stderr
@@ -0,0 +1,14 @@
+error[E0384]: cannot assign twice to immutable variable `a`
+  --> $DIR/tainted-promoteds.rs:7:5
+   |
+LL |     let a = 0;
+   |         -
+   |         |
+   |         first assignment to `a`
+   |         help: consider making this binding mutable: `mut a`
+LL |     a = &0 * &1 * &2 * &3;
+   |     ^^^^^^^^^^^^^^^^^^^^^ cannot assign twice to immutable variable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0384`.