@@ -13,7 +13,7 @@ use rustc_span::{Ident, Span, kw, sym};
1313use tracing:: { debug, instrument} ;
1414
1515use crate :: errors:: { ParamKindInEnumDiscriminant , ParamKindInNonTrivialAnonConst } ;
16- use crate :: imports:: Import ;
16+ use crate :: imports:: { Import , NameResolution } ;
1717use crate :: late:: { ConstantHasGenerics , NoConstantGenericsReason , PathSource , Rib , RibKind } ;
1818use crate :: macros:: { MacroRulesScope , sub_namespace_match} ;
1919use crate :: {
@@ -37,7 +37,7 @@ impl From<UsePrelude> for bool {
3737 }
3838}
3939
40- #[ derive( Debug , PartialEq ) ]
40+ #[ derive( Debug , PartialEq , Clone , Copy ) ]
4141enum Shadowing {
4242 Restricted ,
4343 Unrestricted ,
@@ -879,53 +879,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
879879 . into_iter ( )
880880 . find_map ( |binding| if binding == ignore_binding { None } else { binding } ) ;
881881
882- if let Some ( Finalize { path_span, report_private, used, root_span, .. } ) = finalize {
883- let Some ( binding) = binding else {
884- return Err ( ( Determined , Weak :: No ) ) ;
885- } ;
886-
887- if !self . is_accessible_from ( binding. vis , parent_scope. module ) {
888- if report_private {
889- self . privacy_errors . push ( PrivacyError {
890- ident,
891- binding,
892- dedup_span : path_span,
893- outermost_res : None ,
894- parent_scope : * parent_scope,
895- single_nested : path_span != root_span,
896- } ) ;
897- } else {
898- return Err ( ( Determined , Weak :: No ) ) ;
899- }
900- }
901-
902- // Forbid expanded shadowing to avoid time travel.
903- if let Some ( shadowed_glob) = resolution. shadowed_glob
904- && shadowing == Shadowing :: Restricted
905- && binding. expansion != LocalExpnId :: ROOT
906- && binding. res ( ) != shadowed_glob. res ( )
907- {
908- self . ambiguity_errors . push ( AmbiguityError {
909- kind : AmbiguityKind :: GlobVsExpanded ,
910- ident,
911- b1 : binding,
912- b2 : shadowed_glob,
913- warning : false ,
914- misc1 : AmbiguityErrorMisc :: None ,
915- misc2 : AmbiguityErrorMisc :: None ,
916- } ) ;
917- }
918-
919- if shadowing == Shadowing :: Unrestricted
920- && binding. expansion != LocalExpnId :: ROOT
921- && let NameBindingKind :: Import { import, .. } = binding. kind
922- && matches ! ( import. kind, ImportKind :: MacroExport )
923- {
924- self . macro_expanded_macro_export_errors . insert ( ( path_span, binding. span ) ) ;
925- }
926-
927- self . record_use ( ident, binding, used) ;
928- return Ok ( binding) ;
882+ if let Some ( finalize) = finalize {
883+ return self . finalize_module_binding (
884+ ident,
885+ binding,
886+ resolution. shadowed_glob ,
887+ parent_scope,
888+ finalize,
889+ shadowing,
890+ ) ;
929891 }
930892
931893 let check_usable = |this : & mut Self , binding : NameBinding < ' ra > | {
@@ -944,75 +906,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
944906
945907 // Check if one of single imports can still define the name,
946908 // if it can then our result is not determined and can be invalidated.
947- for single_import in & resolution. single_imports {
948- if ignore_import == Some ( * single_import) {
949- // This branch handles a cycle in single imports.
950- //
951- // For example:
952- // ```
953- // use a::b;
954- // use b as a;
955- // ```
956- // 1. Record `use a::b` as the `ignore_import` and attempt to locate `a` in the
957- // current module.
958- // 2. Encounter the import `use b as a`, which is a `single_import` for `a`,
959- // and try to find `b` in the current module.
960- // 3. Re-encounter the `use a::b` import since it's a `single_import` of `b`.
961- // This leads to entering this branch.
962- continue ;
963- }
964- if !self . is_accessible_from ( single_import. vis , parent_scope. module ) {
965- continue ;
966- }
967- if let Some ( ignored) = ignore_binding
968- && let NameBindingKind :: Import { import, .. } = ignored. kind
969- && import == * single_import
970- {
971- // Ignore not just the binding itself, but if it has a shadowed_glob,
972- // ignore that, too, because this loop is supposed to only process
973- // named imports.
974- continue ;
975- }
976-
977- let Some ( module) = single_import. imported_module . get ( ) else {
978- return Err ( ( Undetermined , Weak :: No ) ) ;
979- } ;
980- let ImportKind :: Single { source, target, target_bindings, .. } = & single_import. kind
981- else {
982- unreachable ! ( ) ;
983- } ;
984- if source != target {
985- // This branch allows the binding to be defined or updated later if the target name
986- // can hide the source.
987- if target_bindings. iter ( ) . all ( |binding| binding. get ( ) . is_none ( ) ) {
988- // None of the target bindings are available, so we can't determine
989- // if this binding is correct or not.
990- // See more details in #124840
991- return Err ( ( Undetermined , Weak :: No ) ) ;
992- } else if target_bindings[ ns] . get ( ) . is_none ( ) && binding. is_some ( ) {
993- // `binding.is_some()` avoids the condition where the binding
994- // truly doesn't exist in this namespace and should return `Err(Determined)`.
995- return Err ( ( Undetermined , Weak :: No ) ) ;
996- }
997- }
998-
999- match self . resolve_ident_in_module (
1000- module,
1001- * source,
1002- ns,
1003- & single_import. parent_scope ,
1004- None ,
1005- ignore_binding,
1006- ignore_import,
1007- ) {
1008- Err ( ( Determined , _) ) => continue ,
1009- Ok ( binding)
1010- if !self . is_accessible_from ( binding. vis , single_import. parent_scope . module ) =>
1011- {
1012- continue ;
1013- }
1014- Ok ( _) | Err ( ( Undetermined , _) ) => return Err ( ( Undetermined , Weak :: No ) ) ,
1015- }
909+ if self . single_import_can_define_name (
910+ & resolution,
911+ binding,
912+ ns,
913+ ignore_import,
914+ ignore_binding,
915+ parent_scope,
916+ ) {
917+ return Err ( ( Undetermined , Weak :: No ) ) ;
1016918 }
1017919
1018920 // So we have a resolution that's from a glob import. This resolution is determined
@@ -1101,6 +1003,129 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11011003 Err ( ( Determined , Weak :: No ) )
11021004 }
11031005
1006+ fn finalize_module_binding (
1007+ & mut self ,
1008+ ident : Ident ,
1009+ binding : Option < NameBinding < ' ra > > ,
1010+ shadowed_glob : Option < NameBinding < ' ra > > ,
1011+ parent_scope : & ParentScope < ' ra > ,
1012+ finalize : Finalize ,
1013+ shadowing : Shadowing ,
1014+ ) -> Result < NameBinding < ' ra > , ( Determinacy , Weak ) > {
1015+ let Finalize { path_span, report_private, used, root_span, .. } = finalize;
1016+
1017+ let Some ( binding) = binding else {
1018+ return Err ( ( Determined , Weak :: No ) ) ;
1019+ } ;
1020+
1021+ if !self . is_accessible_from ( binding. vis , parent_scope. module ) {
1022+ if report_private {
1023+ self . privacy_errors . push ( PrivacyError {
1024+ ident,
1025+ binding,
1026+ dedup_span : path_span,
1027+ outermost_res : None ,
1028+ parent_scope : * parent_scope,
1029+ single_nested : path_span != root_span,
1030+ } ) ;
1031+ } else {
1032+ return Err ( ( Determined , Weak :: No ) ) ;
1033+ }
1034+ }
1035+
1036+ // Forbid expanded shadowing to avoid time travel.
1037+ if let Some ( shadowed_glob) = shadowed_glob
1038+ && shadowing == Shadowing :: Restricted
1039+ && binding. expansion != LocalExpnId :: ROOT
1040+ && binding. res ( ) != shadowed_glob. res ( )
1041+ {
1042+ self . ambiguity_errors . push ( AmbiguityError {
1043+ kind : AmbiguityKind :: GlobVsExpanded ,
1044+ ident,
1045+ b1 : binding,
1046+ b2 : shadowed_glob,
1047+ warning : false ,
1048+ misc1 : AmbiguityErrorMisc :: None ,
1049+ misc2 : AmbiguityErrorMisc :: None ,
1050+ } ) ;
1051+ }
1052+
1053+ if shadowing == Shadowing :: Unrestricted
1054+ && binding. expansion != LocalExpnId :: ROOT
1055+ && let NameBindingKind :: Import { import, .. } = binding. kind
1056+ && matches ! ( import. kind, ImportKind :: MacroExport )
1057+ {
1058+ self . macro_expanded_macro_export_errors . insert ( ( path_span, binding. span ) ) ;
1059+ }
1060+
1061+ self . record_use ( ident, binding, used) ;
1062+ return Ok ( binding) ;
1063+ }
1064+
1065+ // Checks if a single import can define the `Ident` corresponding to `binding`.
1066+ // This is used to check whether we can definitively accept a glob as a resolution.
1067+ fn single_import_can_define_name (
1068+ & mut self ,
1069+ resolution : & NameResolution < ' ra > ,
1070+ binding : Option < NameBinding < ' ra > > ,
1071+ ns : Namespace ,
1072+ ignore_import : Option < Import < ' ra > > ,
1073+ ignore_binding : Option < NameBinding < ' ra > > ,
1074+ parent_scope : & ParentScope < ' ra > ,
1075+ ) -> bool {
1076+ for single_import in & resolution. single_imports {
1077+ if ignore_import == Some ( * single_import) {
1078+ continue ;
1079+ }
1080+ if !self . is_accessible_from ( single_import. vis , parent_scope. module ) {
1081+ continue ;
1082+ }
1083+ if let Some ( ignored) = ignore_binding
1084+ && let NameBindingKind :: Import { import, .. } = ignored. kind
1085+ && import == * single_import
1086+ {
1087+ continue ;
1088+ }
1089+
1090+ let Some ( module) = single_import. imported_module . get ( ) else {
1091+ return true ;
1092+ } ;
1093+ let ImportKind :: Single { source, target, target_bindings, .. } = & single_import. kind
1094+ else {
1095+ unreachable ! ( ) ;
1096+ } ;
1097+ if source != target {
1098+ if target_bindings. iter ( ) . all ( |binding| binding. get ( ) . is_none ( ) ) {
1099+ return true ;
1100+ } else if target_bindings[ ns] . get ( ) . is_none ( ) && binding. is_some ( ) {
1101+ return true ;
1102+ }
1103+ }
1104+
1105+ match self . resolve_ident_in_module (
1106+ module,
1107+ * source,
1108+ ns,
1109+ & single_import. parent_scope ,
1110+ None ,
1111+ ignore_binding,
1112+ ignore_import,
1113+ ) {
1114+ Err ( ( Determined , _) ) => continue ,
1115+ Ok ( binding)
1116+ if !self . is_accessible_from ( binding. vis , single_import. parent_scope . module ) =>
1117+ {
1118+ continue ;
1119+ }
1120+ Ok ( _) | Err ( ( Undetermined , _) ) => {
1121+ return true ;
1122+ }
1123+ }
1124+ }
1125+
1126+ false
1127+ }
1128+
11041129 /// Validate a local resolution (from ribs).
11051130 #[ instrument( level = "debug" , skip( self , all_ribs) ) ]
11061131 fn validate_res_from_ribs (
0 commit comments