@@ -33,7 +33,7 @@ use syntax::util::lev_distance::find_best_match_for_name;
3333use syntax_pos:: Span ;
3434
3535use std:: cell:: { Cell , RefCell } ;
36- use std:: mem;
36+ use std:: { mem, ptr } ;
3737
3838/// Contains data for specific types of import directives.
3939#[ derive( Clone , Debug ) ]
@@ -89,6 +89,8 @@ enum SingleImports<'a> {
8989 None ,
9090 /// Only the given single import can define the name in the namespace.
9191 MaybeOne ( & ' a ImportDirective < ' a > ) ,
92+ /// Only one of these two single imports can define the name in the namespace.
93+ MaybeTwo ( & ' a ImportDirective < ' a > , & ' a ImportDirective < ' a > ) ,
9294 /// At least one single import will define the name in the namespace.
9395 AtLeastOne ,
9496}
@@ -101,21 +103,28 @@ impl<'a> Default for SingleImports<'a> {
101103}
102104
103105impl < ' a > SingleImports < ' a > {
104- fn add_directive ( & mut self , directive : & ' a ImportDirective < ' a > ) {
106+ fn add_directive ( & mut self , directive : & ' a ImportDirective < ' a > , use_extern_macros : bool ) {
105107 match * self {
106108 SingleImports :: None => * self = SingleImports :: MaybeOne ( directive) ,
107- // If two single imports can define the name in the namespace, we can assume that at
108- // least one of them will define it since otherwise both would have to define only one
109- // namespace, leading to a duplicate error.
110- SingleImports :: MaybeOne ( _) => * self = SingleImports :: AtLeastOne ,
109+ SingleImports :: MaybeOne ( directive_one) => * self = if use_extern_macros {
110+ SingleImports :: MaybeTwo ( directive_one, directive)
111+ } else {
112+ SingleImports :: AtLeastOne
113+ } ,
114+ // If three single imports can define the name in the namespace, we can assume that at
115+ // least one of them will define it since otherwise we'd get duplicate errors in one of
116+ // other namespaces.
117+ SingleImports :: MaybeTwo ( ..) => * self = SingleImports :: AtLeastOne ,
111118 SingleImports :: AtLeastOne => { }
112119 } ;
113120 }
114121
115- fn directive_failed ( & mut self ) {
122+ fn directive_failed ( & mut self , dir : & ' a ImportDirective < ' a > ) {
116123 match * self {
117124 SingleImports :: None => unreachable ! ( ) ,
118125 SingleImports :: MaybeOne ( _) => * self = SingleImports :: None ,
126+ SingleImports :: MaybeTwo ( dir1, dir2) =>
127+ * self = SingleImports :: MaybeOne ( if ptr:: eq ( dir1, dir) { dir1 } else { dir2 } ) ,
119128 SingleImports :: AtLeastOne => { }
120129 }
121130 }
@@ -199,23 +208,50 @@ impl<'a> Resolver<'a> {
199208 }
200209
201210 // Check if a single import can still define the name.
211+ let resolve_single_import = |this : & mut Self , directive : & ' a ImportDirective < ' a > | {
212+ let module = match directive. imported_module . get ( ) {
213+ Some ( module) => module,
214+ None => return false ,
215+ } ;
216+ let ident = match directive. subclass {
217+ SingleImport { source, .. } => source,
218+ _ => unreachable ! ( ) ,
219+ } ;
220+ match this. resolve_ident_in_module ( module, ident, ns, false , false , path_span) {
221+ Err ( Determined ) => { }
222+ _ => return false ,
223+ }
224+ true
225+ } ;
202226 match resolution. single_imports {
203227 SingleImports :: AtLeastOne => return Err ( Undetermined ) ,
204- SingleImports :: MaybeOne ( directive) if self . is_accessible ( directive. vis . get ( ) ) => {
205- let module = match directive. imported_module . get ( ) {
206- Some ( module) => module,
207- None => return Err ( Undetermined ) ,
208- } ;
209- let ident = match directive. subclass {
210- SingleImport { source, .. } => source,
211- _ => unreachable ! ( ) ,
212- } ;
213- match self . resolve_ident_in_module ( module, ident, ns, false , false , path_span) {
214- Err ( Determined ) => { }
215- _ => return Err ( Undetermined ) ,
228+ SingleImports :: MaybeOne ( directive) => {
229+ let accessible = self . is_accessible ( directive. vis . get ( ) ) ;
230+ if accessible {
231+ if !resolve_single_import ( self , directive) {
232+ return Err ( Undetermined )
233+ }
234+ }
235+ }
236+ SingleImports :: MaybeTwo ( directive1, directive2) => {
237+ let accessible1 = self . is_accessible ( directive1. vis . get ( ) ) ;
238+ let accessible2 = self . is_accessible ( directive2. vis . get ( ) ) ;
239+ if accessible1 && accessible2 {
240+ if !resolve_single_import ( self , directive1) &&
241+ !resolve_single_import ( self , directive2) {
242+ return Err ( Undetermined )
243+ }
244+ } else if accessible1 {
245+ if !resolve_single_import ( self , directive1) {
246+ return Err ( Undetermined )
247+ }
248+ } else {
249+ if !resolve_single_import ( self , directive2) {
250+ return Err ( Undetermined )
251+ }
216252 }
217253 }
218- SingleImports :: MaybeOne ( _ ) | SingleImports :: None => { } ,
254+ SingleImports :: None => { } ,
219255 }
220256
221257 let no_unresolved_invocations =
@@ -281,7 +317,7 @@ impl<'a> Resolver<'a> {
281317 SingleImport { target, .. } => {
282318 self . per_ns ( |this, ns| {
283319 let mut resolution = this. resolution ( current_module, target, ns) . borrow_mut ( ) ;
284- resolution. single_imports . add_directive ( directive) ;
320+ resolution. single_imports . add_directive ( directive, this . use_extern_macros ) ;
285321 } ) ;
286322 }
287323 // We don't add prelude imports to the globs since they only affect lexical scopes,
@@ -575,7 +611,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
575611 Err ( Undetermined ) => indeterminate = true ,
576612 Err ( Determined ) => {
577613 this. update_resolution ( parent, target, ns, |_, resolution| {
578- resolution. single_imports . directive_failed ( )
614+ resolution. single_imports . directive_failed ( directive )
579615 } ) ;
580616 }
581617 Ok ( binding) if !binding. is_importable ( ) => {
0 commit comments