about summary refs log tree commit diff
diff options
context:
space:
mode:
authoroli <github35764891676564198441@oli-obk.de>2021-01-04 19:05:51 +0000
committeroli <github35764891676564198441@oli-obk.de>2021-01-04 22:29:45 +0000
commit65ee418e5c2de7d84353979bbd978ca09390ccba (patch)
tree8ae584e6e2d19afbf775901375f97caffb9eaf6c
parent409195d4e50b2c2ae0fc49602350c8a5bdd6bd28 (diff)
downloadrust-65ee418e5c2de7d84353979bbd978ca09390ccba.tar.gz
rust-65ee418e5c2de7d84353979bbd978ca09390ccba.zip
Do not run const prop on the `mir_for_ctfe` of `const fn`
-rw-r--r--compiler/rustc_mir/src/transform/mod.rs53
-rw-r--r--src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs4
-rw-r--r--src/test/ui/const_prop/ice-assert-fail-div-by-zero.stderr4
-rw-r--r--src/test/ui/consts/const-eval/issue-49296.stderr2
4 files changed, 40 insertions, 23 deletions
diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs
index 717479b9990..11f7e6922cc 100644
--- a/compiler/rustc_mir/src/transform/mod.rs
+++ b/compiler/rustc_mir/src/transform/mod.rs
@@ -357,28 +357,43 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -
         return shim::build_adt_ctor(tcx, def.did.to_def_id());
     }
 
-    assert_ne!(
-        tcx.hir().body_const_context(def.did),
-        None,
-        "mir_for_ctfe should not be used for runtime functions"
-    );
+    let context = tcx
+        .hir()
+        .body_const_context(def.did)
+        .expect("mir_for_ctfe should not be used for runtime functions");
 
     let mut body = tcx.mir_drops_elaborated_and_const_checked(def).borrow().clone();
 
-    #[rustfmt::skip]
-    let optimizations: &[&dyn MirPass<'_>] = &[
-        &const_prop::ConstProp,
-    ];
-
-    #[rustfmt::skip]
-    run_passes(
-        tcx,
-        &mut body,
-        MirPhase::Optimization,
-        &[
-            optimizations,
-        ],
-    );
+    match context {
+        // Do not const prop functions, either they get executed at runtime or exported to metadata,
+        // so we run const prop on them, or they don't, in which case we const evaluate some control
+        // flow paths of the function and any errors in those paths will get emitted as const eval
+        // errors.
+        hir::ConstContext::ConstFn => {}
+        // Static items always get evaluated, so we can just let const eval see if any erroneous
+        // control flow paths get executed.
+        hir::ConstContext::Static(_) => {}
+        // Associated constants get const prop run so we detect common failure situations in the
+        // crate that defined the constant.
+        // Technically we want to not run on regular const items, but oli-obk doesn't know how to
+        // conveniently detect that at this point without looking at the HIR.
+        hir::ConstContext::Const => {
+            #[rustfmt::skip]
+            let optimizations: &[&dyn MirPass<'_>] = &[
+                &const_prop::ConstProp,
+            ];
+
+            #[rustfmt::skip]
+            run_passes(
+                tcx,
+                &mut body,
+                MirPhase::Optimization,
+                &[
+                    optimizations,
+                ],
+            );
+        }
+    }
 
     debug_assert!(!body.has_free_regions(), "Free regions in MIR for CTFE");
 
diff --git a/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs b/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs
index d19cf00eb9c..2afbf3432fb 100644
--- a/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs
+++ b/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs
@@ -1,6 +1,8 @@
 // check-pass
 
-// compile-flags: --crate-type lib
+// need to emit MIR, because const prop (which emits `unconditional_panic`) only runs if
+// the `optimized_mir` query is run, which it isn't in check-only mode.
+// compile-flags: --crate-type lib --emit=mir,link
 
 #![warn(unconditional_panic)]
 
diff --git a/src/test/ui/const_prop/ice-assert-fail-div-by-zero.stderr b/src/test/ui/const_prop/ice-assert-fail-div-by-zero.stderr
index 276fb716d42..865c69c3c89 100644
--- a/src/test/ui/const_prop/ice-assert-fail-div-by-zero.stderr
+++ b/src/test/ui/const_prop/ice-assert-fail-div-by-zero.stderr
@@ -1,11 +1,11 @@
 warning: this operation will panic at runtime
-  --> $DIR/ice-assert-fail-div-by-zero.rs:11:5
+  --> $DIR/ice-assert-fail-div-by-zero.rs:13:5
    |
 LL |     f.0 / 0;
    |     ^^^^^^^ attempt to divide `_` by zero
    |
 note: the lint level is defined here
-  --> $DIR/ice-assert-fail-div-by-zero.rs:5:9
+  --> $DIR/ice-assert-fail-div-by-zero.rs:7:9
    |
 LL | #![warn(unconditional_panic)]
    |         ^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/consts/const-eval/issue-49296.stderr b/src/test/ui/consts/const-eval/issue-49296.stderr
index 798f130a4ba..9363ffbb996 100644
--- a/src/test/ui/consts/const-eval/issue-49296.stderr
+++ b/src/test/ui/consts/const-eval/issue-49296.stderr
@@ -4,7 +4,7 @@ error: any use of this value will cause an error
 LL | const X: u64 = *wat(42);
    | ---------------^^^^^^^^-
    |                |
-   |                pointer to alloc2 was dereferenced after this allocation got freed
+   |                pointer to alloc1 was dereferenced after this allocation got freed
    |
    = note: `#[deny(const_err)]` on by default