@@ -35,7 +35,7 @@ use syntax::ast::{Name, Ident};
35
35
use syntax:: attr;
36
36
37
37
use 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 } ;
39
39
use syntax:: ext:: base:: { MacroKind , SyntaxExtension } ;
40
40
use syntax:: ext:: base:: Determinacy :: Undetermined ;
41
41
use syntax:: ext:: hygiene:: Mark ;
@@ -83,12 +83,6 @@ impl<'a> ToNameBinding<'a> for (Def, ty::Visibility, Span, Mark, IsMacroExport)
83
83
}
84
84
}
85
85
86
- #[ derive( Default , PartialEq , Eq ) ]
87
- struct LegacyMacroImports {
88
- import_all : Option < Span > ,
89
- imports : Vec < ( Name , Span ) > ,
90
- }
91
-
92
86
impl < ' a , ' cl > Resolver < ' a , ' cl > {
93
87
/// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
94
88
/// otherwise, reports an error.
@@ -852,14 +846,32 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
852
846
// This returns true if we should consider the underlying `extern crate` to be used.
853
847
fn process_legacy_macro_imports ( & mut self , item : & Item , module : Module < ' a > ,
854
848
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
+ }
863
875
}
864
876
865
877
let arenas = self . arenas ;
@@ -877,15 +889,16 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
877
889
is_uniform_paths_canary : false ,
878
890
} ) ;
879
891
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 {
881
894
let directive = macro_use_directive ( span) ;
882
895
self . potentially_unused_imports . push ( directive) ;
883
896
module. for_each_child ( |ident, ns, binding| if ns == MacroNS {
884
897
let imported_binding = self . import ( binding, directive) ;
885
898
self . legacy_import_macro ( ident. name , imported_binding, span, allow_shadowing) ;
886
899
} ) ;
887
900
} else {
888
- for ( name, span) in legacy_imports . imports {
901
+ for ( name, span) in single_imports . iter ( ) . cloned ( ) {
889
902
let ident = Ident :: with_empty_ctxt ( name) ;
890
903
let result = self . resolve_ident_in_module (
891
904
ModuleOrUniformRoot :: Module ( module) ,
@@ -904,7 +917,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
904
917
}
905
918
}
906
919
}
907
- used
920
+ import_all . is_some ( ) || !single_imports . is_empty ( )
908
921
}
909
922
910
923
// does this attribute list contain "macro_use"?
@@ -930,25 +943,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
930
943
931
944
false
932
945
}
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
- }
952
946
}
953
947
954
948
pub struct BuildReducedGraphVisitor < ' a , ' b : ' a , ' c : ' b > {
0 commit comments