Skip to content

Commit 65ee418

Browse files
committed
Do not run const prop on the mir_for_ctfe of const fn
1 parent 409195d commit 65ee418

File tree

4 files changed

+40
-23
lines changed

4 files changed

+40
-23
lines changed

compiler/rustc_mir/src/transform/mod.rs

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -357,28 +357,43 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -
357357
return shim::build_adt_ctor(tcx, def.did.to_def_id());
358358
}
359359

360-
assert_ne!(
361-
tcx.hir().body_const_context(def.did),
362-
None,
363-
"mir_for_ctfe should not be used for runtime functions"
364-
);
360+
let context = tcx
361+
.hir()
362+
.body_const_context(def.did)
363+
.expect("mir_for_ctfe should not be used for runtime functions");
365364

366365
let mut body = tcx.mir_drops_elaborated_and_const_checked(def).borrow().clone();
367366

368-
#[rustfmt::skip]
369-
let optimizations: &[&dyn MirPass<'_>] = &[
370-
&const_prop::ConstProp,
371-
];
372-
373-
#[rustfmt::skip]
374-
run_passes(
375-
tcx,
376-
&mut body,
377-
MirPhase::Optimization,
378-
&[
379-
optimizations,
380-
],
381-
);
367+
match context {
368+
// Do not const prop functions, either they get executed at runtime or exported to metadata,
369+
// so we run const prop on them, or they don't, in which case we const evaluate some control
370+
// flow paths of the function and any errors in those paths will get emitted as const eval
371+
// errors.
372+
hir::ConstContext::ConstFn => {}
373+
// Static items always get evaluated, so we can just let const eval see if any erroneous
374+
// control flow paths get executed.
375+
hir::ConstContext::Static(_) => {}
376+
// Associated constants get const prop run so we detect common failure situations in the
377+
// crate that defined the constant.
378+
// Technically we want to not run on regular const items, but oli-obk doesn't know how to
379+
// conveniently detect that at this point without looking at the HIR.
380+
hir::ConstContext::Const => {
381+
#[rustfmt::skip]
382+
let optimizations: &[&dyn MirPass<'_>] = &[
383+
&const_prop::ConstProp,
384+
];
385+
386+
#[rustfmt::skip]
387+
run_passes(
388+
tcx,
389+
&mut body,
390+
MirPhase::Optimization,
391+
&[
392+
optimizations,
393+
],
394+
);
395+
}
396+
}
382397

383398
debug_assert!(!body.has_free_regions(), "Free regions in MIR for CTFE");
384399

src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// check-pass
22

3-
// compile-flags: --crate-type lib
3+
// need to emit MIR, because const prop (which emits `unconditional_panic`) only runs if
4+
// the `optimized_mir` query is run, which it isn't in check-only mode.
5+
// compile-flags: --crate-type lib --emit=mir,link
46

57
#![warn(unconditional_panic)]
68

src/test/ui/const_prop/ice-assert-fail-div-by-zero.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
warning: this operation will panic at runtime
2-
--> $DIR/ice-assert-fail-div-by-zero.rs:11:5
2+
--> $DIR/ice-assert-fail-div-by-zero.rs:13:5
33
|
44
LL | f.0 / 0;
55
| ^^^^^^^ attempt to divide `_` by zero
66
|
77
note: the lint level is defined here
8-
--> $DIR/ice-assert-fail-div-by-zero.rs:5:9
8+
--> $DIR/ice-assert-fail-div-by-zero.rs:7:9
99
|
1010
LL | #![warn(unconditional_panic)]
1111
| ^^^^^^^^^^^^^^^^^^^

src/test/ui/consts/const-eval/issue-49296.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error: any use of this value will cause an error
44
LL | const X: u64 = *wat(42);
55
| ---------------^^^^^^^^-
66
| |
7-
| pointer to alloc2 was dereferenced after this allocation got freed
7+
| pointer to alloc1 was dereferenced after this allocation got freed
88
|
99
= note: `#[deny(const_err)]` on by default
1010

0 commit comments

Comments
 (0)