@@ -42,9 +42,15 @@ use std::{mem, ptr};
4242#[ derive( Clone , Debug ) ]
4343pub enum ImportDirectiveSubclass < ' a > {
4444 SingleImport {
45- target : Ident ,
45+ /// `source` in `use prefix::source as target`.
4646 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.
4854 type_ns_only : bool ,
4955 } ,
5056 GlobImport {
@@ -227,6 +233,11 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
227233 }
228234
229235 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+ }
230241 // `extern crate` are always usable for backwards compatibility, see issue #37020,
231242 // remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`.
232243 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> {
642653 if let Some ( ( span, err, note) ) = self . finalize_import ( import) {
643654 errors = true ;
644655
645- if let SingleImport { source, ref result , .. } = import. subclass {
656+ if let SingleImport { source, ref source_bindings , .. } = import. subclass {
646657 if source. name == "self" {
647658 // 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 ( ) {
649660 continue ;
650661 }
651662 }
@@ -765,9 +776,11 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
765776 } ;
766777
767778 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) ,
771784 GlobImport { .. } => {
772785 self . resolve_glob_import ( directive) ;
773786 return true ;
@@ -777,7 +790,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
777790
778791 let mut indeterminate = false ;
779792 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 ( ) {
781794 // For better failure detection, pretend that the import will
782795 // not define any names while resolving its module path.
783796 let orig_vis = directive. vis . replace ( ty:: Visibility :: Invisible ) ;
@@ -786,13 +799,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
786799 ) ;
787800 directive. vis . set ( orig_vis) ;
788801
789- result [ ns] . set ( binding) ;
802+ source_bindings [ ns] . set ( binding) ;
790803 } else {
791804 return
792805 } ;
793806
794807 let parent = directive. parent_scope . module ;
795- match result [ ns] . get ( ) {
808+ match source_bindings [ ns] . get ( ) {
796809 Err ( Undetermined ) => indeterminate = true ,
797810 Err ( Determined ) => {
798811 this. update_resolution ( parent, target, ns, |_, resolution| {
@@ -810,6 +823,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
810823 }
811824 Ok ( binding) => {
812825 let imported_binding = this. import ( binding, directive) ;
826+ target_bindings[ ns] . set ( Some ( imported_binding) ) ;
813827 let conflict = this. try_define ( parent, target, ns, imported_binding) ;
814828 if let Err ( old_binding) = conflict {
815829 this. report_conflict ( parent, target, ns, imported_binding, old_binding) ;
@@ -879,8 +893,11 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
879893 PathResult :: Indeterminate | PathResult :: NonModule ( ..) => unreachable ! ( ) ,
880894 } ;
881895
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) ,
884901 GlobImport { is_prelude, ref max_vis } => {
885902 if directive. module_path . len ( ) <= 1 {
886903 // 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> {
919936 let mut all_ns_err = true ;
920937 self . per_ns ( |this, ns| if !type_ns_only || ns == TypeNS {
921938 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 ( ) ) ;
922941 let orig_last_import_segment = mem:: replace ( & mut this. last_import_segment , true ) ;
923942 let binding = this. resolve_ident_in_module (
924943 module, ident, ns, Some ( & directive. parent_scope ) , true , directive. span
925944 ) ;
926945 this. last_import_segment = orig_last_import_segment;
946+ this. blacklisted_binding = orig_blacklisted_binding;
927947 directive. vis . set ( orig_vis) ;
928948
929949 match binding {
930950 Ok ( binding) => {
931951 // 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| {
933953 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+ }
936961 initial_binding. def_ignoring_ambiguity ( )
937962 } ) ;
938963 let def = binding. def_ignoring_ambiguity ( ) ;
@@ -1034,7 +1059,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
10341059 let mut reexport_error = None ;
10351060 let mut any_successful_reexport = false ;
10361061 self . per_ns ( |this, ns| {
1037- if let Ok ( binding) = result [ ns] . get ( ) {
1062+ if let Ok ( binding) = source_bindings [ ns] . get ( ) {
10381063 let vis = directive. vis . get ( ) ;
10391064 if !binding. pseudo_vis ( ) . is_at_least ( vis, & * this) {
10401065 reexport_error = Some ( ( ns, binding) ) ;
@@ -1078,7 +1103,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
10781103 let mut full_path = directive. module_path . clone ( ) ;
10791104 full_path. push ( Segment :: from_ident ( ident) ) ;
10801105 self . per_ns ( |this, ns| {
1081- if let Ok ( binding) = result [ ns] . get ( ) {
1106+ if let Ok ( binding) = source_bindings [ ns] . get ( ) {
10821107 this. lint_if_path_starts_with_module (
10831108 directive. crate_lint ( ) ,
10841109 & full_path,
@@ -1092,7 +1117,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
10921117 // Record what this import resolves to for later uses in documentation,
10931118 // this may resolve to either a value or a type, but for documentation
10941119 // 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 ( ) {
10961121 let mut def = binding. def ( ) ;
10971122 if let Def :: Macro ( def_id, _) = def {
10981123 // `DefId`s from the "built-in macro crate" should not leak from resolve because
0 commit comments