@@ -4,10 +4,10 @@ use crate::diagnostics::Suggestion;
44use crate :: Determinacy :: { self , * } ;
55use crate :: Namespace :: { self , MacroNS , TypeNS } ;
66use crate :: { module_to_string, names_to_string} ;
7+ use crate :: { AllowResolveBlocks , BindingKey , ModuleKind , ResolutionError , Resolver , Segment } ;
78use crate :: { AmbiguityError , AmbiguityErrorMisc , AmbiguityKind } ;
8- use crate :: { BindingKey , ModuleKind , ResolutionError , Resolver , Segment } ;
99use 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 } ;
1111
1212use rustc_ast:: unwrap_or;
1313use rustc_ast:: NodeId ;
@@ -777,13 +777,15 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
777777 // For better failure detection, pretend that the import will
778778 // not define any names while resolving its module path.
779779 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 (
781781 & import. module_path ,
782782 None ,
783783 & import. parent_scope ,
784784 false ,
785785 import. span ,
786786 import. crate_lint ( ) ,
787+ None ,
788+ AllowResolveBlocks :: Yes ,
787789 ) ;
788790 import. vis . set ( orig_vis) ;
789791
@@ -818,16 +820,37 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
818820 // For better failure detection, pretend that the import will
819821 // not define any names while resolving its module path.
820822 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 (
822824 module,
823825 source,
824826 ns,
825827 & import. parent_scope ,
826828 false ,
827829 import. span ,
828830 ) ;
829- import. vis . set ( orig_vis) ;
830831
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) ;
831854 source_bindings[ ns] . set ( binding) ;
832855 } else {
833856 return ;
@@ -878,13 +901,15 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
878901 _ => None ,
879902 } ;
880903 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 (
882905 & import. module_path ,
883906 None ,
884907 & import. parent_scope ,
885908 true ,
886909 import. span ,
887910 import. crate_lint ( ) ,
911+ None ,
912+ AllowResolveBlocks :: Yes ,
888913 ) ;
889914 let no_ambiguity = self . r . ambiguity_errors . len ( ) == prev_ambiguity_errors_len;
890915 if let Some ( orig_unusable_binding) = orig_unusable_binding {
@@ -1010,14 +1035,36 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
10101035 let orig_unusable_binding =
10111036 mem:: replace ( & mut this. unusable_binding , target_bindings[ ns] . get ( ) ) ;
10121037 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 (
10141039 module,
10151040 ident,
10161041 ns,
10171042 & import. parent_scope ,
10181043 true ,
10191044 import. span ,
10201045 ) ;
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+
10211068 this. last_import_segment = orig_last_import_segment;
10221069 this. unusable_binding = orig_unusable_binding;
10231070 import. vis . set ( orig_vis) ;
@@ -1323,7 +1370,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
13231370 }
13241371
13251372 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 ( ) {
13271374 ModuleOrUniformRoot :: Module ( module) => module,
13281375 _ => {
13291376 self . r . session . span_err ( import. span , "cannot glob-import all possible crates" ) ;
@@ -1346,7 +1393,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
13461393
13471394 // Ensure that `resolutions` isn't borrowed during `try_define`,
13481395 // since it might get updated via a glob cycle.
1349- let bindings = self
1396+ let mut bindings = self
13501397 . r
13511398 . resolutions ( module)
13521399 . borrow ( )
@@ -1355,6 +1402,53 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
13551402 resolution. borrow ( ) . binding ( ) . map ( |binding| ( * key, binding) )
13561403 } )
13571404 . 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+
13581452 for ( mut key, binding) in bindings {
13591453 let scope = match key. ident . span . reverse_glob_adjust ( module. expansion , import. span ) {
13601454 Some ( Some ( def) ) => self . r . macro_def_scope ( def) ,
0 commit comments