about summary refs log tree commit diff
path: root/src/libsyntax/feature_gate
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax/feature_gate')
-rw-r--r--src/libsyntax/feature_gate/accepted.rs16
-rw-r--r--src/libsyntax/feature_gate/active.rs10
-rw-r--r--src/libsyntax/feature_gate/check.rs33
-rw-r--r--src/libsyntax/feature_gate/mod.rs33
-rw-r--r--src/libsyntax/feature_gate/removed.rs29
5 files changed, 98 insertions, 23 deletions
diff --git a/src/libsyntax/feature_gate/accepted.rs b/src/libsyntax/feature_gate/accepted.rs
index 28e4d2c073c..6c0b271c6c5 100644
--- a/src/libsyntax/feature_gate/accepted.rs
+++ b/src/libsyntax/feature_gate/accepted.rs
@@ -1,14 +1,24 @@
 //! List of the accepted feature gates.
 
-use crate::symbol::{Symbol, sym};
+use crate::symbol::sym;
+use super::{State, Feature};
 
 macro_rules! declare_features {
     ($(
         $(#[doc = $doc:tt])* (accepted, $feature:ident, $ver:expr, $issue:expr, None),
     )+) => {
         /// Those language feature has since been Accepted (it was once Active)
-        pub const ACCEPTED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
-            $((sym::$feature, $ver, $issue, None)),+
+        pub const ACCEPTED_FEATURES: &[Feature] = &[
+            $(
+                Feature {
+                    state: State::Accepted,
+                    name: sym::$feature,
+                    since: $ver,
+                    issue: $issue,
+                    edition: None,
+                    description: concat!($($doc,)*),
+                }
+            ),+
         ];
     }
 }
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index 4008b79b141..c947b09fdcb 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -65,6 +65,16 @@ macro_rules! declare_features {
     };
 }
 
+impl Feature {
+    /// Set this feature in `Features`. Panics if called on a non-active feature.
+    pub fn set(&self, features: &mut Features, span: Span) {
+        match self.state {
+            State::Active { set } => set(features, span),
+            _ => panic!("Called `set` on feature `{}` which is not `active`", self.name)
+        }
+    }
+}
+
 // If you change this, please modify `src/doc/unstable-book` as well.
 //
 // Don't ever remove anything from this list; move them to `removed.rs`.
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index d82b287b6fb..344e5fd6e46 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -1,4 +1,4 @@
-use super::active::{ACTIVE_FEATURES, Features};
+use super::{active::{ACTIVE_FEATURES, Features}, Feature, State as FeatureState};
 use super::accepted::ACCEPTED_FEATURES;
 use super::removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
 use super::builtin_attrs::{AttributeGate, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
@@ -127,17 +127,16 @@ pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features:
 }
 
 fn find_lang_feature_issue(feature: Symbol) -> Option<u32> {
-    if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.0 == feature) {
-        let issue = info.2;
+    if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.name == feature) {
         // FIXME (#28244): enforce that active features have issue numbers
-        // assert!(issue.is_some())
-        issue
+        // assert!(info.issue.is_some())
+        info.issue
     } else {
         // search in Accepted, Removed, or Stable Removed features
         let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES)
-            .find(|t| t.0 == feature);
+            .find(|t| t.name == feature);
         match found {
-            Some(&(_, _, issue, _)) => issue,
+            Some(&Feature { issue, .. }) => issue,
             None => panic!("Feature `{}` is not declared anywhere", feature),
         }
     }
@@ -829,14 +828,18 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
                 continue;
             }
 
-            let removed = REMOVED_FEATURES.iter().find(|f| name == f.0);
-            let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.0);
-            if let Some((.., reason)) = removed.or(stable_removed) {
-                feature_removed(span_handler, mi.span(), *reason);
-                continue;
+            let removed = REMOVED_FEATURES.iter().find(|f| name == f.name);
+            let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.name);
+            if let Some(Feature { state, .. }) = removed.or(stable_removed) {
+                if let FeatureState::Removed { reason }
+                | FeatureState::Stabilized { reason } = state
+                {
+                    feature_removed(span_handler, mi.span(), *reason);
+                    continue;
+                }
             }
 
-            if let Some((_, since, ..)) = ACCEPTED_FEATURES.iter().find(|f| name == f.0) {
+            if let Some(Feature { since, .. }) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) {
                 let since = Some(Symbol::intern(since));
                 features.declared_lang_features.push((name, mi.span(), since));
                 continue;
@@ -851,8 +854,8 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
                 }
             }
 
-            if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
-                set(&mut features, mi.span());
+            if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.name) {
+                f.set(&mut features, mi.span());
                 features.declared_lang_features.push((name, mi.span(), None));
                 continue;
             }
diff --git a/src/libsyntax/feature_gate/mod.rs b/src/libsyntax/feature_gate/mod.rs
index 97793bca1f5..1e41667ea41 100644
--- a/src/libsyntax/feature_gate/mod.rs
+++ b/src/libsyntax/feature_gate/mod.rs
@@ -18,6 +18,39 @@ mod active;
 mod builtin_attrs;
 mod check;
 
+use std::fmt;
+use crate::{edition::Edition, symbol::Symbol};
+use syntax_pos::Span;
+
+#[derive(Clone, Copy)]
+pub enum State {
+    Accepted,
+    Active { set: fn(&mut Features, Span) },
+    Removed { reason: Option<&'static str> },
+    Stabilized { reason: Option<&'static str> },
+}
+
+impl fmt::Debug for State {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            State::Accepted { .. } => write!(f, "accepted"),
+            State::Active { .. } => write!(f, "active"),
+            State::Removed { .. } => write!(f, "removed"),
+            State::Stabilized { .. } => write!(f, "stabilized"),
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Feature {
+    state: State,
+    name: Symbol,
+    since: &'static str,
+    issue: Option<u32>,
+    edition: Option<Edition>,
+    description: &'static str,
+}
+
 pub use active::{Features, INCOMPLETE_FEATURES};
 pub use builtin_attrs::{
     AttributeGate, AttributeType, GatedCfg,
diff --git a/src/libsyntax/feature_gate/removed.rs b/src/libsyntax/feature_gate/removed.rs
index 6494c82e122..ad7d69b3e73 100644
--- a/src/libsyntax/feature_gate/removed.rs
+++ b/src/libsyntax/feature_gate/removed.rs
@@ -1,14 +1,24 @@
 //! List of the removed feature gates.
 
-use crate::symbol::{Symbol, sym};
+use crate::symbol::sym;
+use super::{State, Feature};
 
 macro_rules! declare_features {
     ($(
         $(#[doc = $doc:tt])* (removed, $feature:ident, $ver:expr, $issue:expr, None, $reason:expr),
     )+) => {
         /// Represents unstable features which have since been removed (it was once Active)
-        pub const REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
-            $((sym::$feature, $ver, $issue, $reason)),+
+        pub const REMOVED_FEATURES: &[Feature] = &[
+            $(
+                Feature {
+                    state: State::Removed { reason: $reason },
+                    name: sym::$feature,
+                    since: $ver,
+                    issue: $issue,
+                    edition: None,
+                    description: concat!($($doc,)*),
+                }
+            ),+
         ];
     };
 
@@ -16,8 +26,17 @@ macro_rules! declare_features {
         $(#[doc = $doc:tt])* (stable_removed, $feature:ident, $ver:expr, $issue:expr, None),
     )+) => {
         /// Represents stable features which have since been removed (it was once Accepted)
-        pub const STABLE_REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
-            $((sym::$feature, $ver, $issue, None)),+
+        pub const STABLE_REMOVED_FEATURES: &[Feature] = &[
+            $(
+                Feature {
+                    state: State::Stabilized { reason: None },
+                    name: sym::$feature,
+                    since: $ver,
+                    issue: $issue,
+                    edition: None,
+                    description: concat!($($doc,)*),
+                }
+            ),+
         ];
     };
 }