@@ -35,7 +35,7 @@ use syntax::ast::{Name, Ident};
3535use syntax:: attr;
3636
3737use syntax:: ast:: { self , Block , ForeignItem , ForeignItemKind , Item , ItemKind , NodeId } ;
38- use syntax:: ast:: { Mutability , StmtKind , TraitItem , TraitItemKind , Variant } ;
38+ use syntax:: ast:: { MetaItemKind , Mutability , StmtKind , TraitItem , TraitItemKind , Variant } ;
3939use syntax:: ext:: base:: { MacroKind , SyntaxExtension } ;
4040use syntax:: ext:: base:: Determinacy :: Undetermined ;
4141use syntax:: ext:: hygiene:: Mark ;
@@ -83,12 +83,6 @@ impl<'a> ToNameBinding<'a> for (Def, ty::Visibility, Span, Mark, IsMacroExport)
8383 }
8484}
8585
86- #[ derive( Default , PartialEq , Eq ) ]
87- struct LegacyMacroImports {
88- import_all : Option < Span > ,
89- imports : Vec < ( Name , Span ) > ,
90- }
91-
9286impl < ' a , ' cl > Resolver < ' a , ' cl > {
9387 /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
9488 /// otherwise, reports an error.
@@ -852,14 +846,32 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
852846 // This returns true if we should consider the underlying `extern crate` to be used.
853847 fn process_legacy_macro_imports ( & mut self , item : & Item , module : Module < ' a > ,
854848 parent_scope : & ParentScope < ' a > ) -> bool {
855- let allow_shadowing = parent_scope. expansion == Mark :: root ( ) ;
856- let legacy_imports = self . legacy_macro_imports ( & item. attrs ) ;
857- let used = legacy_imports != LegacyMacroImports :: default ( ) ;
858-
859- // `#[macro_use]` is only allowed at the crate root.
860- if self . current_module . parent . is_some ( ) && used {
861- span_err ! ( self . session, item. span, E0468 ,
862- "an `extern crate` loading macros must be at the crate root" ) ;
849+ let mut import_all = None ;
850+ let mut single_imports = Vec :: new ( ) ;
851+ for attr in & item. attrs {
852+ if attr. check_name ( "macro_use" ) {
853+ if self . current_module . parent . is_some ( ) {
854+ span_err ! ( self . session, item. span, E0468 ,
855+ "an `extern crate` loading macros must be at the crate root" ) ;
856+ }
857+ let ill_formed = |span| span_err ! ( self . session, span, E0466 , "bad macro import" ) ;
858+ match attr. meta ( ) {
859+ Some ( meta) => match meta. node {
860+ MetaItemKind :: Word => {
861+ import_all = Some ( meta. span ) ;
862+ break ;
863+ }
864+ MetaItemKind :: List ( nested_metas) => for nested_meta in nested_metas {
865+ match nested_meta. word ( ) {
866+ Some ( word) => single_imports. push ( ( word. name ( ) , word. span ) ) ,
867+ None => ill_formed ( nested_meta. span ) ,
868+ }
869+ }
870+ MetaItemKind :: NameValue ( ..) => ill_formed ( meta. span ) ,
871+ }
872+ None => ill_formed ( attr. span ( ) ) ,
873+ }
874+ }
863875 }
864876
865877 let arenas = self . arenas ;
@@ -877,15 +889,16 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
877889 is_uniform_paths_canary : false ,
878890 } ) ;
879891
880- if let Some ( span) = legacy_imports. import_all {
892+ let allow_shadowing = parent_scope. expansion == Mark :: root ( ) ;
893+ if let Some ( span) = import_all {
881894 let directive = macro_use_directive ( span) ;
882895 self . potentially_unused_imports . push ( directive) ;
883896 module. for_each_child ( |ident, ns, binding| if ns == MacroNS {
884897 let imported_binding = self . import ( binding, directive) ;
885898 self . legacy_import_macro ( ident. name , imported_binding, span, allow_shadowing) ;
886899 } ) ;
887900 } else {
888- for ( name, span) in legacy_imports . imports {
901+ for ( name, span) in single_imports . iter ( ) . cloned ( ) {
889902 let ident = Ident :: with_empty_ctxt ( name) ;
890903 let result = self . resolve_ident_in_module (
891904 ModuleOrUniformRoot :: Module ( module) ,
@@ -904,7 +917,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
904917 }
905918 }
906919 }
907- used
920+ import_all . is_some ( ) || !single_imports . is_empty ( )
908921 }
909922
910923 // does this attribute list contain "macro_use"?
@@ -930,25 +943,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
930943
931944 false
932945 }
933-
934- fn legacy_macro_imports ( & mut self , attrs : & [ ast:: Attribute ] ) -> LegacyMacroImports {
935- let mut imports = LegacyMacroImports :: default ( ) ;
936- for attr in attrs {
937- if attr. check_name ( "macro_use" ) {
938- match attr. meta_item_list ( ) {
939- Some ( names) => for attr in names {
940- if let Some ( word) = attr. word ( ) {
941- imports. imports . push ( ( word. name ( ) , attr. span ( ) ) ) ;
942- } else {
943- span_err ! ( self . session, attr. span( ) , E0466 , "bad macro import" ) ;
944- }
945- } ,
946- None => imports. import_all = Some ( attr. span ) ,
947- }
948- }
949- }
950- imports
951- }
952946}
953947
954948pub struct BuildReducedGraphVisitor < ' a , ' b : ' a , ' c : ' b > {
0 commit comments