@@ -4,10 +4,10 @@ use crate::diagnostics::Suggestion;
4
4
use crate :: Determinacy :: { self , * } ;
5
5
use crate :: Namespace :: { self , MacroNS , TypeNS } ;
6
6
use crate :: { module_to_string, names_to_string} ;
7
+ use crate :: { AllowResolveBlocks , BindingKey , ModuleKind , ResolutionError , Resolver , Segment } ;
7
8
use crate :: { AmbiguityError , AmbiguityErrorMisc , AmbiguityKind } ;
8
- use crate :: { BindingKey , ModuleKind , ResolutionError , Resolver , Segment } ;
9
9
use crate :: { CrateLint , Module , ModuleOrUniformRoot , ParentScope , PerNS , ScopeSet , Weak } ;
10
- use crate :: { NameBinding , NameBindingKind , PathResult , PrivacyError , ToNameBinding } ;
10
+ use crate :: { ModuleData , NameBinding , NameBindingKind , PathResult , PrivacyError , ToNameBinding } ;
11
11
12
12
use rustc_ast:: unwrap_or;
13
13
use rustc_ast:: NodeId ;
@@ -777,13 +777,15 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
777
777
// For better failure detection, pretend that the import will
778
778
// not define any names while resolving its module path.
779
779
let orig_vis = import. vis . replace ( ty:: Visibility :: Invisible ) ;
780
- let path_res = self . r . resolve_path (
780
+ let path_res = self . r . resolve_path_with_ribs (
781
781
& import. module_path ,
782
782
None ,
783
783
& import. parent_scope ,
784
784
false ,
785
785
import. span ,
786
786
import. crate_lint ( ) ,
787
+ None ,
788
+ AllowResolveBlocks :: Yes ,
787
789
) ;
788
790
import. vis . set ( orig_vis) ;
789
791
@@ -818,16 +820,37 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
818
820
// For better failure detection, pretend that the import will
819
821
// not define any names while resolving its module path.
820
822
let orig_vis = import. vis . replace ( ty:: Visibility :: Invisible ) ;
821
- let binding = this. resolve_ident_in_module (
823
+ let mut binding = this. resolve_ident_in_module (
822
824
module,
823
825
source,
824
826
ns,
825
827
& import. parent_scope ,
826
828
false ,
827
829
import. span ,
828
830
) ;
829
- import. vis . set ( orig_vis) ;
830
831
832
+ let mut module = module;
833
+ while binding. is_err ( ) {
834
+ match module {
835
+ ModuleOrUniformRoot :: Module ( m @ ModuleData { parent : Some ( p) , .. } )
836
+ if m. is_block ( ) =>
837
+ {
838
+ // item not found in opaque block module; try inside module containing the block
839
+ module = ModuleOrUniformRoot :: Module ( * p) ;
840
+ binding = this. resolve_ident_in_module (
841
+ module,
842
+ source,
843
+ ns,
844
+ & import. parent_scope ,
845
+ false ,
846
+ import. span ,
847
+ ) ;
848
+ }
849
+ _ => break ,
850
+ }
851
+ }
852
+
853
+ import. vis . set ( orig_vis) ;
831
854
source_bindings[ ns] . set ( binding) ;
832
855
} else {
833
856
return ;
@@ -878,13 +901,15 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
878
901
_ => None ,
879
902
} ;
880
903
let prev_ambiguity_errors_len = self . r . ambiguity_errors . len ( ) ;
881
- let path_res = self . r . resolve_path (
904
+ let path_res = self . r . resolve_path_with_ribs (
882
905
& import. module_path ,
883
906
None ,
884
907
& import. parent_scope ,
885
908
true ,
886
909
import. span ,
887
910
import. crate_lint ( ) ,
911
+ None ,
912
+ AllowResolveBlocks :: Yes ,
888
913
) ;
889
914
let no_ambiguity = self . r . ambiguity_errors . len ( ) == prev_ambiguity_errors_len;
890
915
if let Some ( orig_unusable_binding) = orig_unusable_binding {
@@ -1010,14 +1035,36 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
1010
1035
let orig_unusable_binding =
1011
1036
mem:: replace ( & mut this. unusable_binding , target_bindings[ ns] . get ( ) ) ;
1012
1037
let orig_last_import_segment = mem:: replace ( & mut this. last_import_segment , true ) ;
1013
- let binding = this. resolve_ident_in_module (
1038
+ let mut binding = this. resolve_ident_in_module (
1014
1039
module,
1015
1040
ident,
1016
1041
ns,
1017
1042
& import. parent_scope ,
1018
1043
true ,
1019
1044
import. span ,
1020
1045
) ;
1046
+
1047
+ let mut module = module;
1048
+ while binding. is_err ( ) {
1049
+ match module {
1050
+ ModuleOrUniformRoot :: Module ( m @ ModuleData { parent : Some ( p) , .. } )
1051
+ if m. is_block ( ) =>
1052
+ {
1053
+ // item not found in opaque block module; try inside module containing the block
1054
+ module = ModuleOrUniformRoot :: Module ( * p) ;
1055
+ binding = this. resolve_ident_in_module (
1056
+ module,
1057
+ ident,
1058
+ ns,
1059
+ & import. parent_scope ,
1060
+ false ,
1061
+ import. span ,
1062
+ ) ;
1063
+ }
1064
+ _ => break ,
1065
+ }
1066
+ }
1067
+
1021
1068
this. last_import_segment = orig_last_import_segment;
1022
1069
this. unusable_binding = orig_unusable_binding;
1023
1070
import. vis . set ( orig_vis) ;
@@ -1323,7 +1370,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
1323
1370
}
1324
1371
1325
1372
fn resolve_glob_import ( & mut self , import : & ' b Import < ' b > ) {
1326
- let module = match import. imported_module . get ( ) . unwrap ( ) {
1373
+ let mut module = match import. imported_module . get ( ) . unwrap ( ) {
1327
1374
ModuleOrUniformRoot :: Module ( module) => module,
1328
1375
_ => {
1329
1376
self . r . session . span_err ( import. span , "cannot glob-import all possible crates" ) ;
@@ -1346,7 +1393,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
1346
1393
1347
1394
// Ensure that `resolutions` isn't borrowed during `try_define`,
1348
1395
// since it might get updated via a glob cycle.
1349
- let bindings = self
1396
+ let mut bindings = self
1350
1397
. r
1351
1398
. resolutions ( module)
1352
1399
. borrow ( )
@@ -1355,6 +1402,53 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
1355
1402
resolution. borrow ( ) . binding ( ) . map ( |binding| ( * key, binding) )
1356
1403
} )
1357
1404
. collect :: < Vec < _ > > ( ) ;
1405
+
1406
+ if module. is_block ( ) {
1407
+ // Glob imports should see "through" an opaque module.
1408
+ // Prefer items in the opaque module to items in the parent.
1409
+
1410
+ let mut imported_items = FxHashSet :: default ( ) ;
1411
+
1412
+ while module. is_block ( ) && module. parent . is_some ( ) {
1413
+ // import these bindings
1414
+ for ( mut key, binding) in bindings {
1415
+ let scope =
1416
+ match key. ident . span . reverse_glob_adjust ( module. expansion , import. span ) {
1417
+ Some ( Some ( def) ) => self . r . macro_def_scope ( def) ,
1418
+ Some ( None ) => import. parent_scope . module ,
1419
+ None => continue ,
1420
+ } ;
1421
+ if self . r . is_accessible_from ( binding. vis , scope) {
1422
+ let imported_binding = self . r . import ( binding, import) ;
1423
+ let _ =
1424
+ self . r . try_define ( import. parent_scope . module , key, imported_binding) ;
1425
+ imported_items. insert ( key) ;
1426
+ }
1427
+ }
1428
+
1429
+ // This was an opaque module; repeat with parent module.
1430
+ module = module. parent . unwrap ( ) ;
1431
+
1432
+ // Add to module's glob_importers
1433
+ module. glob_importers . borrow_mut ( ) . push ( import) ;
1434
+
1435
+ // Ensure that `resolutions` isn't borrowed during `try_define`,
1436
+ // since it might get updated via a glob cycle.
1437
+ bindings = self
1438
+ . r
1439
+ . resolutions ( module)
1440
+ . borrow ( )
1441
+ . iter ( )
1442
+ . filter_map ( |( key, resolution) | {
1443
+ if imported_items. contains ( key) {
1444
+ return None ;
1445
+ }
1446
+ resolution. borrow ( ) . binding ( ) . map ( |binding| ( * key, binding) )
1447
+ } )
1448
+ . collect :: < Vec < _ > > ( ) ;
1449
+ }
1450
+ }
1451
+
1358
1452
for ( mut key, binding) in bindings {
1359
1453
let scope = match key. ident . span . reverse_glob_adjust ( module. expansion , import. span ) {
1360
1454
Some ( Some ( def) ) => self . r . macro_def_scope ( def) ,
0 commit comments