@@ -42,9 +42,15 @@ use std::{mem, ptr};
42
42
#[ derive( Clone , Debug ) ]
43
43
pub enum ImportDirectiveSubclass < ' a > {
44
44
SingleImport {
45
- target : Ident ,
45
+ /// `source` in `use prefix::source as target`.
46
46
source : Ident ,
47
- result : PerNS < Cell < Result < & ' a NameBinding < ' a > , Determinacy > > > ,
47
+ /// `target` in `use prefix::source as target`.
48
+ target : Ident ,
49
+ /// Bindings to which `source` refers to.
50
+ source_bindings : PerNS < Cell < Result < & ' a NameBinding < ' a > , Determinacy > > > ,
51
+ /// Bindings introduced by `target`.
52
+ target_bindings : PerNS < Cell < Option < & ' a NameBinding < ' a > > > > ,
53
+ /// `true` for `...::{self [as target]}` imports, `false` otherwise.
48
54
type_ns_only : bool ,
49
55
} ,
50
56
GlobImport {
@@ -227,6 +233,11 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
227
233
}
228
234
229
235
let check_usable = |this : & mut Self , binding : & ' a NameBinding < ' a > | {
236
+ if let Some ( blacklisted_binding) = this. blacklisted_binding {
237
+ if ptr:: eq ( binding, blacklisted_binding) {
238
+ return Err ( ( Determined , Weak :: No ) ) ;
239
+ }
240
+ }
230
241
// `extern crate` are always usable for backwards compatibility, see issue #37020,
231
242
// remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`.
232
243
let usable = this. is_accessible ( binding. vis ) || binding. is_extern_crate ( ) ;
@@ -642,10 +653,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
642
653
if let Some ( ( span, err, note) ) = self . finalize_import ( import) {
643
654
errors = true ;
644
655
645
- if let SingleImport { source, ref result , .. } = import. subclass {
656
+ if let SingleImport { source, ref source_bindings , .. } = import. subclass {
646
657
if source. name == "self" {
647
658
// Silence `unresolved import` error if E0429 is already emitted
648
- if let Err ( Determined ) = result . value_ns . get ( ) {
659
+ if let Err ( Determined ) = source_bindings . value_ns . get ( ) {
649
660
continue ;
650
661
}
651
662
}
@@ -765,9 +776,11 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
765
776
} ;
766
777
767
778
directive. imported_module . set ( Some ( module) ) ;
768
- let ( source, target, result, type_ns_only) = match directive. subclass {
769
- SingleImport { source, target, ref result, type_ns_only } =>
770
- ( source, target, result, type_ns_only) ,
779
+ let ( source, target, source_bindings, target_bindings, type_ns_only) =
780
+ match directive. subclass {
781
+ SingleImport { source, target, ref source_bindings,
782
+ ref target_bindings, type_ns_only } =>
783
+ ( source, target, source_bindings, target_bindings, type_ns_only) ,
771
784
GlobImport { .. } => {
772
785
self . resolve_glob_import ( directive) ;
773
786
return true ;
@@ -777,7 +790,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
777
790
778
791
let mut indeterminate = false ;
779
792
self . per_ns ( |this, ns| if !type_ns_only || ns == TypeNS {
780
- if let Err ( Undetermined ) = result [ ns] . get ( ) {
793
+ if let Err ( Undetermined ) = source_bindings [ ns] . get ( ) {
781
794
// For better failure detection, pretend that the import will
782
795
// not define any names while resolving its module path.
783
796
let orig_vis = directive. vis . replace ( ty:: Visibility :: Invisible ) ;
@@ -786,13 +799,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
786
799
) ;
787
800
directive. vis . set ( orig_vis) ;
788
801
789
- result [ ns] . set ( binding) ;
802
+ source_bindings [ ns] . set ( binding) ;
790
803
} else {
791
804
return
792
805
} ;
793
806
794
807
let parent = directive. parent_scope . module ;
795
- match result [ ns] . get ( ) {
808
+ match source_bindings [ ns] . get ( ) {
796
809
Err ( Undetermined ) => indeterminate = true ,
797
810
Err ( Determined ) => {
798
811
this. update_resolution ( parent, target, ns, |_, resolution| {
@@ -810,6 +823,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
810
823
}
811
824
Ok ( binding) => {
812
825
let imported_binding = this. import ( binding, directive) ;
826
+ target_bindings[ ns] . set ( Some ( imported_binding) ) ;
813
827
let conflict = this. try_define ( parent, target, ns, imported_binding) ;
814
828
if let Err ( old_binding) = conflict {
815
829
this. report_conflict ( parent, target, ns, imported_binding, old_binding) ;
@@ -879,8 +893,11 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
879
893
PathResult :: Indeterminate | PathResult :: NonModule ( ..) => unreachable ! ( ) ,
880
894
} ;
881
895
882
- let ( ident, result, type_ns_only) = match directive. subclass {
883
- SingleImport { source, ref result, type_ns_only, .. } => ( source, result, type_ns_only) ,
896
+ let ( ident, target, source_bindings, target_bindings, type_ns_only) =
897
+ match directive. subclass {
898
+ SingleImport { source, target, ref source_bindings,
899
+ ref target_bindings, type_ns_only } =>
900
+ ( source, target, source_bindings, target_bindings, type_ns_only) ,
884
901
GlobImport { is_prelude, ref max_vis } => {
885
902
if directive. module_path . len ( ) <= 1 {
886
903
// HACK(eddyb) `lint_if_path_starts_with_module` needs at least
@@ -919,20 +936,28 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
919
936
let mut all_ns_err = true ;
920
937
self . per_ns ( |this, ns| if !type_ns_only || ns == TypeNS {
921
938
let orig_vis = directive. vis . replace ( ty:: Visibility :: Invisible ) ;
939
+ let orig_blacklisted_binding =
940
+ mem:: replace ( & mut this. blacklisted_binding , target_bindings[ ns] . get ( ) ) ;
922
941
let orig_last_import_segment = mem:: replace ( & mut this. last_import_segment , true ) ;
923
942
let binding = this. resolve_ident_in_module (
924
943
module, ident, ns, Some ( & directive. parent_scope ) , true , directive. span
925
944
) ;
926
945
this. last_import_segment = orig_last_import_segment;
946
+ this. blacklisted_binding = orig_blacklisted_binding;
927
947
directive. vis . set ( orig_vis) ;
928
948
929
949
match binding {
930
950
Ok ( binding) => {
931
951
// Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
932
- let initial_def = result [ ns] . get ( ) . map ( |initial_binding| {
952
+ let initial_def = source_bindings [ ns] . get ( ) . map ( |initial_binding| {
933
953
all_ns_err = false ;
934
- this. record_use ( ident, ns, initial_binding,
935
- directive. module_path . is_empty ( ) ) ;
954
+ if let Some ( target_binding) = target_bindings[ ns] . get ( ) {
955
+ if target. name == "_" &&
956
+ initial_binding. is_extern_crate ( ) && !initial_binding. is_import ( ) {
957
+ this. record_use ( ident, ns, target_binding,
958
+ directive. module_path . is_empty ( ) ) ;
959
+ }
960
+ }
936
961
initial_binding. def_ignoring_ambiguity ( )
937
962
} ) ;
938
963
let def = binding. def_ignoring_ambiguity ( ) ;
@@ -1034,7 +1059,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
1034
1059
let mut reexport_error = None ;
1035
1060
let mut any_successful_reexport = false ;
1036
1061
self . per_ns ( |this, ns| {
1037
- if let Ok ( binding) = result [ ns] . get ( ) {
1062
+ if let Ok ( binding) = source_bindings [ ns] . get ( ) {
1038
1063
let vis = directive. vis . get ( ) ;
1039
1064
if !binding. pseudo_vis ( ) . is_at_least ( vis, & * this) {
1040
1065
reexport_error = Some ( ( ns, binding) ) ;
@@ -1078,7 +1103,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
1078
1103
let mut full_path = directive. module_path . clone ( ) ;
1079
1104
full_path. push ( Segment :: from_ident ( ident) ) ;
1080
1105
self . per_ns ( |this, ns| {
1081
- if let Ok ( binding) = result [ ns] . get ( ) {
1106
+ if let Ok ( binding) = source_bindings [ ns] . get ( ) {
1082
1107
this. lint_if_path_starts_with_module (
1083
1108
directive. crate_lint ( ) ,
1084
1109
& full_path,
@@ -1092,7 +1117,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
1092
1117
// Record what this import resolves to for later uses in documentation,
1093
1118
// this may resolve to either a value or a type, but for documentation
1094
1119
// purposes it's good enough to just favor one over the other.
1095
- self . per_ns ( |this, ns| if let Some ( binding) = result [ ns] . get ( ) . ok ( ) {
1120
+ self . per_ns ( |this, ns| if let Some ( binding) = source_bindings [ ns] . get ( ) . ok ( ) {
1096
1121
let mut def = binding. def ( ) ;
1097
1122
if let Def :: Macro ( def_id, _) = def {
1098
1123
// `DefId`s from the "built-in macro crate" should not leak from resolve because
0 commit comments