about summary refs log tree commit diff
path: root/src/librustc_mir/transform
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-01-11 12:36:14 +0100
committerGitHub <noreply@github.com>2020-01-11 12:36:14 +0100
commit50d76d647191bdff875e854ed2ee2282ab274a09 (patch)
tree12e19976ffaa3e72ec450b2947d02b57a511a956 /src/librustc_mir/transform
parentf02f338ee064cf78e0b2234cbbfcaf43c451217d (diff)
parentfc30825c8b22d93419a087fcec1817108d9b694b (diff)
downloadrust-50d76d647191bdff875e854ed2ee2282ab274a09.tar.gz
rust-50d76d647191bdff875e854ed2ee2282ab274a09.zip
Rollup merge of #68114 - ecstatic-morse:fix-feature-gating, r=Centril
Don't require `allow_internal_unstable` unless `staged_api` is enabled.

#63770 changed `qualify_min_const_fn` to require `allow_internal_unstable` for *all* crates that used an unstable feature, regardless of whether `staged_api` was enabled or the `fn` that used that feature was stably const. In practice, this meant that every crate in the ecosystem that wanted to use nightly features added `#![feature(const_fn)]`, which skips `qualify_min_const_fn` entirely.

After this PR, crates that do not have `#![feature(staged_api)]` will only need to enable the feature they are interested in. For example, `#![feature(const_if_match)]` will be enough to enable `if` and `match` in constants. Crates with `staged_api` (e.g., `libstd`) require `#[allow_internal_unstable]` to be added to a function if it uses nightly features unless that function is also marked `#[rustc_const_unstable]`. This prevents proliferation of `#[allow_internal_unstable]` into functions that are not callable in a `const` context on stable.

r? @oli-obk (author of #63770)
cc @Centril
Diffstat (limited to 'src/librustc_mir/transform')
-rw-r--r--src/librustc_mir/transform/qualify_min_const_fn.rs16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index fcdabb29cd0..c2c1625001d 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -281,8 +281,22 @@ fn check_place(
     Ok(())
 }
 
-/// Returns whether `allow_internal_unstable(..., <feature_gate>, ...)` is present.
+/// Returns `true` if the given feature gate is allowed within the function with the given `DefId`.
 fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool {
+    // All features require that the corresponding gate be enabled,
+    // even if the function has `#[allow_internal_unstable(the_gate)]`.
+    if !tcx.features().enabled(feature_gate) {
+        return false;
+    }
+
+    // If this crate is not using stability attributes, or this function is not claiming to be a
+    // stable `const fn`, that is all that is required.
+    if !tcx.features().staged_api || tcx.has_attr(def_id, sym::rustc_const_unstable) {
+        return true;
+    }
+
+    // However, we cannot allow stable `const fn`s to use unstable features without an explicit
+    // opt-in via `allow_internal_unstable`.
     attr::allow_internal_unstable(&tcx.get_attrs(def_id), &tcx.sess.diagnostic())
         .map_or(false, |mut features| features.any(|name| name == feature_gate))
 }