@@ -8,7 +8,7 @@ use super::{Feature, to_nonzero};
88
99pub struct UnstableFeature {
1010 pub feature : Feature ,
11- pub set_enabled : fn ( & mut Features ) ,
11+ set_enabled : fn ( & mut Features ) ,
1212}
1313
1414#[ derive( PartialEq ) ]
@@ -54,11 +54,11 @@ macro_rules! declare_features {
5454 #[ derive( Clone , Default , Debug ) ]
5555 pub struct Features {
5656 /// `#![feature]` attrs for language features, for error reporting.
57- pub enabled_lang_features: Vec <( Symbol , Span , Option <Symbol >) >,
57+ enabled_lang_features: Vec <( Symbol , Span , Option <Symbol >) >,
5858 /// `#![feature]` attrs for non-language (library) features.
59- pub enabled_lib_features: Vec <( Symbol , Span ) >,
59+ enabled_lib_features: Vec <( Symbol , Span ) >,
6060 /// `enabled_lang_features` + `enabled_lib_features`.
61- pub enabled_features: FxHashSet <Symbol >,
61+ enabled_features: FxHashSet <Symbol >,
6262 /// State of individual features (unstable lang features only).
6363 /// This is `true` if and only if the corresponding feature is listed in `enabled_lang_features`.
6464 $(
@@ -70,17 +70,27 @@ macro_rules! declare_features {
7070 impl Features {
7171 pub fn set_enabled_lang_feature(
7272 & mut self ,
73- symbol : Symbol ,
73+ name : Symbol ,
7474 span: Span ,
75- since: Option <Symbol >
75+ since: Option <Symbol >,
76+ feature: Option <& UnstableFeature >,
7677 ) {
77- self . enabled_lang_features. push( ( symbol, span, since) ) ;
78- self . enabled_features. insert( symbol) ;
78+ self . enabled_lang_features. push( ( name, span, since) ) ;
79+ self . enabled_features. insert( name) ;
80+ if let Some ( feature) = feature {
81+ assert_eq!( feature. feature. name, name) ;
82+ ( feature. set_enabled) ( self ) ;
83+ } else {
84+ // Ensure we don't skip a `set_enabled` call.
85+ debug_assert!( UNSTABLE_FEATURES . iter( ) . find( |f| name == f. feature. name) . is_none( ) ) ;
86+ }
7987 }
8088
81- pub fn set_enabled_lib_feature( & mut self , symbol: Symbol , span: Span ) {
82- self . enabled_lib_features. push( ( symbol, span) ) ;
83- self . enabled_features. insert( symbol) ;
89+ pub fn set_enabled_lib_feature( & mut self , name: Symbol , span: Span ) {
90+ self . enabled_lib_features. push( ( name, span) ) ;
91+ self . enabled_features. insert( name) ;
92+ // Ensure we don't skip a `set_enabled` call.
93+ debug_assert!( UNSTABLE_FEATURES . iter( ) . find( |f| name == f. feature. name) . is_none( ) ) ;
8494 }
8595
8696 /// This is intended for hashing the set of enabled language features.
@@ -93,9 +103,36 @@ macro_rules! declare_features {
93103 [ $( self . $feature as u8 ) ,+]
94104 }
95105
106+ pub fn enabled_lang_features( & self ) -> & Vec <( Symbol , Span , Option <Symbol >) > {
107+ & self . enabled_lang_features
108+ }
109+
110+ pub fn enabled_lib_features( & self ) -> & Vec <( Symbol , Span ) > {
111+ & self . enabled_lib_features
112+ }
113+
114+ pub fn enabled_features( & self ) -> & FxHashSet <Symbol > {
115+ & self . enabled_features
116+ }
117+
96118 /// Is the given feature enabled (via `#[feature(...)]`)?
97119 pub fn enabled( & self , feature: Symbol ) -> bool {
98- self . enabled_features. contains( & feature)
120+ let e = self . enabled_features. contains( & feature) ;
121+ if cfg!( debug_assertions) {
122+ // Ensure this matches `self.$feature`, if that exists.
123+ let e2 = match feature {
124+ $( sym:: $feature => Some ( self . $feature) , ) *
125+ _ => None ,
126+ } ;
127+ if let Some ( e2) = e2 {
128+ assert_eq!(
129+ e, e2,
130+ "mismatch in feature state for `{feature}`: \
131+ `enabled_features` says {e} but `self.{feature}` says {e2}"
132+ ) ;
133+ }
134+ }
135+ e
99136 }
100137
101138 /// Some features are known to be incomplete and using them is likely to have
0 commit comments