@@ -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.
@@ -858,14 +852,32 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
858852 // This returns true if we should consider the underlying `extern crate` to be used.
859853 fn process_legacy_macro_imports ( & mut self , item : & Item , module : Module < ' a > ,
860854 parent_scope : & ParentScope < ' a > ) -> bool {
861- let allow_shadowing = parent_scope. expansion == Mark :: root ( ) ;
862- let legacy_imports = self . legacy_macro_imports ( & item. attrs ) ;
863- let used = legacy_imports != LegacyMacroImports :: default ( ) ;
864-
865- // `#[macro_use]` is only allowed at the crate root.
866- if self . current_module . parent . is_some ( ) && used {
867- span_err ! ( self . session, item. span, E0468 ,
868- "an `extern crate` loading macros must be at the crate root" ) ;
855+ let mut import_all = None ;
856+ let mut single_imports = Vec :: new ( ) ;
857+ for attr in & item. attrs {
858+ if attr. check_name ( "macro_use" ) {
859+ if self . current_module . parent . is_some ( ) {
860+ span_err ! ( self . session, item. span, E0468 ,
861+ "an `extern crate` loading macros must be at the crate root" ) ;
862+ }
863+ let ill_formed = |span| span_err ! ( self . session, span, E0466 , "bad macro import" ) ;
864+ match attr. meta ( ) {
865+ Some ( meta) => match meta. node {
866+ MetaItemKind :: Word => {
867+ import_all = Some ( meta. span ) ;
868+ break ;
869+ }
870+ MetaItemKind :: List ( nested_metas) => for nested_meta in nested_metas {
871+ match nested_meta. word ( ) {
872+ Some ( word) => single_imports. push ( ( word. name ( ) , word. span ) ) ,
873+ None => ill_formed ( nested_meta. span ) ,
874+ }
875+ }
876+ MetaItemKind :: NameValue ( ..) => ill_formed ( meta. span ) ,
877+ }
878+ None => ill_formed ( attr. span ( ) ) ,
879+ }
880+ }
869881 }
870882
871883 let arenas = self . arenas ;
@@ -883,15 +895,16 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
883895 is_uniform_paths_canary : false ,
884896 } ) ;
885897
886- if let Some ( span) = legacy_imports. import_all {
898+ let allow_shadowing = parent_scope. expansion == Mark :: root ( ) ;
899+ if let Some ( span) = import_all {
887900 let directive = macro_use_directive ( span) ;
888901 self . potentially_unused_imports . push ( directive) ;
889902 module. for_each_child ( |ident, ns, binding| if ns == MacroNS {
890903 let imported_binding = self . import ( binding, directive) ;
891904 self . legacy_import_macro ( ident. name , imported_binding, span, allow_shadowing) ;
892905 } ) ;
893906 } else {
894- for ( name, span) in legacy_imports . imports {
907+ for ( name, span) in single_imports . iter ( ) . cloned ( ) {
895908 let ident = Ident :: with_empty_ctxt ( name) ;
896909 let result = self . resolve_ident_in_module (
897910 ModuleOrUniformRoot :: Module ( module) ,
@@ -910,7 +923,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
910923 }
911924 }
912925 }
913- used
926+ import_all . is_some ( ) || !single_imports . is_empty ( )
914927 }
915928
916929 // does this attribute list contain "macro_use"?
@@ -936,25 +949,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
936949
937950 false
938951 }
939-
940- fn legacy_macro_imports ( & mut self , attrs : & [ ast:: Attribute ] ) -> LegacyMacroImports {
941- let mut imports = LegacyMacroImports :: default ( ) ;
942- for attr in attrs {
943- if attr. check_name ( "macro_use" ) {
944- match attr. meta_item_list ( ) {
945- Some ( names) => for attr in names {
946- if let Some ( word) = attr. word ( ) {
947- imports. imports . push ( ( word. name ( ) , attr. span ( ) ) ) ;
948- } else {
949- span_err ! ( self . session, attr. span( ) , E0466 , "bad macro import" ) ;
950- }
951- } ,
952- None => imports. import_all = Some ( attr. span ) ,
953- }
954- }
955- }
956- imports
957- }
958952}
959953
960954pub struct BuildReducedGraphVisitor < ' a , ' b : ' a , ' c : ' b > {
0 commit comments