Skip to content

Commit a008aff

Browse files
authored
Rollup merge of #67055 - lqd:const_qualif, r=oli-obk
Make const-qualification look at more `const fn`s As explained in a lot more detail in #67053 this makes const-qualification not ignore the unstable const fns in libcore. r? @oli-obk cc @ecstatic-morse (Still a bit unsure about the `cfg`s here, for bootstrapping, does that seem correct ?) Fixes #67053.
2 parents 0e18ca1 + 2d83b76 commit a008aff

File tree

4 files changed

+59
-1
lines changed

4 files changed

+59
-1
lines changed

Diff for: src/libcore/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@
7474
#![feature(const_fn)]
7575
#![feature(const_fn_union)]
7676
#![feature(const_generics)]
77+
#![cfg_attr(not(bootstrap), feature(const_ptr_offset_from))]
78+
#![cfg_attr(not(bootstrap), feature(const_type_name))]
7779
#![feature(custom_inner_attributes)]
7880
#![feature(decl_macro)]
7981
#![feature(doc_cfg)]

Diff for: src/librustc_mir/transform/check_consts/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,12 @@ impl ConstKind {
7777
let mode = match tcx.hir().body_owner_kind(hir_id) {
7878
HirKind::Closure => return None,
7979

80-
HirKind::Fn if tcx.is_const_fn(def_id) => ConstKind::ConstFn,
80+
// Note: this is deliberately checking for `is_const_fn_raw`, as the `is_const_fn`
81+
// checks take into account the `rustc_const_unstable` attribute combined with enabled
82+
// feature gates. Otherwise, const qualification would _not check_ whether this
83+
// function body follows the `const fn` rules, as an unstable `const fn` would
84+
// be considered "not const". More details are available in issue #67053.
85+
HirKind::Fn if tcx.is_const_fn_raw(def_id) => ConstKind::ConstFn,
8186
HirKind::Fn => return None,
8287

8388
HirKind::Const => ConstKind::Const,

Diff for: src/test/ui/consts/unstable-const-fn-in-libcore.rs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// This is a non-regression test for const-qualification of unstable items in libcore
2+
// as explained in issue #67053.
3+
// const-qualification could miss some `const fn`s if they were unstable and the feature
4+
// gate was not enabled in libcore.
5+
6+
#![stable(feature = "core", since = "1.6.0")]
7+
#![feature(const_if_match)]
8+
#![feature(rustc_const_unstable)]
9+
#![feature(staged_api)]
10+
11+
enum Opt<T> {
12+
Some(T),
13+
None,
14+
}
15+
16+
impl<T> Opt<T> {
17+
#[rustc_const_unstable(feature = "foo")]
18+
#[stable(feature = "rust1", since = "1.0.0")]
19+
const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
20+
//~^ ERROR destructors cannot be evaluated at compile-time
21+
//~| ERROR destructors cannot be evaluated at compile-time
22+
match self {
23+
Opt::Some(t) => t,
24+
Opt::None => f(), //~ ERROR E0015
25+
}
26+
}
27+
}
28+
29+
fn main() {}
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
2+
--> $DIR/unstable-const-fn-in-libcore.rs:24:26
3+
|
4+
LL | Opt::None => f(),
5+
| ^^^
6+
7+
error[E0493]: destructors cannot be evaluated at compile-time
8+
--> $DIR/unstable-const-fn-in-libcore.rs:19:53
9+
|
10+
LL | const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
11+
| ^ constant functions cannot evaluate destructors
12+
13+
error[E0493]: destructors cannot be evaluated at compile-time
14+
--> $DIR/unstable-const-fn-in-libcore.rs:19:47
15+
|
16+
LL | const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
17+
| ^^^^ constant functions cannot evaluate destructors
18+
19+
error: aborting due to 3 previous errors
20+
21+
Some errors have detailed explanations: E0015, E0493.
22+
For more information about an error, try `rustc --explain E0015`.

0 commit comments

Comments
 (0)