From 65ee418e5c2de7d84353979bbd978ca09390ccba Mon Sep 17 00:00:00 2001 From: oli Date: Mon, 4 Jan 2021 19:05:51 +0000 Subject: [PATCH] Do not run const prop on the `mir_for_ctfe` of `const fn` --- compiler/rustc_mir/src/transform/mod.rs | 53 ++++++++++++------- .../const_prop/ice-assert-fail-div-by-zero.rs | 4 +- .../ice-assert-fail-div-by-zero.stderr | 4 +- .../ui/consts/const-eval/issue-49296.stderr | 2 +- 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 717479b999076..11f7e6922ccbc 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) - 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 d19cf00eb9ce4..2afbf3432fb45 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 276fb716d4255..865c69c3c8983 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 798f130a4baf6..9363ffbb996e4 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