@@ -9,7 +9,7 @@ use crate::{
9
9
Resolver , Segment ,
10
10
} ;
11
11
use crate :: { Finalize , Module , ModuleOrUniformRoot , ParentScope , PerNS , ScopeSet } ;
12
- use crate :: { NameBinding , NameBindingKind , PathResult } ;
12
+ use crate :: { NameBinding , NameBindingKind , PathResult , Res } ;
13
13
14
14
use rustc_ast:: NodeId ;
15
15
use rustc_data_structures:: fx:: FxHashSet ;
@@ -34,8 +34,6 @@ use smallvec::SmallVec;
34
34
use std:: cell:: Cell ;
35
35
use std:: { mem, ptr} ;
36
36
37
- type Res = def:: Res < NodeId > ;
38
-
39
37
/// Contains data for specific kinds of imports.
40
38
#[ derive( Clone ) ]
41
39
pub ( crate ) enum ImportKind < ' a > {
@@ -212,25 +210,32 @@ pub(crate) struct NameResolution<'a> {
212
210
/// Single imports that may define the name in the namespace.
213
211
/// Imports are arena-allocated, so it's ok to use pointers as keys.
214
212
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 > > ,
218
215
}
219
216
220
217
impl < ' a > NameResolution < ' a > {
221
- /// Returns the binding for the name if it is known or None if it not known.
222
218
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)
229
234
} )
230
235
}
231
236
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 ( ) )
234
239
}
235
240
}
236
241
@@ -305,65 +310,41 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
305
310
self . check_reserved_macro_name ( key. ident , res) ;
306
311
self . set_binding_parent_module ( binding, module) ;
307
312
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) ;
360
326
}
361
327
} else {
362
- resolution. binding = Some ( binding) ;
328
+ resolution. glob_binding = Some ( binding) ;
363
329
}
364
330
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
+ }
365
340
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
+ } )
367
348
}
368
349
369
350
fn ambiguity (
@@ -549,11 +530,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
549
530
for ( key, resolution) in self . resolutions ( module) . borrow ( ) . iter ( ) {
550
531
let resolution = resolution. borrow ( ) ;
551
532
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 ) )
557
538
{
558
539
self . lint_buffer . buffer_lint_with_diagnostic (
559
540
AMBIGUOUS_GLOB_REEXPORTS ,
@@ -569,7 +550,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
569
550
) ;
570
551
}
571
552
572
- if let Some ( glob_binding ) = resolution. shadowed_glob {
553
+ if let Some ( binding ) = resolution. non_glob_binding ( ) {
573
554
let binding_id = match binding. kind {
574
555
NameBindingKind :: Res ( res) => {
575
556
Some ( self . def_id_to_node_id [ res. def_id ( ) . expect_local ( ) ] )
@@ -769,9 +750,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
769
750
. emit ( ) ;
770
751
}
771
752
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) ) ;
775
755
}
776
756
}
777
757
}
@@ -1025,29 +1005,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1025
1005
let resolutions = resolutions. as_ref ( ) . into_iter ( ) . flat_map ( |r| r. iter ( ) ) ;
1026
1006
let names = resolutions
1027
1007
. filter_map ( |( BindingKey { ident : i, .. } , resolution) | {
1008
+ let resolution = resolution. borrow ( ) ;
1028
1009
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 ) ,
1041
1019
}
1042
- _ => Some ( i. name ) ,
1043
1020
}
1021
+ _ => Some ( i. name ) ,
1044
1022
}
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 )
1051
1027
}
1052
1028
} )
1053
1029
. collect :: < Vec < Symbol > > ( ) ;
0 commit comments