@@ -36,7 +36,7 @@ use syntax::parse::token;
3636use syntax:: ast:: { self , Block , ForeignItem , ForeignItemKind , Item , ItemKind } ;
3737use syntax:: ast:: { Mutability , StmtKind , TraitItem , TraitItemKind } ;
3838use syntax:: ast:: { Variant , ViewPathGlob , ViewPathList , ViewPathSimple } ;
39- use syntax:: ext:: base:: { MultiItemModifier , Resolver as SyntaxResolver } ;
39+ use syntax:: ext:: base:: { SyntaxExtension , Resolver as SyntaxResolver } ;
4040use syntax:: ext:: hygiene:: Mark ;
4141use syntax:: feature_gate:: { self , emit_feature_err} ;
4242use syntax:: ext:: tt:: macro_rules;
@@ -195,33 +195,45 @@ impl<'b> Resolver<'b> {
195195 // We need to error on `#[macro_use] extern crate` when it isn't at the
196196 // crate root, because `$crate` won't work properly.
197197 let is_crate_root = self . current_module . parent . is_none ( ) ;
198+ let import_macro = |this : & mut Self , name, ext, span| {
199+ let shadowing = this. builtin_macros . insert ( name, Rc :: new ( ext) ) . is_some ( ) ;
200+ if shadowing && expansion != Mark :: root ( ) {
201+ let msg = format ! ( "`{}` is already in scope" , name) ;
202+ this. session . struct_span_err ( span, & msg)
203+ . note ( "macro-expanded `#[macro_use]`s may not shadow \
204+ existing macros (see RFC 1560)")
205+ . emit ( ) ;
206+ }
207+ } ;
208+
209+ let mut custom_derive_crate = false ;
198210 for loaded_macro in self . crate_loader . load_macros ( item, is_crate_root) {
199211 match loaded_macro. kind {
200212 LoadedMacroKind :: Def ( mut def) => {
201- let name = def. ident . name ;
202213 if def. use_locally {
203- let ext =
204- Rc :: new ( macro_rules:: compile ( & self . session . parse_sess , & def) ) ;
205- if self . builtin_macros . insert ( name, ext) . is_some ( ) &&
206- expansion != Mark :: root ( ) {
207- let msg = format ! ( "`{}` is already in scope" , name) ;
208- self . session . struct_span_err ( loaded_macro. import_site , & msg)
209- . note ( "macro-expanded `#[macro_use]`s may not shadow \
210- existing macros (see RFC 1560)")
211- . emit ( ) ;
212- }
213- self . macro_names . insert ( name) ;
214+ self . macro_names . insert ( def. ident . name ) ;
215+ let ext = macro_rules:: compile ( & self . session . parse_sess , & def) ;
216+ import_macro ( self , def. ident . name , ext, loaded_macro. import_site ) ;
214217 }
215218 if def. export {
216219 def. id = self . next_node_id ( ) ;
217220 self . exported_macros . push ( def) ;
218221 }
219222 }
220223 LoadedMacroKind :: CustomDerive ( name, ext) => {
221- self . insert_custom_derive ( & name, ext, item. span ) ;
224+ custom_derive_crate = true ;
225+ let ext = SyntaxExtension :: CustomDerive ( ext) ;
226+ import_macro ( self , token:: intern ( & name) , ext, loaded_macro. import_site ) ;
222227 }
223228 }
224229 }
230+
231+ if custom_derive_crate && !self . session . features . borrow ( ) . proc_macro {
232+ let issue = feature_gate:: GateIssue :: Language ;
233+ let msg = "loading custom derive macro crates is experimentally supported" ;
234+ emit_feature_err ( & self . session . parse_sess , "proc_macro" , item. span , issue, msg) ;
235+ }
236+
225237 self . crate_loader . process_item ( item, & self . definitions ) ;
226238
227239 // n.b. we don't need to look at the path option here, because cstore already did
@@ -238,6 +250,12 @@ impl<'b> Resolver<'b> {
238250 self . define ( parent, name, TypeNS , ( module, sp, vis) ) ;
239251
240252 self . populate_module_if_necessary ( module) ;
253+ } else if custom_derive_crate {
254+ // Define an empty module
255+ let def = Def :: Mod ( self . definitions . local_def_id ( item. id ) ) ;
256+ let module = ModuleS :: new ( Some ( parent) , ModuleKind :: Def ( def, name) ) ;
257+ let module = self . arenas . alloc_module ( module) ;
258+ self . define ( parent, name, TypeNS , ( module, sp, vis) ) ;
241259 }
242260 }
243261
@@ -504,17 +522,6 @@ impl<'b> Resolver<'b> {
504522
505523 false
506524 }
507-
508- fn insert_custom_derive ( & mut self , name : & str , ext : Rc < MultiItemModifier > , sp : Span ) {
509- if !self . session . features . borrow ( ) . proc_macro {
510- let sess = & self . session . parse_sess ;
511- let msg = "loading custom derive macro crates is experimentally supported" ;
512- emit_feature_err ( sess, "proc_macro" , sp, feature_gate:: GateIssue :: Language , msg) ;
513- }
514- if self . derive_modes . insert ( token:: intern ( name) , ext) . is_some ( ) {
515- self . session . span_err ( sp, & format ! ( "cannot shadow existing derive mode `{}`" , name) ) ;
516- }
517- }
518525}
519526
520527pub struct BuildReducedGraphVisitor < ' a , ' b : ' a > {
0 commit comments