about summary refs log tree commit diff
path: root/compiler/rustc_feature/src/unstable.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_feature/src/unstable.rs')
-rw-r--r--compiler/rustc_feature/src/unstable.rs61
1 files changed, 49 insertions, 12 deletions
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 166f2af2210..0f9cf34fc18 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -8,7 +8,7 @@ use super::{Feature, to_nonzero};
 
 pub struct UnstableFeature {
     pub feature: Feature,
-    pub set_enabled: fn(&mut Features),
+    set_enabled: fn(&mut Features),
 }
 
 #[derive(PartialEq)]
@@ -54,11 +54,11 @@ macro_rules! declare_features {
         #[derive(Clone, Default, Debug)]
         pub struct Features {
             /// `#![feature]` attrs for language features, for error reporting.
-            pub enabled_lang_features: Vec<(Symbol, Span, Option<Symbol>)>,
+            enabled_lang_features: Vec<(Symbol, Span, Option<Symbol>)>,
             /// `#![feature]` attrs for non-language (library) features.
-            pub enabled_lib_features: Vec<(Symbol, Span)>,
+            enabled_lib_features: Vec<(Symbol, Span)>,
             /// `enabled_lang_features` + `enabled_lib_features`.
-            pub enabled_features: FxHashSet<Symbol>,
+            enabled_features: FxHashSet<Symbol>,
             /// State of individual features (unstable lang features only).
             /// This is `true` if and only if the corresponding feature is listed in `enabled_lang_features`.
             $(
@@ -70,17 +70,27 @@ macro_rules! declare_features {
         impl Features {
             pub fn set_enabled_lang_feature(
                 &mut self,
-                symbol: Symbol,
+                name: Symbol,
                 span: Span,
-                since: Option<Symbol>
+                since: Option<Symbol>,
+                feature: Option<&UnstableFeature>,
             ) {
-                self.enabled_lang_features.push((symbol, span, since));
-                self.enabled_features.insert(symbol);
+                self.enabled_lang_features.push((name, span, since));
+                self.enabled_features.insert(name);
+                if let Some(feature) = feature {
+                    assert_eq!(feature.feature.name, name);
+                    (feature.set_enabled)(self);
+                } else {
+                    // Ensure we don't skip a `set_enabled` call.
+                    debug_assert!(UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name).is_none());
+                }
             }
 
-            pub fn set_enabled_lib_feature(&mut self, symbol: Symbol, span: Span) {
-                self.enabled_lib_features.push((symbol, span));
-                self.enabled_features.insert(symbol);
+            pub fn set_enabled_lib_feature(&mut self, name: Symbol, span: Span) {
+                self.enabled_lib_features.push((name, span));
+                self.enabled_features.insert(name);
+                // Ensure we don't skip a `set_enabled` call.
+                debug_assert!(UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name).is_none());
             }
 
             /// This is intended for hashing the set of enabled language features.
@@ -93,9 +103,36 @@ macro_rules! declare_features {
                 [$(self.$feature as u8),+]
             }
 
+            pub fn enabled_lang_features(&self) -> &Vec<(Symbol, Span, Option<Symbol>)> {
+                &self.enabled_lang_features
+            }
+
+            pub fn enabled_lib_features(&self) -> &Vec<(Symbol, Span)> {
+                &self.enabled_lib_features
+            }
+
+            pub fn enabled_features(&self) -> &FxHashSet<Symbol> {
+                &self.enabled_features
+            }
+
             /// Is the given feature enabled (via `#[feature(...)]`)?
             pub fn enabled(&self, feature: Symbol) -> bool {
-                self.enabled_features.contains(&feature)
+                let e = self.enabled_features.contains(&feature);
+                if cfg!(debug_assertions) {
+                    // Ensure this matches `self.$feature`, if that exists.
+                    let e2 = match feature {
+                        $( sym::$feature => Some(self.$feature), )*
+                        _ => None,
+                    };
+                    if let Some(e2) = e2 {
+                        assert_eq!(
+                            e, e2,
+                            "mismatch in feature state for `{feature}`: \
+                            `enabled_features` says {e} but `self.{feature}` says {e2}"
+                        );
+                    }
+                }
+                e
             }
 
             /// Some features are known to be incomplete and using them is likely to have