@@ -42,9 +42,10 @@ use std::{mem, ptr};
42
42
#[ derive( Clone , Debug ) ]
43
43
pub enum ImportDirectiveSubclass < ' a > {
44
44
SingleImport {
45
- target : Ident ,
46
45
source : Ident ,
47
- result : PerNS < Cell < Result < & ' a NameBinding < ' a > , Determinacy > > > ,
46
+ target : Ident ,
47
+ source_bindings : PerNS < Cell < Result < & ' a NameBinding < ' a > , Determinacy > > > ,
48
+ target_bindings : PerNS < Cell < Option < & ' a NameBinding < ' a > > > > ,
48
49
type_ns_only : bool ,
49
50
} ,
50
51
GlobImport {
@@ -227,14 +228,30 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
227
228
}
228
229
229
230
let check_usable = |this : & mut Self , binding : & ' a NameBinding < ' a > | {
231
+ if let Some ( blacklisted_binding) = this. blacklisted_binding {
232
+ if ptr:: eq ( binding, blacklisted_binding) {
233
+ return Err ( ( Determined , Weak :: No ) ) ;
234
+ }
235
+ }
230
236
// `extern crate` are always usable for backwards compatibility, see issue #37020,
231
237
// remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`.
232
238
let usable = this. is_accessible ( binding. vis ) || binding. is_extern_crate ( ) ;
233
239
if usable { Ok ( binding) } else { Err ( ( Determined , Weak :: No ) ) }
234
240
} ;
235
241
236
242
if record_used {
237
- return resolution. binding . ok_or ( ( Determined , Weak :: No ) ) . and_then ( |binding| {
243
+ return resolution. binding . and_then ( |binding| {
244
+ // If the primary binding is blacklisted, search further and return the shadowed
245
+ // glob binding if it exists. What we really want here is having two separate
246
+ // scopes in a module - one for non-globs and one for globs, but until that's done
247
+ // use this hack to avoid inconsistent resolution ICEs during import validation.
248
+ if let Some ( blacklisted_binding) = self . blacklisted_binding {
249
+ if ptr:: eq ( binding, blacklisted_binding) {
250
+ return resolution. shadowed_glob ;
251
+ }
252
+ }
253
+ Some ( binding)
254
+ } ) . ok_or ( ( Determined , Weak :: No ) ) . and_then ( |binding| {
238
255
if self . last_import_segment && check_usable ( self , binding) . is_err ( ) {
239
256
Err ( ( Determined , Weak :: No ) )
240
257
} else {
@@ -646,10 +663,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
646
663
if let Some ( ( span, err, note) ) = self . finalize_import ( import) {
647
664
errors = true ;
648
665
649
- if let SingleImport { source, ref result , .. } = import. subclass {
666
+ if let SingleImport { source, ref source_bindings , .. } = import. subclass {
650
667
if source. name == "self" {
651
668
// Silence `unresolved import` error if E0429 is already emitted
652
- if let Err ( Determined ) = result . value_ns . get ( ) {
669
+ if let Err ( Determined ) = source_bindings . value_ns . get ( ) {
653
670
continue ;
654
671
}
655
672
}
@@ -769,9 +786,11 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
769
786
} ;
770
787
771
788
directive. imported_module . set ( Some ( module) ) ;
772
- let ( source, target, result, type_ns_only) = match directive. subclass {
773
- SingleImport { source, target, ref result, type_ns_only } =>
774
- ( source, target, result, type_ns_only) ,
789
+ let ( source, target, source_bindings, target_bindings, type_ns_only) =
790
+ match directive. subclass {
791
+ SingleImport { source, target, ref source_bindings,
792
+ ref target_bindings, type_ns_only } =>
793
+ ( source, target, source_bindings, target_bindings, type_ns_only) ,
775
794
GlobImport { .. } => {
776
795
self . resolve_glob_import ( directive) ;
777
796
return true ;
@@ -781,7 +800,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
781
800
782
801
let mut indeterminate = false ;
783
802
self . per_ns ( |this, ns| if !type_ns_only || ns == TypeNS {
784
- if let Err ( Undetermined ) = result [ ns] . get ( ) {
803
+ if let Err ( Undetermined ) = source_bindings [ ns] . get ( ) {
785
804
// For better failure detection, pretend that the import will
786
805
// not define any names while resolving its module path.
787
806
let orig_vis = directive. vis . replace ( ty:: Visibility :: Invisible ) ;
@@ -790,13 +809,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
790
809
) ;
791
810
directive. vis . set ( orig_vis) ;
792
811
793
- result [ ns] . set ( binding) ;
812
+ source_bindings [ ns] . set ( binding) ;
794
813
} else {
795
814
return
796
815
} ;
797
816
798
817
let parent = directive. parent_scope . module ;
799
- match result [ ns] . get ( ) {
818
+ match source_bindings [ ns] . get ( ) {
800
819
Err ( Undetermined ) => indeterminate = true ,
801
820
Err ( Determined ) => {
802
821
this. update_resolution ( parent, target, ns, |_, resolution| {
@@ -814,6 +833,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
814
833
}
815
834
Ok ( binding) => {
816
835
let imported_binding = this. import ( binding, directive) ;
836
+ target_bindings[ ns] . set ( Some ( imported_binding) ) ;
817
837
let conflict = this. try_define ( parent, target, ns, imported_binding) ;
818
838
if let Err ( old_binding) = conflict {
819
839
this. report_conflict ( parent, target, ns, imported_binding, old_binding) ;
@@ -885,8 +905,9 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
885
905
PathResult :: Indeterminate | PathResult :: NonModule ( ..) => unreachable ! ( ) ,
886
906
} ;
887
907
888
- let ( ident, result, type_ns_only) = match directive. subclass {
889
- SingleImport { source, ref result, type_ns_only, .. } => ( source, result, type_ns_only) ,
908
+ let ( ident, source_bindings, target_bindings, type_ns_only) = match directive. subclass {
909
+ SingleImport { source, ref source_bindings, ref target_bindings, type_ns_only, .. } =>
910
+ ( source, source_bindings, target_bindings, type_ns_only) ,
890
911
GlobImport { is_prelude, ref max_vis } => {
891
912
if directive. module_path . len ( ) <= 1 {
892
913
// HACK(eddyb) `lint_if_path_starts_with_module` needs at least
@@ -925,17 +946,20 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
925
946
let mut all_ns_err = true ;
926
947
self . per_ns ( |this, ns| if !type_ns_only || ns == TypeNS {
927
948
let orig_vis = directive. vis . replace ( ty:: Visibility :: Invisible ) ;
949
+ let orig_blacklisted_binding =
950
+ mem:: replace ( & mut this. blacklisted_binding , target_bindings[ ns] . get ( ) ) ;
928
951
let orig_last_import_segment = mem:: replace ( & mut this. last_import_segment , true ) ;
929
952
let binding = this. resolve_ident_in_module (
930
953
module, ident, ns, Some ( & directive. parent_scope ) , true , directive. span
931
954
) ;
932
955
this. last_import_segment = orig_last_import_segment;
956
+ this. blacklisted_binding = orig_blacklisted_binding;
933
957
directive. vis . set ( orig_vis) ;
934
958
935
959
match binding {
936
960
Ok ( binding) => {
937
961
// Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
938
- let initial_def = result [ ns] . get ( ) . map ( |initial_binding| {
962
+ let initial_def = source_bindings [ ns] . get ( ) . map ( |initial_binding| {
939
963
all_ns_err = false ;
940
964
this. record_use ( ident, ns, initial_binding,
941
965
directive. module_path . is_empty ( ) ) ;
@@ -1040,7 +1064,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
1040
1064
let mut reexport_error = None ;
1041
1065
let mut any_successful_reexport = false ;
1042
1066
self . per_ns ( |this, ns| {
1043
- if let Ok ( binding) = result [ ns] . get ( ) {
1067
+ if let Ok ( binding) = source_bindings [ ns] . get ( ) {
1044
1068
let vis = directive. vis . get ( ) ;
1045
1069
if !binding. pseudo_vis ( ) . is_at_least ( vis, & * this) {
1046
1070
reexport_error = Some ( ( ns, binding) ) ;
@@ -1084,7 +1108,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
1084
1108
let mut full_path = directive. module_path . clone ( ) ;
1085
1109
full_path. push ( Segment :: from_ident ( ident) ) ;
1086
1110
self . per_ns ( |this, ns| {
1087
- if let Ok ( binding) = result [ ns] . get ( ) {
1111
+ if let Ok ( binding) = source_bindings [ ns] . get ( ) {
1088
1112
this. lint_if_path_starts_with_module (
1089
1113
directive. crate_lint ( ) ,
1090
1114
& full_path,
@@ -1098,7 +1122,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
1098
1122
// Record what this import resolves to for later uses in documentation,
1099
1123
// this may resolve to either a value or a type, but for documentation
1100
1124
// purposes it's good enough to just favor one over the other.
1101
- self . per_ns ( |this, ns| if let Some ( binding) = result [ ns] . get ( ) . ok ( ) {
1125
+ self . per_ns ( |this, ns| if let Some ( binding) = source_bindings [ ns] . get ( ) . ok ( ) {
1102
1126
let mut def = binding. def ( ) ;
1103
1127
if let Def :: Macro ( def_id, _) = def {
1104
1128
// `DefId`s from the "built-in macro crate" should not leak from resolve because
0 commit comments