diff options
Diffstat (limited to 'compiler/rustc_feature/src/unstable.rs')
| -rw-r--r-- | compiler/rustc_feature/src/unstable.rs | 61 |
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 |
