@@ -17,16 +17,14 @@ use rustc::hir::def_id::{DefId, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefIndex}
17
17
use rustc:: hir:: def:: { Def , Export } ;
18
18
use rustc:: hir:: map:: { self , DefCollector } ;
19
19
use rustc:: ty;
20
- use std:: cell:: Cell ;
21
- use std:: rc:: Rc ;
22
20
use syntax:: ast:: { self , Name , Ident } ;
23
- use syntax:: attr;
21
+ use syntax:: attr:: { self , HasAttrs } ;
24
22
use syntax:: errors:: DiagnosticBuilder ;
25
- use syntax:: ext:: base:: { self , Determinacy , MultiModifier , MultiDecorator } ;
26
- use syntax:: ext:: base:: { Resolver as SyntaxResolver , SyntaxExtension } ;
27
- use syntax:: ext:: base:: MacroKind ;
28
- use syntax:: ext:: expand:: Expansion ;
23
+ use syntax:: ext:: base:: { self , Annotatable , Determinacy , MultiModifier , MultiDecorator } ;
24
+ use syntax:: ext:: base:: { MacroKind , SyntaxExtension , Resolver as SyntaxResolver } ;
25
+ use syntax:: ext:: expand:: { Expansion , ExpansionKind , Invocation , InvocationKind , find_attr_invoc} ;
29
26
use syntax:: ext:: hygiene:: Mark ;
27
+ use syntax:: ext:: placeholders:: placeholder;
30
28
use syntax:: ext:: tt:: macro_rules;
31
29
use syntax:: feature_gate:: { self , emit_feature_err, GateIssue } ;
32
30
use syntax:: fold:: { self , Folder } ;
@@ -35,6 +33,10 @@ use syntax::symbol::{Symbol, keywords};
35
33
use syntax:: util:: lev_distance:: find_best_match_for_name;
36
34
use syntax_pos:: { Span , DUMMY_SP } ;
37
35
36
+ use std:: cell:: Cell ;
37
+ use std:: mem;
38
+ use std:: rc:: Rc ;
39
+
38
40
#[ derive( Clone ) ]
39
41
pub struct InvocationData < ' a > {
40
42
pub module : Cell < Module < ' a > > ,
@@ -235,8 +237,64 @@ impl<'a> base::Resolver for Resolver<'a> {
235
237
None
236
238
}
237
239
238
- fn resolve_macro ( & mut self , scope : Mark , path : & ast:: Path , kind : MacroKind ,
239
- force : bool ) -> Result < Rc < SyntaxExtension > , Determinacy > {
240
+ fn resolve_invoc ( & mut self , invoc : & mut Invocation , scope : Mark , force : bool )
241
+ -> Result < Option < Rc < SyntaxExtension > > , Determinacy > {
242
+ let ( attr, traits, item) = match invoc. kind {
243
+ InvocationKind :: Attr { attr : None , .. } => return Ok ( None ) ,
244
+ InvocationKind :: Attr { ref mut attr, ref traits, ref mut item } => ( attr, traits, item) ,
245
+ InvocationKind :: Bang { ref mac, .. } => {
246
+ return self . resolve_macro ( scope, & mac. node . path , MacroKind :: Bang , force) . map ( Some ) ;
247
+ }
248
+ InvocationKind :: Derive { name, span, .. } => {
249
+ let path = ast:: Path :: from_ident ( span, Ident :: with_empty_ctxt ( name) ) ;
250
+ return self . resolve_macro ( scope, & path, MacroKind :: Derive , force) . map ( Some ) ;
251
+ }
252
+ } ;
253
+
254
+ let ( attr_name, path) = {
255
+ let attr = attr. as_ref ( ) . unwrap ( ) ;
256
+ ( attr. name ( ) , ast:: Path :: from_ident ( attr. span , Ident :: with_empty_ctxt ( attr. name ( ) ) ) )
257
+ } ;
258
+
259
+ let mut determined = true ;
260
+ match self . resolve_macro ( scope, & path, MacroKind :: Attr , force) {
261
+ Ok ( ext) => return Ok ( Some ( ext) ) ,
262
+ Err ( Determinacy :: Undetermined ) => determined = false ,
263
+ Err ( Determinacy :: Determined ) if force => return Err ( Determinacy :: Determined ) ,
264
+ Err ( Determinacy :: Determined ) => { }
265
+ }
266
+
267
+ for & ( name, span) in traits {
268
+ let path = ast:: Path :: from_ident ( span, Ident :: with_empty_ctxt ( name) ) ;
269
+ match self . resolve_macro ( scope, & path, MacroKind :: Derive , force) {
270
+ Ok ( ext) => if let SyntaxExtension :: ProcMacroDerive ( _, ref inert_attrs) = * ext {
271
+ if inert_attrs. contains ( & attr_name) {
272
+ // FIXME(jseyfried) Avoid `mem::replace` here.
273
+ let dummy_item = placeholder ( ExpansionKind :: Items , ast:: DUMMY_NODE_ID )
274
+ . make_items ( ) . pop ( ) . unwrap ( ) ;
275
+ let dummy_item = Annotatable :: Item ( dummy_item) ;
276
+ * item = mem:: replace ( item, dummy_item) . map_attrs ( |mut attrs| {
277
+ let inert_attr = attr. take ( ) . unwrap ( ) ;
278
+ attr:: mark_known ( & inert_attr) ;
279
+ if self . proc_macro_enabled {
280
+ * attr = find_attr_invoc ( & mut attrs) ;
281
+ }
282
+ attrs. push ( inert_attr) ;
283
+ attrs
284
+ } ) ;
285
+ }
286
+ return Err ( Determinacy :: Undetermined ) ;
287
+ } ,
288
+ Err ( Determinacy :: Undetermined ) => determined = false ,
289
+ Err ( Determinacy :: Determined ) => { }
290
+ }
291
+ }
292
+
293
+ Err ( if determined { Determinacy :: Determined } else { Determinacy :: Undetermined } )
294
+ }
295
+
296
+ fn resolve_macro ( & mut self , scope : Mark , path : & ast:: Path , kind : MacroKind , force : bool )
297
+ -> Result < Rc < SyntaxExtension > , Determinacy > {
240
298
let ast:: Path { ref segments, span } = * path;
241
299
if segments. iter ( ) . any ( |segment| segment. parameters . is_some ( ) ) {
242
300
let kind =
0 commit comments