@@ -9,7 +9,7 @@ use crate::{
99 Resolver , Segment ,
1010} ;
1111use crate :: { Finalize , Module , ModuleOrUniformRoot , ParentScope , PerNS , ScopeSet } ;
12- use crate :: { NameBinding , NameBindingKind , PathResult } ;
12+ use crate :: { NameBinding , NameBindingKind , PathResult , Res } ;
1313
1414use rustc_ast:: NodeId ;
1515use rustc_data_structures:: fx:: FxHashSet ;
@@ -34,8 +34,6 @@ use smallvec::SmallVec;
3434use std:: cell:: Cell ;
3535use std:: { mem, ptr} ;
3636
37- type Res = def:: Res < NodeId > ;
38-
3937/// Contains data for specific kinds of imports.
4038#[ derive( Clone ) ]
4139pub ( crate ) enum ImportKind < ' a > {
@@ -212,25 +210,32 @@ pub(crate) struct NameResolution<'a> {
212210 /// Single imports that may define the name in the namespace.
213211 /// Imports are arena-allocated, so it's ok to use pointers as keys.
214212 pub single_imports : FxHashSet < Interned < ' a , Import < ' a > > > ,
215- /// The least shadowable known binding for this name, or None if there are no known bindings.
216- pub binding : Option < & ' a NameBinding < ' a > > ,
217- pub shadowed_glob : Option < & ' a NameBinding < ' a > > ,
213+ non_glob_binding : Option < & ' a NameBinding < ' a > > ,
214+ glob_binding : Option < & ' a NameBinding < ' a > > ,
218215}
219216
220217impl < ' a > NameResolution < ' a > {
221- /// Returns the binding for the name if it is known or None if it not known.
222218 pub ( crate ) fn binding ( & self ) -> Option < & ' a NameBinding < ' a > > {
223- self . binding . and_then ( |binding| {
224- if !binding. is_glob_import ( ) || self . single_imports . is_empty ( ) {
225- Some ( binding)
226- } else {
227- None
228- }
219+ self . non_glob_binding ( )
220+ . or_else ( || if self . single_imports . is_empty ( ) { self . glob_binding ( ) } else { None } )
221+ }
222+
223+ pub ( crate ) fn non_glob_binding ( & self ) -> Option < & ' a NameBinding < ' a > > {
224+ self . non_glob_binding . and_then ( |binding| {
225+ assert ! ( !binding. is_glob_import( ) ) ;
226+ Some ( binding)
227+ } )
228+ }
229+
230+ pub ( crate ) fn glob_binding ( & self ) -> Option < & ' a NameBinding < ' a > > {
231+ self . glob_binding . and_then ( |binding| {
232+ assert ! ( binding. is_glob_import( ) ) ;
233+ Some ( binding)
229234 } )
230235 }
231236
232- pub ( crate ) fn add_single_import ( & mut self , import : & ' a Import < ' a > ) {
233- self . single_imports . insert ( Interned :: new_unchecked ( import ) ) ;
237+ pub ( crate ) fn available_binding ( & self ) -> Option < & ' a NameBinding < ' a > > {
238+ self . non_glob_binding ( ) . or ( self . glob_binding ( ) )
234239 }
235240}
236241
@@ -305,65 +310,41 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
305310 self . check_reserved_macro_name ( key. ident , res) ;
306311 self . set_binding_parent_module ( binding, module) ;
307312 self . update_resolution ( module, key, |this, resolution| {
308- if let Some ( old_binding) = resolution. binding {
309- if res == Res :: Err && old_binding. res ( ) != Res :: Err {
310- // Do not override real bindings with `Res::Err`s from error recovery.
311- return Ok ( ( ) ) ;
312- }
313- match ( old_binding. is_glob_import ( ) , binding. is_glob_import ( ) ) {
314- ( true , true ) => {
315- if res != old_binding. res ( ) {
316- resolution. binding = Some ( this. ambiguity (
317- AmbiguityKind :: GlobVsGlob ,
318- old_binding,
319- binding,
320- ) ) ;
321- } else if !old_binding. vis . is_at_least ( binding. vis , this. tcx ) {
322- // We are glob-importing the same item but with greater visibility.
323- resolution. binding = Some ( binding) ;
324- }
325- }
326- ( old_glob @ true , false ) | ( old_glob @ false , true ) => {
327- let ( glob_binding, nonglob_binding) =
328- if old_glob { ( old_binding, binding) } else { ( binding, old_binding) } ;
329- if glob_binding. res ( ) != nonglob_binding. res ( )
330- && key. ns == MacroNS
331- && nonglob_binding. expansion != LocalExpnId :: ROOT
332- {
333- resolution. binding = Some ( this. ambiguity (
334- AmbiguityKind :: GlobVsExpanded ,
335- nonglob_binding,
336- glob_binding,
337- ) ) ;
338- } else {
339- resolution. binding = Some ( nonglob_binding) ;
340- }
341-
342- if let Some ( old_binding) = resolution. shadowed_glob {
343- assert ! ( old_binding. is_glob_import( ) ) ;
344- if glob_binding. res ( ) != old_binding. res ( ) {
345- resolution. shadowed_glob = Some ( this. ambiguity (
346- AmbiguityKind :: GlobVsGlob ,
347- old_binding,
348- glob_binding,
349- ) ) ;
350- } else if !old_binding. vis . is_at_least ( binding. vis , this. tcx ) {
351- resolution. shadowed_glob = Some ( glob_binding) ;
352- }
353- } else {
354- resolution. shadowed_glob = Some ( glob_binding) ;
355- }
356- }
357- ( false , false ) => {
358- return Err ( old_binding) ;
359- }
313+ if let Some ( old_binding) = resolution. available_binding ( ) && res == Res :: Err && old_binding. res ( ) != Res :: Err {
314+ // Do not override real bindings with `Res::Err`s from error recovery.
315+ Ok ( ( ) )
316+ } else if binding. is_glob_import ( ) {
317+ if let Some ( old_binding) = resolution. glob_binding ( ) {
318+ if binding. res ( ) != old_binding. res ( ) {
319+ resolution. glob_binding = Some ( this. ambiguity (
320+ AmbiguityKind :: GlobVsGlob ,
321+ old_binding,
322+ binding,
323+ ) ) ;
324+ } else if !old_binding. vis . is_at_least ( binding. vis , this. tcx ) {
325+ resolution. glob_binding = Some ( binding) ;
360326 }
361327 } else {
362- resolution. binding = Some ( binding) ;
328+ resolution. glob_binding = Some ( binding) ;
363329 }
364330
331+ if let Some ( old_binding) = resolution. non_glob_binding ( ) {
332+ if binding. res ( ) != old_binding. res ( ) && key. ns == MacroNS && old_binding. expansion != LocalExpnId :: ROOT {
333+ resolution. non_glob_binding = Some ( this. ambiguity (
334+ AmbiguityKind :: GlobVsExpanded ,
335+ old_binding,
336+ binding,
337+ ) ) ;
338+ }
339+ }
365340 Ok ( ( ) )
366- } )
341+ } else if let Some ( old_binding) = resolution. non_glob_binding ( ) {
342+ Err ( old_binding)
343+ } else {
344+ resolution. non_glob_binding = Some ( binding) ;
345+ Ok ( ( ) )
346+ }
347+ } )
367348 }
368349
369350 fn ambiguity (
@@ -549,11 +530,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
549530 for ( key, resolution) in self . resolutions ( module) . borrow ( ) . iter ( ) {
550531 let resolution = resolution. borrow ( ) ;
551532
552- if let Some ( binding ) = resolution. binding {
553- if let NameBindingKind :: Import { import, .. } = binding . kind
554- && let Some ( ( amb_binding, _) ) = binding . ambiguity
555- && binding . res ( ) != Res :: Err
556- && exported_ambiguities. contains ( & Interned :: new_unchecked ( binding ) )
533+ if let Some ( glob_binding ) = resolution. glob_binding ( ) {
534+ if let NameBindingKind :: Import { import, .. } = glob_binding . kind
535+ && let Some ( ( amb_binding, _) ) = glob_binding . ambiguity
536+ && glob_binding . res ( ) != Res :: Err
537+ && exported_ambiguities. contains ( & Interned :: new_unchecked ( glob_binding ) )
557538 {
558539 self . lint_buffer . buffer_lint_with_diagnostic (
559540 AMBIGUOUS_GLOB_REEXPORTS ,
@@ -569,7 +550,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
569550 ) ;
570551 }
571552
572- if let Some ( glob_binding ) = resolution. shadowed_glob {
553+ if let Some ( binding ) = resolution. non_glob_binding ( ) {
573554 let binding_id = match binding. kind {
574555 NameBindingKind :: Res ( res) => {
575556 Some ( self . def_id_to_node_id [ res. def_id ( ) . expect_local ( ) ] )
@@ -769,9 +750,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
769750 . emit ( ) ;
770751 }
771752 let key = BindingKey :: new ( target, ns) ;
772- this. update_resolution ( parent, key, |_, resolution| {
773- resolution. single_imports . remove ( & Interned :: new_unchecked ( import) ) ;
774- } ) ;
753+ let mut resolution = this. resolution ( parent, key) . borrow_mut ( ) ;
754+ resolution. single_imports . remove ( & Interned :: new_unchecked ( import) ) ;
775755 }
776756 }
777757 }
@@ -1025,29 +1005,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
10251005 let resolutions = resolutions. as_ref ( ) . into_iter ( ) . flat_map ( |r| r. iter ( ) ) ;
10261006 let names = resolutions
10271007 . filter_map ( |( BindingKey { ident : i, .. } , resolution) | {
1008+ let resolution = resolution. borrow ( ) ;
10281009 if i. name == ident. name {
1029- return None ;
1030- } // Never suggest the same name
1031- match * resolution. borrow ( ) {
1032- NameResolution { binding : Some ( name_binding) , .. } => {
1033- match name_binding. kind {
1034- NameBindingKind :: Import { binding, .. } => {
1035- match binding. kind {
1036- // Never suggest the name that has binding error
1037- // i.e., the name that cannot be previously resolved
1038- NameBindingKind :: Res ( Res :: Err ) => None ,
1039- _ => Some ( i. name ) ,
1040- }
1010+ None
1011+ } else if let Some ( name_binding) = resolution. available_binding ( ) {
1012+ match name_binding. kind {
1013+ NameBindingKind :: Import { binding, .. } => {
1014+ match binding. kind {
1015+ // Never suggest the name that has binding error
1016+ // i.e., the name that cannot be previously resolved
1017+ NameBindingKind :: Res ( Res :: Err ) => None ,
1018+ _ => Some ( i. name ) ,
10411019 }
1042- _ => Some ( i. name ) ,
10431020 }
1021+ _ => Some ( i. name ) ,
10441022 }
1045- NameResolution { ref single_imports, .. }
1046- if single_imports. is_empty ( ) =>
1047- {
1048- None
1049- }
1050- _ => Some ( i. name ) ,
1023+ } else if resolution. single_imports . is_empty ( ) {
1024+ None
1025+ } else {
1026+ Some ( i. name )
10511027 }
10521028 } )
10531029 . collect :: < Vec < Symbol > > ( ) ;
0 commit comments