@@ -32,15 +32,10 @@ pub enum Stability {
32
32
Deprecated ( & ' static str , Option < & ' static str > ) ,
33
33
}
34
34
35
- struct Context < ' a > {
36
- parse_sess : & ' a ParseSess ,
37
- features : & ' a Features ,
38
- }
39
-
40
35
macro_rules! gate_feature_fn {
41
36
( $cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $level: expr) => { {
42
37
let ( cx, has_feature, span,
43
- name, explain, level) = ( $cx, $has_feature, $span, $name, $explain, $level) ;
38
+ name, explain, level) = ( & * $cx, $has_feature, $span, $name, $explain, $level) ;
44
39
let has_feature: bool = has_feature( & $cx. features) ;
45
40
debug!( "gate_feature(feature = {:?}, span = {:?}); has? {}" , name, span, has_feature) ;
46
41
if !has_feature && !span. allows_unstable( $name) {
@@ -62,45 +57,7 @@ macro_rules! gate_feature {
62
57
}
63
58
64
59
crate fn check_attribute ( attr : & ast:: Attribute , parse_sess : & ParseSess , features : & Features ) {
65
- let cx = & Context { parse_sess, features } ;
66
- let attr_info =
67
- attr. ident ( ) . and_then ( |ident| BUILTIN_ATTRIBUTE_MAP . get ( & ident. name ) ) . map ( |a| * * a) ;
68
- // Check feature gates for built-in attributes.
69
- if let Some ( ( .., AttributeGate :: Gated ( _, name, descr, has_feature) ) ) = attr_info {
70
- gate_feature_fn ! ( cx, has_feature, attr. span, name, descr, GateStrength :: Hard ) ;
71
- }
72
- // Check input tokens for built-in and key-value attributes.
73
- match attr_info {
74
- // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
75
- Some ( ( name, _, template, _) ) if name != sym:: rustc_dummy =>
76
- check_builtin_attribute ( parse_sess, attr, name, template) ,
77
- _ => if let Some ( TokenTree :: Token ( token) ) = attr. tokens . trees ( ) . next ( ) {
78
- if token == token:: Eq {
79
- // All key-value attributes are restricted to meta-item syntax.
80
- attr. parse_meta ( parse_sess) . map_err ( |mut err| err. emit ( ) ) . ok ( ) ;
81
- }
82
- }
83
- }
84
- // Check unstable flavors of the `#[doc]` attribute.
85
- if attr. check_name ( sym:: doc) {
86
- for nested_meta in attr. meta_item_list ( ) . unwrap_or_default ( ) {
87
- macro_rules! gate_doc { ( $( $name: ident => $feature: ident) * ) => {
88
- $( if nested_meta. check_name( sym:: $name) {
89
- let msg = concat!( "`#[doc(" , stringify!( $name) , ")]` is experimental" ) ;
90
- gate_feature!( cx, $feature, attr. span, msg) ;
91
- } ) *
92
- } }
93
-
94
- gate_doc ! (
95
- include => external_doc
96
- cfg => doc_cfg
97
- masked => doc_masked
98
- spotlight => doc_spotlight
99
- alias => doc_alias
100
- keyword => doc_keyword
101
- ) ;
102
- }
103
- }
60
+ PostExpansionVisitor { parse_sess, features } . visit_attribute ( attr)
104
61
}
105
62
106
63
fn find_lang_feature_issue ( feature : Symbol ) -> Option < u32 > {
@@ -215,20 +172,21 @@ pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &str =
215
172
"unsized tuple coercion is not stable enough for use and is subject to change" ;
216
173
217
174
struct PostExpansionVisitor < ' a > {
218
- context : & ' a Context < ' a > ,
175
+ parse_sess : & ' a ParseSess ,
176
+ features : & ' a Features ,
219
177
}
220
178
221
179
macro_rules! gate_feature_post {
222
180
( $cx: expr, $feature: ident, $span: expr, $explain: expr) => { {
223
181
let ( cx, span) = ( $cx, $span) ;
224
182
if !span. allows_unstable( sym:: $feature) {
225
- gate_feature!( cx. context , $feature, span, $explain)
183
+ gate_feature!( cx, $feature, span, $explain)
226
184
}
227
185
} } ;
228
186
( $cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => { {
229
187
let ( cx, span) = ( $cx, $span) ;
230
188
if !span. allows_unstable( sym:: $feature) {
231
- gate_feature!( cx. context , $feature, span, $explain, $level)
189
+ gate_feature!( cx, $feature, span, $explain, $level)
232
190
}
233
191
} }
234
192
}
@@ -292,15 +250,52 @@ impl<'a> PostExpansionVisitor<'a> {
292
250
293
251
impl < ' a > Visitor < ' a > for PostExpansionVisitor < ' a > {
294
252
fn visit_attribute ( & mut self , attr : & ast:: Attribute ) {
295
- check_attribute ( attr, self . context . parse_sess , self . context . features ) ;
253
+ let attr_info =
254
+ attr. ident ( ) . and_then ( |ident| BUILTIN_ATTRIBUTE_MAP . get ( & ident. name ) ) . map ( |a| * * a) ;
255
+ // Check feature gates for built-in attributes.
256
+ if let Some ( ( .., AttributeGate :: Gated ( _, name, descr, has_feature) ) ) = attr_info {
257
+ gate_feature_fn ! ( self , has_feature, attr. span, name, descr, GateStrength :: Hard ) ;
258
+ }
259
+ // Check input tokens for built-in and key-value attributes.
260
+ match attr_info {
261
+ // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
262
+ Some ( ( name, _, template, _) ) if name != sym:: rustc_dummy =>
263
+ check_builtin_attribute ( self . parse_sess , attr, name, template) ,
264
+ _ => if let Some ( TokenTree :: Token ( token) ) = attr. tokens . trees ( ) . next ( ) {
265
+ if token == token:: Eq {
266
+ // All key-value attributes are restricted to meta-item syntax.
267
+ attr. parse_meta ( self . parse_sess ) . map_err ( |mut err| err. emit ( ) ) . ok ( ) ;
268
+ }
269
+ }
270
+ }
271
+ // Check unstable flavors of the `#[doc]` attribute.
272
+ if attr. check_name ( sym:: doc) {
273
+ for nested_meta in attr. meta_item_list ( ) . unwrap_or_default ( ) {
274
+ macro_rules! gate_doc { ( $( $name: ident => $feature: ident) * ) => {
275
+ $( if nested_meta. check_name( sym:: $name) {
276
+ let msg = concat!( "`#[doc(" , stringify!( $name) , ")]` is experimental" ) ;
277
+ gate_feature!( self , $feature, attr. span, msg) ;
278
+ } ) *
279
+ } }
280
+
281
+ gate_doc ! (
282
+ include => external_doc
283
+ cfg => doc_cfg
284
+ masked => doc_masked
285
+ spotlight => doc_spotlight
286
+ alias => doc_alias
287
+ keyword => doc_keyword
288
+ ) ;
289
+ }
290
+ }
296
291
}
297
292
298
293
fn visit_name ( & mut self , sp : Span , name : ast:: Name ) {
299
294
if !name. as_str ( ) . is_ascii ( ) {
300
295
gate_feature_post ! (
301
296
& self ,
302
297
non_ascii_idents,
303
- self . context . parse_sess. source_map( ) . def_span( sp) ,
298
+ self . parse_sess. source_map( ) . def_span( sp) ,
304
299
"non-ascii idents are not fully supported"
305
300
) ;
306
301
}
@@ -356,12 +351,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
356
351
}
357
352
}
358
353
359
- let has_feature = self . context . features . arbitrary_enum_discriminant ;
354
+ let has_feature = self . features . arbitrary_enum_discriminant ;
360
355
if !has_feature && !i. span . allows_unstable ( sym:: arbitrary_enum_discriminant) {
361
- Parser :: maybe_report_invalid_custom_discriminants (
362
- self . context . parse_sess ,
363
- & variants,
364
- ) ;
356
+ Parser :: maybe_report_invalid_custom_discriminants ( self . parse_sess , & variants) ;
365
357
}
366
358
}
367
359
@@ -471,7 +463,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
471
463
ast:: ExprKind :: Type ( ..) => {
472
464
// To avoid noise about type ascription in common syntax errors, only emit if it
473
465
// is the *only* error.
474
- if self . context . parse_sess . span_diagnostic . err_count ( ) == 0 {
466
+ if self . parse_sess . span_diagnostic . err_count ( ) == 0 {
475
467
gate_feature_post ! ( & self , type_ascription, e. span,
476
468
"type ascription is experimental" ) ;
477
469
}
@@ -809,13 +801,13 @@ pub fn check_crate(krate: &ast::Crate,
809
801
features : & Features ,
810
802
unstable : UnstableFeatures ) {
811
803
maybe_stage_features ( & parse_sess. span_diagnostic , krate, unstable) ;
812
- let ctx = Context { parse_sess, features } ;
804
+ let mut visitor = PostExpansionVisitor { parse_sess, features } ;
813
805
814
806
macro_rules! gate_all {
815
807
( $gate: ident, $msg: literal) => { gate_all!( $gate, $gate, $msg) ; } ;
816
808
( $spans: ident, $gate: ident, $msg: literal) => {
817
809
for span in & * parse_sess. gated_spans. $spans. borrow( ) {
818
- gate_feature!( & ctx , $gate, * span, $msg) ;
810
+ gate_feature!( & visitor , $gate, * span, $msg) ;
819
811
}
820
812
}
821
813
}
@@ -826,7 +818,7 @@ pub fn check_crate(krate: &ast::Crate,
826
818
gate_all ! ( yields, generators, "yield syntax is experimental" ) ;
827
819
gate_all ! ( or_patterns, "or-patterns syntax is experimental" ) ;
828
820
829
- visit:: walk_crate ( & mut PostExpansionVisitor { context : & ctx } , krate) ;
821
+ visit:: walk_crate ( & mut visitor , krate) ;
830
822
}
831
823
832
824
#[ derive( Clone , Copy , Hash ) ]
0 commit comments