Skip to content

Commit

Permalink
Rollup merge of rust-lang#68114 - ecstatic-morse:fix-feature-gating, …
Browse files Browse the repository at this point in the history
…r=Centril

Don't require `allow_internal_unstable` unless `staged_api` is enabled.

rust-lang#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 rust-lang#63770)
cc @Centril
  • Loading branch information
Centril authored Jan 11, 2020
2 parents c47118c + fc30825 commit 28a63cd
Show file tree
Hide file tree
Showing 19 changed files with 66 additions and 41 deletions.
1 change: 0 additions & 1 deletion src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
#![feature(bound_cloned)]
#![feature(cfg_target_has_atomic)]
#![feature(concat_idents)]
#![feature(const_fn)]
#![feature(const_if_match)]
#![feature(const_panic)]
#![feature(const_fn_union)]
Expand Down
1 change: 0 additions & 1 deletion src/libcore/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#![feature(slice_internals)]
#![feature(slice_partition_dedup)]
#![feature(int_error_matching)]
#![feature(const_fn)]
#![feature(array_value_iter)]
#![feature(iter_partition_in_place)]
#![feature(iter_is_partitioned)]
Expand Down
1 change: 0 additions & 1 deletion src/libproc_macro/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#![feature(nll)]
#![feature(staged_api)]
#![feature(allow_internal_unstable)]
#![feature(const_fn)]
#![feature(decl_macro)]
#![feature(extern_types)]
#![feature(in_band_lifetimes)]
Expand Down
1 change: 0 additions & 1 deletion src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#![feature(bool_to_option)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(const_fn)]
#![feature(const_transmute)]
#![feature(core_intrinsics)]
#![feature(drain_filter)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_hir/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html

#![feature(crate_visibility_modifier)]
#![feature(const_fn)]
#![feature(const_fn)] // For the unsizing cast on `&[]`
#![feature(in_band_lifetimes)]
#![feature(specialization)]
#![recursion_limit = "256"]
Expand Down
1 change: 0 additions & 1 deletion src/librustc_mir/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
#![feature(box_syntax)]
#![feature(crate_visibility_modifier)]
#![feature(core_intrinsics)]
#![feature(const_fn)]
#![feature(decl_macro)]
#![feature(drain_filter)]
#![feature(exhaustive_patterns)]
Expand Down
16 changes: 15 additions & 1 deletion src/librustc_mir/transform/qualify_min_const_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand Down
1 change: 0 additions & 1 deletion src/librustc_span/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
//! This API is completely unstable and subject to change.

#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(const_fn)]
#![feature(crate_visibility_modifier)]
#![feature(nll)]
#![feature(optin_builtin_traits)]
Expand Down
1 change: 0 additions & 1 deletion src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#![feature(test)]
#![feature(ptr_offset_from)]
#![feature(crate_visibility_modifier)]
#![feature(const_fn)]
#![feature(drain_filter)]
#![feature(never_type)]
#![feature(unicode_internals)]
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))]
#![feature(bool_to_option)]
#![feature(box_syntax)]
#![feature(const_fn)]
#![feature(const_fn)] // For the `transmute` in `P::new`
#![feature(const_transmute)]
#![feature(crate_visibility_modifier)]
#![feature(label_break_value)]
Expand Down
1 change: 0 additions & 1 deletion src/test/ui/consts/const-mut-refs/const_mut_refs.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// run-pass

#![feature(const_mut_refs)]
#![feature(const_fn)]

struct Foo {
x: usize
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// check-pass

#![feature(const_if_match)]
#![feature(const_fn)]

enum E {
A,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: fatal error triggered by #[rustc_error]
--> $DIR/feature-gate-const-if-match.rs:109:1
--> $DIR/feature-gate-const-if-match.rs:108:1
|
LL | / fn main() {
LL | | let _ = [0; {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

#![feature(rustc_attrs)]
#![cfg_attr(if_match, feature(const_if_match))]
#![feature(const_fn)]

const _: i32 = if true { //[stock]~ ERROR `if` is not allowed in a `const`
5
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0658]: `if` is not allowed in a `const`
--> $DIR/feature-gate-const-if-match.rs:11:16
--> $DIR/feature-gate-const-if-match.rs:10:16
|
LL | const _: i32 = if true {
| ________________^
Expand All @@ -13,7 +13,7 @@ LL | | };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `const`
--> $DIR/feature-gate-const-if-match.rs:17:16
--> $DIR/feature-gate-const-if-match.rs:16:16
|
LL | const _: i32 = if let Some(true) = Some(false) {
| ________________^
Expand All @@ -27,7 +27,7 @@ LL | | };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `match` is not allowed in a `const`
--> $DIR/feature-gate-const-if-match.rs:23:16
--> $DIR/feature-gate-const-if-match.rs:22:16
|
LL | const _: i32 = match 1 {
| ________________^
Expand All @@ -41,7 +41,7 @@ LL | | };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `static`
--> $DIR/feature-gate-const-if-match.rs:30:13
--> $DIR/feature-gate-const-if-match.rs:29:13
|
LL | let x = if true { 0 } else { 1 };
| ^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -50,7 +50,7 @@ LL | let x = if true { 0 } else { 1 };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `match` is not allowed in a `static`
--> $DIR/feature-gate-const-if-match.rs:32:13
--> $DIR/feature-gate-const-if-match.rs:31:13
|
LL | let x = match x { 0 => 1, _ => 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -59,7 +59,7 @@ LL | let x = match x { 0 => 1, _ => 0 };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `static`
--> $DIR/feature-gate-const-if-match.rs:34:5
--> $DIR/feature-gate-const-if-match.rs:33:5
|
LL | if let Some(x) = Some(x) { x } else { 1 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -68,7 +68,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 }
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `static mut`
--> $DIR/feature-gate-const-if-match.rs:39:13
--> $DIR/feature-gate-const-if-match.rs:38:13
|
LL | let x = if true { 0 } else { 1 };
| ^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -77,7 +77,7 @@ LL | let x = if true { 0 } else { 1 };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `match` is not allowed in a `static mut`
--> $DIR/feature-gate-const-if-match.rs:41:13
--> $DIR/feature-gate-const-if-match.rs:40:13
|
LL | let x = match x { 0 => 1, _ => 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -86,7 +86,7 @@ LL | let x = match x { 0 => 1, _ => 0 };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `static mut`
--> $DIR/feature-gate-const-if-match.rs:43:5
--> $DIR/feature-gate-const-if-match.rs:42:5
|
LL | if let Some(x) = Some(x) { x } else { 1 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -95,7 +95,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 }
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `const fn`
--> $DIR/feature-gate-const-if-match.rs:48:5
--> $DIR/feature-gate-const-if-match.rs:47:5
|
LL | if true { 5 } else { 6 }
| ^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -104,7 +104,7 @@ LL | if true { 5 } else { 6 }
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `const fn`
--> $DIR/feature-gate-const-if-match.rs:52:5
--> $DIR/feature-gate-const-if-match.rs:51:5
|
LL | / if let Some(true) = a {
LL | | 0
Expand All @@ -117,7 +117,7 @@ LL | | }
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `match` is not allowed in a `const fn`
--> $DIR/feature-gate-const-if-match.rs:60:5
--> $DIR/feature-gate-const-if-match.rs:59:5
|
LL | / match i {
LL | | i if i > 10 => i,
Expand All @@ -130,7 +130,7 @@ LL | | }
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `const fn`
--> $DIR/feature-gate-const-if-match.rs:91:17
--> $DIR/feature-gate-const-if-match.rs:90:17
|
LL | let x = if y { 0 } else { 1 };
| ^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -139,7 +139,7 @@ LL | let x = if y { 0 } else { 1 };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `match` is not allowed in a `const fn`
--> $DIR/feature-gate-const-if-match.rs:93:17
--> $DIR/feature-gate-const-if-match.rs:92:17
|
LL | let x = match x { 0 => 1, _ => 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -148,7 +148,7 @@ LL | let x = match x { 0 => 1, _ => 0 };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `const fn`
--> $DIR/feature-gate-const-if-match.rs:95:9
--> $DIR/feature-gate-const-if-match.rs:94:9
|
LL | if let Some(x) = Some(x) { x } else { 1 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -157,7 +157,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 }
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `const`
--> $DIR/feature-gate-const-if-match.rs:111:17
--> $DIR/feature-gate-const-if-match.rs:110:17
|
LL | let x = if false { 0 } else { 1 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -166,7 +166,7 @@ LL | let x = if false { 0 } else { 1 };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `match` is not allowed in a `const`
--> $DIR/feature-gate-const-if-match.rs:113:17
--> $DIR/feature-gate-const-if-match.rs:112:17
|
LL | let x = match x { 0 => 1, _ => 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -175,7 +175,7 @@ LL | let x = match x { 0 => 1, _ => 0 };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `const`
--> $DIR/feature-gate-const-if-match.rs:115:9
--> $DIR/feature-gate-const-if-match.rs:114:9
|
LL | if let Some(x) = Some(x) { x } else { 1 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -184,7 +184,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 }
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `const`
--> $DIR/feature-gate-const-if-match.rs:68:21
--> $DIR/feature-gate-const-if-match.rs:67:21
|
LL | const IF: i32 = if true { 5 } else { 6 };
| ^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -193,7 +193,7 @@ LL | const IF: i32 = if true { 5 } else { 6 };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `const`
--> $DIR/feature-gate-const-if-match.rs:71:25
--> $DIR/feature-gate-const-if-match.rs:70:25
|
LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -202,7 +202,7 @@ LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `match` is not allowed in a `const`
--> $DIR/feature-gate-const-if-match.rs:74:24
--> $DIR/feature-gate-const-if-match.rs:73:24
|
LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -211,7 +211,7 @@ LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `const`
--> $DIR/feature-gate-const-if-match.rs:79:21
--> $DIR/feature-gate-const-if-match.rs:78:21
|
LL | const IF: i32 = if true { 5 } else { 6 };
| ^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -220,7 +220,7 @@ LL | const IF: i32 = if true { 5 } else { 6 };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `if` is not allowed in a `const`
--> $DIR/feature-gate-const-if-match.rs:82:25
--> $DIR/feature-gate-const-if-match.rs:81:25
|
LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -229,7 +229,7 @@ LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `match` is not allowed in a `const`
--> $DIR/feature-gate-const-if-match.rs:85:24
--> $DIR/feature-gate-const-if-match.rs:84:24
|
LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -238,7 +238,7 @@ LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0019]: constant contains unimplemented expression type
--> $DIR/feature-gate-const-if-match.rs:115:21
--> $DIR/feature-gate-const-if-match.rs:114:21
|
LL | if let Some(x) = Some(x) { x } else { 1 }
| ^
Expand Down
1 change: 0 additions & 1 deletion src/test/ui/consts/control-flow/short-circuit-let.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#![feature(const_if_match)]
#![feature(const_panic)]
#![feature(const_fn)]

const X: i32 = {
let mut x = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// check-pass

#![feature(const_if_match, const_fn)]
#![feature(const_if_match)]

enum Foo {
Prob,
Expand Down
10 changes: 10 additions & 0 deletions src/test/ui/internal/internal-unstable-const.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#![feature(staged_api)]
#![feature(const_if_match)]

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
const fn foo() -> i32 {
if true { 4 } else { 5 } //~ loops and conditional expressions are not stable in const fn
}

fn main() {}
12 changes: 12 additions & 0 deletions src/test/ui/internal/internal-unstable-const.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0723]: loops and conditional expressions are not stable in const fn
--> $DIR/internal-unstable-const.rs:7:5
|
LL | if true { 4 } else { 5 }
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
= help: add `#![feature(const_fn)]` to the crate attributes to enable

error: aborting due to previous error

For more information about this error, try `rustc --explain E0723`.

0 comments on commit 28a63cd

Please sign in to comment.