Skip to content

Commit

Permalink
Do not run const prop on the mir_for_ctfe of const fn
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Jan 4, 2021
1 parent 409195d commit 65ee418
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 23 deletions.
53 changes: 34 additions & 19 deletions compiler/rustc_mir/src/transform/mod.rs
Expand Up @@ -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");

Expand Down
4 changes: 3 additions & 1 deletion 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)]

Expand Down
4 changes: 2 additions & 2 deletions 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)]
| ^^^^^^^^^^^^^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/issue-49296.stderr
Expand Up @@ -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

Expand Down

0 comments on commit 65ee418

Please sign in to comment.