10
10
11
11
//! The compiler code necessary to implement the `#[derive]` extensions.
12
12
13
+ use std:: rc:: Rc ;
13
14
use syntax:: ast:: { self , MetaItem } ;
14
15
use syntax:: attr:: HasAttrs ;
15
16
use syntax:: codemap;
16
- use syntax:: ext:: base:: { Annotatable , ExtCtxt , SyntaxExtension } ;
17
+ use syntax:: ext:: base:: { Annotatable , ExtCtxt , SyntaxExtension , Resolver } ;
17
18
use syntax:: ext:: build:: AstBuilder ;
18
19
use syntax:: feature_gate;
19
20
use syntax:: ptr:: P ;
@@ -292,7 +293,10 @@ pub fn expand_derive(cx: &mut ExtCtxt,
292
293
for titem in traits. iter ( ) {
293
294
let tname = titem. word ( ) . unwrap ( ) . name ( ) ;
294
295
let name = Symbol :: intern ( & format ! ( "derive({})" , tname) ) ;
296
+ let tname_cx = ast:: Ident :: with_empty_ctxt ( titem. name ( ) . unwrap ( ) ) ;
295
297
let mitem = cx. meta_word ( titem. span , name) ;
298
+ let path = ast:: Path :: from_ident ( titem. span , tname_cx) ;
299
+ let ext = cx. resolver . resolve_macro ( cx. current_expansion . mark , & path, false ) . unwrap ( ) ;
296
300
297
301
let span = Span {
298
302
expn_id : cx. codemap ( ) . record_expansion ( codemap:: ExpnInfo {
@@ -306,11 +310,15 @@ pub fn expand_derive(cx: &mut ExtCtxt,
306
310
..titem. span
307
311
} ;
308
312
309
- let my_item = Annotatable :: Item ( item) ;
310
- expand_builtin ( & tname. as_str ( ) , cx, span, & mitem, & my_item, & mut |a| {
311
- items. push ( a) ;
312
- } ) ;
313
- item = my_item. expect_item ( ) ;
313
+ if let SyntaxExtension :: BuiltinDerive ( ref func) = * ext {
314
+ let my_item = Annotatable :: Item ( item) ;
315
+ func ( cx, span, & mitem, & my_item, & mut |a| {
316
+ items. push ( a)
317
+ } ) ;
318
+ item = my_item. expect_item ( ) ;
319
+ } else {
320
+ unreachable ! ( ) ;
321
+ }
314
322
}
315
323
316
324
items. insert ( 0 , Annotatable :: Item ( item) ) ;
@@ -326,21 +334,13 @@ macro_rules! derive_traits {
326
334
}
327
335
}
328
336
329
- fn expand_builtin( name: & str ,
330
- ecx: & mut ExtCtxt ,
331
- span: Span ,
332
- mitem: & MetaItem ,
333
- item: & Annotatable ,
334
- push: & mut FnMut ( Annotatable ) ) {
335
- match name {
336
- $(
337
- $name => {
338
- warn_if_deprecated( ecx, span, $name) ;
339
- $func( ecx, span, mitem, item, push) ;
340
- }
341
- ) *
342
- _ => panic!( "not a builtin derive mode: {}" , name) ,
343
- }
337
+ pub fn register_builtin_derives( resolver: & mut Resolver ) {
338
+ $(
339
+ resolver. add_ext(
340
+ ast:: Ident :: with_empty_ctxt( Symbol :: intern( $name) ) ,
341
+ Rc :: new( SyntaxExtension :: BuiltinDerive ( $func) )
342
+ ) ;
343
+ ) *
344
344
}
345
345
}
346
346
}
0 commit comments