Skip to content

Commit

Permalink
Rollup merge of rust-lang#67055 - lqd:const_qualif, r=oli-obk
Browse files Browse the repository at this point in the history
Make const-qualification look at more `const fn`s

As explained in a lot more detail in rust-lang#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 rust-lang#67053.
  • Loading branch information
Centril authored Dec 5, 2019
2 parents 0e18ca1 + 2d83b76 commit a008aff
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@
#![feature(const_fn)]
#![feature(const_fn_union)]
#![feature(const_generics)]
#![cfg_attr(not(bootstrap), feature(const_ptr_offset_from))]
#![cfg_attr(not(bootstrap), feature(const_type_name))]
#![feature(custom_inner_attributes)]
#![feature(decl_macro)]
#![feature(doc_cfg)]
Expand Down
7 changes: 6 additions & 1 deletion src/librustc_mir/transform/check_consts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,12 @@ impl ConstKind {
let mode = match tcx.hir().body_owner_kind(hir_id) {
HirKind::Closure => return None,

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

HirKind::Const => ConstKind::Const,
Expand Down
29 changes: 29 additions & 0 deletions src/test/ui/consts/unstable-const-fn-in-libcore.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// This is a non-regression test for const-qualification of unstable items in libcore
// as explained in issue #67053.
// const-qualification could miss some `const fn`s if they were unstable and the feature
// gate was not enabled in libcore.

#![stable(feature = "core", since = "1.6.0")]
#![feature(const_if_match)]
#![feature(rustc_const_unstable)]
#![feature(staged_api)]

enum Opt<T> {
Some(T),
None,
}

impl<T> Opt<T> {
#[rustc_const_unstable(feature = "foo")]
#[stable(feature = "rust1", since = "1.0.0")]
const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
//~^ ERROR destructors cannot be evaluated at compile-time
//~| ERROR destructors cannot be evaluated at compile-time
match self {
Opt::Some(t) => t,
Opt::None => f(), //~ ERROR E0015
}
}
}

fn main() {}
22 changes: 22 additions & 0 deletions src/test/ui/consts/unstable-const-fn-in-libcore.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
--> $DIR/unstable-const-fn-in-libcore.rs:24:26
|
LL | Opt::None => f(),
| ^^^

error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/unstable-const-fn-in-libcore.rs:19:53
|
LL | const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
| ^ constant functions cannot evaluate destructors

error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/unstable-const-fn-in-libcore.rs:19:47
|
LL | const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
| ^^^^ constant functions cannot evaluate destructors

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0015, E0493.
For more information about an error, try `rustc --explain E0015`.

0 comments on commit a008aff

Please sign in to comment.