about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-12-05 19:03:21 +0100
committerGitHub <noreply@github.com>2019-12-05 19:03:21 +0100
commita008aff0758268c03496d25686cf74e270cef8ba (patch)
tree2527eb2cfba3e52b99aa55f4f199e2a64ccfc67b
parent0e18ca14479df69fd02b68945c3155c50c3effa4 (diff)
parent2d83b7608070d6ad250e8cd6d9d5a7d4be628dc4 (diff)
downloadrust-a008aff0758268c03496d25686cf74e270cef8ba.tar.gz
rust-a008aff0758268c03496d25686cf74e270cef8ba.zip
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.
-rw-r--r--src/libcore/lib.rs2
-rw-r--r--src/librustc_mir/transform/check_consts/mod.rs7
-rw-r--r--src/test/ui/consts/unstable-const-fn-in-libcore.rs29
-rw-r--r--src/test/ui/consts/unstable-const-fn-in-libcore.stderr22
4 files changed, 59 insertions, 1 deletions
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index ec19392450a..188ea1a9631 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -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)]
diff --git a/src/librustc_mir/transform/check_consts/mod.rs b/src/librustc_mir/transform/check_consts/mod.rs
index 7095b3fa0aa..82ffafbedf8 100644
--- a/src/librustc_mir/transform/check_consts/mod.rs
+++ b/src/librustc_mir/transform/check_consts/mod.rs
@@ -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,
diff --git a/src/test/ui/consts/unstable-const-fn-in-libcore.rs b/src/test/ui/consts/unstable-const-fn-in-libcore.rs
new file mode 100644
index 00000000000..cad1516fc78
--- /dev/null
+++ b/src/test/ui/consts/unstable-const-fn-in-libcore.rs
@@ -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() {}
diff --git a/src/test/ui/consts/unstable-const-fn-in-libcore.stderr b/src/test/ui/consts/unstable-const-fn-in-libcore.stderr
new file mode 100644
index 00000000000..a8455cefd01
--- /dev/null
+++ b/src/test/ui/consts/unstable-const-fn-in-libcore.stderr
@@ -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`.