@@ -24,7 +24,7 @@ use ast::NodeId;
24
24
use ast;
25
25
use attr;
26
26
use attr:: AttrMetaMethods ;
27
- use codemap:: Span ;
27
+ use codemap:: { CodeMap , Span } ;
28
28
use diagnostic:: SpanHandler ;
29
29
use visit;
30
30
use visit:: Visitor ;
@@ -127,6 +127,7 @@ impl Features {
127
127
struct Context < ' a > {
128
128
features : Vec < & ' static str > ,
129
129
span_handler : & ' a SpanHandler ,
130
+ cm : & ' a CodeMap ,
130
131
}
131
132
132
133
impl < ' a > Context < ' a > {
@@ -144,7 +145,71 @@ impl<'a> Context<'a> {
144
145
}
145
146
}
146
147
147
- impl < ' a , ' v > Visitor < ' v > for Context < ' a > {
148
+ struct MacroVisitor < ' a > {
149
+ context : & ' a Context < ' a >
150
+ }
151
+
152
+ impl < ' a , ' v > Visitor < ' v > for MacroVisitor < ' a > {
153
+ fn visit_view_item ( & mut self , i : & ast:: ViewItem ) {
154
+ match i. node {
155
+ ast:: ViewItemExternCrate ( ..) => {
156
+ for attr in i. attrs . iter ( ) {
157
+ if attr. name ( ) . get ( ) == "phase" {
158
+ self . context . gate_feature ( "phase" , attr. span ,
159
+ "compile time crate loading is \
160
+ experimental and possibly buggy") ;
161
+ }
162
+ }
163
+ } ,
164
+ _ => { }
165
+ }
166
+ visit:: walk_view_item ( self , i)
167
+ }
168
+
169
+ fn visit_mac ( & mut self , macro : & ast:: Mac ) {
170
+ let ast:: MacInvocTT ( ref path, _, _) = macro. node ;
171
+ let id = path. segments . last ( ) . unwrap ( ) . identifier ;
172
+
173
+ if id == token:: str_to_ident ( "macro_rules" ) {
174
+ self . context . gate_feature ( "macro_rules" , path. span , "macro definitions are \
175
+ not stable enough for use and are subject to change") ;
176
+ }
177
+
178
+ else if id == token:: str_to_ident ( "asm" ) {
179
+ self . context . gate_feature ( "asm" , path. span , "inline assembly is not \
180
+ stable enough for use and is subject to change") ;
181
+ }
182
+
183
+ else if id == token:: str_to_ident ( "log_syntax" ) {
184
+ self . context . gate_feature ( "log_syntax" , path. span , "`log_syntax!` is not \
185
+ stable enough for use and is subject to change") ;
186
+ }
187
+
188
+ else if id == token:: str_to_ident ( "trace_macros" ) {
189
+ self . context . gate_feature ( "trace_macros" , path. span , "`trace_macros` is not \
190
+ stable enough for use and is subject to change") ;
191
+ }
192
+
193
+ else if id == token:: str_to_ident ( "concat_idents" ) {
194
+ self . context . gate_feature ( "concat_idents" , path. span , "`concat_idents` is not \
195
+ stable enough for use and is subject to change") ;
196
+ }
197
+ }
198
+ }
199
+
200
+ struct PostExpansionVisitor < ' a > {
201
+ context : & ' a Context < ' a >
202
+ }
203
+
204
+ impl < ' a > PostExpansionVisitor < ' a > {
205
+ fn gate_feature ( & self , feature : & str , span : Span , explain : & str ) {
206
+ if !self . context . cm . span_is_internal ( span) {
207
+ self . context . gate_feature ( feature, span, explain)
208
+ }
209
+ }
210
+ }
211
+
212
+ impl < ' a , ' v > Visitor < ' v > for PostExpansionVisitor < ' a > {
148
213
fn visit_name ( & mut self , sp : Span , name : ast:: Name ) {
149
214
if !token:: get_name ( name) . get ( ) . is_ascii ( ) {
150
215
self . gate_feature ( "non_ascii_idents" , sp,
@@ -217,7 +282,7 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
217
282
}
218
283
219
284
ast:: ItemImpl ( _, _, _, _, ref items) => {
220
- if attr:: contains_name ( i. attrs . as_slice ( ) ,
285
+ if attr:: contains_name ( i. attrs [ ] ,
221
286
"unsafe_destructor" ) {
222
287
self . gate_feature ( "unsafe_destructor" ,
223
288
i. span ,
@@ -256,36 +321,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
256
321
}
257
322
}
258
323
259
- fn visit_mac ( & mut self , macro : & ast:: Mac ) {
260
- let ast:: MacInvocTT ( ref path, _, _) = macro. node ;
261
- let id = path. segments . last ( ) . unwrap ( ) . identifier ;
262
-
263
- if id == token:: str_to_ident ( "macro_rules" ) {
264
- self . gate_feature ( "macro_rules" , path. span , "macro definitions are \
265
- not stable enough for use and are subject to change") ;
266
- }
267
-
268
- else if id == token:: str_to_ident ( "asm" ) {
269
- self . gate_feature ( "asm" , path. span , "inline assembly is not \
270
- stable enough for use and is subject to change") ;
271
- }
272
-
273
- else if id == token:: str_to_ident ( "log_syntax" ) {
274
- self . gate_feature ( "log_syntax" , path. span , "`log_syntax!` is not \
275
- stable enough for use and is subject to change") ;
276
- }
277
-
278
- else if id == token:: str_to_ident ( "trace_macros" ) {
279
- self . gate_feature ( "trace_macros" , path. span , "`trace_macros` is not \
280
- stable enough for use and is subject to change") ;
281
- }
282
-
283
- else if id == token:: str_to_ident ( "concat_idents" ) {
284
- self . gate_feature ( "concat_idents" , path. span , "`concat_idents` is not \
285
- stable enough for use and is subject to change") ;
286
- }
287
- }
288
-
289
324
fn visit_foreign_item ( & mut self , i : & ast:: ForeignItem ) {
290
325
if attr:: contains_name ( i. attrs [ ] , "linkage" ) {
291
326
self . gate_feature ( "linkage" , i. span ,
@@ -371,10 +406,15 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
371
406
}
372
407
}
373
408
374
- pub fn check_crate ( span_handler : & SpanHandler , krate : & ast:: Crate ) -> ( Features , Vec < Span > ) {
409
+ fn check_crate_inner < F > ( cm : & CodeMap , span_handler : & SpanHandler , krate : & ast:: Crate ,
410
+ check : F )
411
+ -> ( Features , Vec < Span > )
412
+ where F : FnOnce ( & mut Context , & ast:: Crate )
413
+ {
375
414
let mut cx = Context {
376
415
features : Vec :: new ( ) ,
377
416
span_handler : span_handler,
417
+ cm : cm,
378
418
} ;
379
419
380
420
let mut unknown_features = Vec :: new ( ) ;
@@ -419,7 +459,7 @@ pub fn check_crate(span_handler: &SpanHandler, krate: &ast::Crate) -> (Features,
419
459
}
420
460
}
421
461
422
- visit :: walk_crate ( & mut cx, krate) ;
462
+ check ( & mut cx, krate) ;
423
463
424
464
( Features {
425
465
default_type_params : cx. has_feature ( "default_type_params" ) ,
@@ -432,3 +472,16 @@ pub fn check_crate(span_handler: &SpanHandler, krate: &ast::Crate) -> (Features,
432
472
} ,
433
473
unknown_features)
434
474
}
475
+
476
+ pub fn check_crate_macros ( cm : & CodeMap , span_handler : & SpanHandler , krate : & ast:: Crate )
477
+ -> ( Features , Vec < Span > ) {
478
+ check_crate_inner ( cm, span_handler, krate,
479
+ |ctx, krate| visit:: walk_crate ( & mut MacroVisitor { context : ctx } , krate) )
480
+ }
481
+
482
+ pub fn check_crate ( cm : & CodeMap , span_handler : & SpanHandler , krate : & ast:: Crate )
483
+ -> ( Features , Vec < Span > ) {
484
+ check_crate_inner ( cm, span_handler, krate,
485
+ |ctx, krate| visit:: walk_crate ( & mut PostExpansionVisitor { context : ctx } ,
486
+ krate) )
487
+ }
0 commit comments