about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-09-01 11:26:24 +0000
committerbors <bors@rust-lang.org>2018-09-01 11:26:24 +0000
commitfea32f1b775b3f37fc4abfa6391c1bebe48af9d1 (patch)
treeab51afef12f740e9b7e2ffd7595ce0869c7e45a1 /src/libsyntax
parente6381a7f37402dd5f346256b3773ae2e72853fc3 (diff)
parent2839f4f0e8d58c295e146999961b78e2cc47354f (diff)
downloadrust-fea32f1b775b3f37fc4abfa6391c1bebe48af9d1.tar.gz
rust-fea32f1b775b3f37fc4abfa6391c1bebe48af9d1.zip
Auto merge of #53604 - oli-obk:min_const_fn, r=Centril,varkor
Implement the `min_const_fn` feature gate

cc @RalfJung @eddyb

r? @Centril

implements the feature gate for #53555

I added a hack so the `const_fn` feature gate also enables the `min_const_fn` feature gate. This ensures that nightly users of `const_fn` don't have to touch their code at all.

The `min_const_fn` checks are run first, and if they succeeded, the `const_fn` checks are run additionally to ensure we didn't miss anything.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/attr/builtin.rs26
-rw-r--r--src/libsyntax/attr/mod.rs2
-rw-r--r--src/libsyntax/feature_gate.rs29
3 files changed, 34 insertions, 23 deletions
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index ecd52a62eab..3eecdf14a4e 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -107,7 +107,11 @@ pub struct Stability {
     pub level: StabilityLevel,
     pub feature: Symbol,
     pub rustc_depr: Option<RustcDeprecation>,
-    pub rustc_const_unstable: Option<RustcConstUnstable>,
+    /// `None` means the function is stable but needs to be allowed by the
+    /// `min_const_fn` feature
+    /// `Some` contains the feature gate required to be able to use the function
+    /// as const fn
+    pub const_stability: Option<Symbol>,
 }
 
 /// The available stability levels.
@@ -141,11 +145,6 @@ pub struct RustcDeprecation {
     pub reason: Symbol,
 }
 
-#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
-pub struct RustcConstUnstable {
-    pub feature: Symbol,
-}
-
 /// Check if `attrs` contains an attribute like `#![feature(feature_name)]`.
 /// This will not perform any "sanity checks" on the form of the attributes.
 pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool {
@@ -176,7 +175,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
 
     let mut stab: Option<Stability> = None;
     let mut rustc_depr: Option<RustcDeprecation> = None;
-    let mut rustc_const_unstable: Option<RustcConstUnstable> = None;
+    let mut rustc_const_unstable: Option<Symbol> = None;
 
     'outer: for attr in attrs_iter {
         if ![
@@ -191,6 +190,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
         mark_used(attr);
 
         let meta = attr.meta();
+        // attributes with data
         if let Some(MetaItem { node: MetaItemKind::List(ref metas), .. }) = meta {
             let meta = meta.as_ref().unwrap();
             let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
@@ -272,9 +272,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
 
                     get_meta!(feature);
                     if let Some(feature) = feature {
-                        rustc_const_unstable = Some(RustcConstUnstable {
-                            feature
-                        });
+                        rustc_const_unstable = Some(feature);
                     } else {
                         span_err!(diagnostic, attr.span(), E0629, "missing 'feature'");
                         continue
@@ -330,7 +328,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
                                 },
                                 feature,
                                 rustc_depr: None,
-                                rustc_const_unstable: None,
+                                const_stability: None,
                             })
                         }
                         (None, _, _) => {
@@ -379,7 +377,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
                                 },
                                 feature,
                                 rustc_depr: None,
-                                rustc_const_unstable: None,
+                                const_stability: None,
                             })
                         }
                         (None, _) => {
@@ -412,9 +410,9 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler,
     }
 
     // Merge the const-unstable info into the stability info
-    if let Some(rustc_const_unstable) = rustc_const_unstable {
+    if let Some(feature) = rustc_const_unstable {
         if let Some(ref mut stab) = stab {
-            stab.rustc_const_unstable = Some(rustc_const_unstable);
+            stab.const_stability = Some(feature);
         } else {
             span_err!(diagnostic, item_sp, E0630,
                       "rustc_const_unstable attribute must be paired with \
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index cd9d7682210..19bbbceff5f 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -15,7 +15,7 @@ mod builtin;
 pub use self::builtin::{
     cfg_matches, contains_feature_attr, eval_condition, find_crate_name, find_deprecation,
     find_repr_attrs, find_stability, find_unwind_attr, Deprecation, InlineAttr, IntType, ReprAttr,
-    RustcConstUnstable, RustcDeprecation, Stability, StabilityLevel, UnwindAttr,
+    RustcDeprecation, Stability, StabilityLevel, UnwindAttr,
 };
 pub use self::IntType::*;
 pub use self::ReprAttr::*;
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 080860f17f5..f226c9dd979 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -40,6 +40,16 @@ use symbol::{keywords, Symbol};
 use std::{env, path};
 
 macro_rules! set {
+    // The const_fn feature also enables the min_const_fn feature, because `min_const_fn` allows
+    // the declaration `const fn`, but the `const_fn` feature gate enables things inside those
+    // functions that we do not want to expose to the user for now.
+    (const_fn) => {{
+        fn f(features: &mut Features, _: Span) {
+            features.const_fn = true;
+            features.min_const_fn = true;
+        }
+        f as fn(&mut Features, Span)
+    }};
     ($field: ident) => {{
         fn f(features: &mut Features, _: Span) {
             features.$field = true;
@@ -206,25 +216,28 @@ declare_features! (
     // #23121. Array patterns have some hazards yet.
     (active, slice_patterns, "1.0.0", Some(23121), None),
 
-    // Allows the definition of `const fn` functions.
+    // Allows the definition of `const fn` functions with some advanced features.
     (active, const_fn, "1.2.0", Some(24111), None),
 
+    // Allows the definition of `const fn` functions.
+    (active, min_const_fn, "1.30.0", Some(53555), None),
+
     // Allows let bindings and destructuring in `const fn` functions and constants.
     (active, const_let, "1.22.1", Some(48821), None),
 
-    // Allows accessing fields of unions inside const fn
+    // Allows accessing fields of unions inside const fn.
     (active, const_fn_union, "1.27.0", Some(51909), None),
 
-    // Allows casting raw pointers to `usize` during const eval
+    // Allows casting raw pointers to `usize` during const eval.
     (active, const_raw_ptr_to_usize_cast, "1.27.0", Some(51910), None),
 
-    // Allows dereferencing raw pointers during const eval
+    // Allows dereferencing raw pointers during const eval.
     (active, const_raw_ptr_deref, "1.27.0", Some(51911), None),
 
-    // Allows reinterpretation of the bits of a value of one type as another type during const eval
+    // Allows reinterpretation of the bits of a value of one type as another type during const eval.
     (active, const_transmute, "1.29.0", Some(53605), None),
 
-    // Allows comparing raw pointers during const eval
+    // Allows comparing raw pointers during const eval.
     (active, const_compare_raw_pointers, "1.27.0", Some(53020), None),
 
     // Allows panicking during const eval (produces compile-time errors)
@@ -1786,7 +1799,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                     gate_feature_post!(&self, async_await, span, "async fn is unstable");
                 }
                 if header.constness.node == ast::Constness::Const {
-                    gate_feature_post!(&self, const_fn, span, "const fn is unstable");
+                    gate_feature_post!(&self, min_const_fn, span, "const fn is unstable");
                 }
                 // stability of const fn methods are covered in
                 // visit_trait_item and visit_impl_item below; this is
@@ -1844,7 +1857,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         match ii.node {
             ast::ImplItemKind::Method(ref sig, _) => {
                 if sig.header.constness.node == ast::Constness::Const {
-                    gate_feature_post!(&self, const_fn, ii.span, "const fn is unstable");
+                    gate_feature_post!(&self, min_const_fn, ii.span, "const fn is unstable");
                 }
             }
             ast::ImplItemKind::Existential(..) => {