@@ -8,7 +8,7 @@ use super::{Feature, to_nonzero};
8
8
9
9
pub struct UnstableFeature {
10
10
pub feature : Feature ,
11
- pub set_enabled : fn ( & mut Features ) ,
11
+ set_enabled : fn ( & mut Features ) ,
12
12
}
13
13
14
14
#[ derive( PartialEq ) ]
@@ -54,11 +54,11 @@ macro_rules! declare_features {
54
54
#[ derive( Clone , Default , Debug ) ]
55
55
pub struct Features {
56
56
/// `#![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 >) >,
58
58
/// `#![feature]` attrs for non-language (library) features.
59
- pub enabled_lib_features: Vec <( Symbol , Span ) >,
59
+ enabled_lib_features: Vec <( Symbol , Span ) >,
60
60
/// `enabled_lang_features` + `enabled_lib_features`.
61
- pub enabled_features: FxHashSet <Symbol >,
61
+ enabled_features: FxHashSet <Symbol >,
62
62
/// State of individual features (unstable lang features only).
63
63
/// This is `true` if and only if the corresponding feature is listed in `enabled_lang_features`.
64
64
$(
@@ -70,17 +70,27 @@ macro_rules! declare_features {
70
70
impl Features {
71
71
pub fn set_enabled_lang_feature(
72
72
& mut self ,
73
- symbol : Symbol ,
73
+ name : Symbol ,
74
74
span: Span ,
75
- since: Option <Symbol >
75
+ since: Option <Symbol >,
76
+ feature: Option <& UnstableFeature >,
76
77
) {
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
+ }
79
87
}
80
88
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( ) ) ;
84
94
}
85
95
86
96
/// This is intended for hashing the set of enabled language features.
@@ -93,9 +103,36 @@ macro_rules! declare_features {
93
103
[ $( self . $feature as u8 ) ,+]
94
104
}
95
105
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
+
96
118
/// Is the given feature enabled (via `#[feature(...)]`)?
97
119
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
99
136
}
100
137
101
138
/// Some features are known to be incomplete and using them is likely to have
0 commit comments