1010
1111//! The compiler code necessary to implement the `#[derive]` extensions.
1212
13+ use std:: rc:: Rc ;
1314use syntax:: ast:: { self , MetaItem } ;
1415use syntax:: attr:: HasAttrs ;
1516use syntax:: codemap;
16- use syntax:: ext:: base:: { Annotatable , ExtCtxt , SyntaxExtension } ;
17+ use syntax:: ext:: base:: { Annotatable , ExtCtxt , SyntaxExtension , Resolver } ;
1718use syntax:: ext:: build:: AstBuilder ;
1819use syntax:: feature_gate;
1920use syntax:: ptr:: P ;
@@ -292,7 +293,10 @@ pub fn expand_derive(cx: &mut ExtCtxt,
292293 for titem in traits. iter ( ) {
293294 let tname = titem. word ( ) . unwrap ( ) . name ( ) ;
294295 let name = Symbol :: intern ( & format ! ( "derive({})" , tname) ) ;
296+ let tname_cx = ast:: Ident :: with_empty_ctxt ( titem. name ( ) . unwrap ( ) ) ;
295297 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 ( ) ;
296300
297301 let span = Span {
298302 expn_id : cx. codemap ( ) . record_expansion ( codemap:: ExpnInfo {
@@ -306,11 +310,15 @@ pub fn expand_derive(cx: &mut ExtCtxt,
306310 ..titem. span
307311 } ;
308312
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+ }
314322 }
315323
316324 items. insert ( 0 , Annotatable :: Item ( item) ) ;
@@ -326,21 +334,13 @@ macro_rules! derive_traits {
326334 }
327335 }
328336
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+ ) *
344344 }
345345 }
346346}
0 commit comments