1+ use std:: cell:: RefMut ;
2+
13use Determinacy :: * ;
24use Namespace :: * ;
35use rustc_ast:: { self as ast, NodeId } ;
@@ -13,7 +15,7 @@ use rustc_span::{Ident, Span, kw, sym};
1315use tracing:: { debug, instrument} ;
1416
1517use crate :: errors:: { ParamKindInEnumDiscriminant , ParamKindInNonTrivialAnonConst } ;
16- use crate :: imports:: Import ;
18+ use crate :: imports:: { Import , NameResolution } ;
1719use crate :: late:: { ConstantHasGenerics , NoConstantGenericsReason , PathSource , Rib , RibKind } ;
1820use crate :: macros:: { MacroRulesScope , sub_namespace_match} ;
1921use crate :: {
@@ -37,7 +39,7 @@ impl From<UsePrelude> for bool {
3739 }
3840}
3941
40- #[ derive( Debug , PartialEq ) ]
42+ #[ derive( Debug , PartialEq , Clone , Copy ) ]
4143enum Shadowing {
4244 Restricted ,
4345 Unrestricted ,
@@ -879,53 +881,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
879881 . into_iter ( )
880882 . find_map ( |binding| if binding == ignore_binding { None } else { binding } ) ;
881883
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) ;
884+ if let Some ( finalize) = finalize {
885+ return self . finalize_module_binding (
886+ ident,
887+ binding,
888+ resolution. shadowed_glob ,
889+ parent_scope,
890+ finalize,
891+ shadowing,
892+ ) ;
929893 }
930894
931895 let check_usable = |this : & mut Self , binding : NameBinding < ' ra > | {
@@ -944,75 +908,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
944908
945909 // Check if one of single imports can still define the name,
946910 // 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- }
911+ if self . single_import_can_define_name (
912+ & resolution,
913+ binding,
914+ ns,
915+ ignore_import,
916+ ignore_binding,
917+ parent_scope,
918+ ) {
919+ return Err ( ( Undetermined , Weak :: No ) ) ;
1016920 }
1017921
1018922 // So we have a resolution that's from a glob import. This resolution is determined
@@ -1101,6 +1005,129 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
11011005 Err ( ( Determined , Weak :: No ) )
11021006 }
11031007
1008+ fn finalize_module_binding (
1009+ & mut self ,
1010+ ident : Ident ,
1011+ binding : Option < NameBinding < ' ra > > ,
1012+ shadowed_glob : Option < NameBinding < ' ra > > ,
1013+ parent_scope : & ParentScope < ' ra > ,
1014+ finalize : Finalize ,
1015+ shadowing : Shadowing ,
1016+ ) -> Result < NameBinding < ' ra > , ( Determinacy , Weak ) > {
1017+ let Finalize { path_span, report_private, used, root_span, .. } = finalize;
1018+
1019+ let Some ( binding) = binding else {
1020+ return Err ( ( Determined , Weak :: No ) ) ;
1021+ } ;
1022+
1023+ if !self . is_accessible_from ( binding. vis , parent_scope. module ) {
1024+ if report_private {
1025+ self . privacy_errors . push ( PrivacyError {
1026+ ident,
1027+ binding,
1028+ dedup_span : path_span,
1029+ outermost_res : None ,
1030+ parent_scope : * parent_scope,
1031+ single_nested : path_span != root_span,
1032+ } ) ;
1033+ } else {
1034+ return Err ( ( Determined , Weak :: No ) ) ;
1035+ }
1036+ }
1037+
1038+ // Forbid expanded shadowing to avoid time travel.
1039+ if let Some ( shadowed_glob) = shadowed_glob
1040+ && shadowing == Shadowing :: Restricted
1041+ && binding. expansion != LocalExpnId :: ROOT
1042+ && binding. res ( ) != shadowed_glob. res ( )
1043+ {
1044+ self . ambiguity_errors . push ( AmbiguityError {
1045+ kind : AmbiguityKind :: GlobVsExpanded ,
1046+ ident,
1047+ b1 : binding,
1048+ b2 : shadowed_glob,
1049+ warning : false ,
1050+ misc1 : AmbiguityErrorMisc :: None ,
1051+ misc2 : AmbiguityErrorMisc :: None ,
1052+ } ) ;
1053+ }
1054+
1055+ if shadowing == Shadowing :: Unrestricted
1056+ && binding. expansion != LocalExpnId :: ROOT
1057+ && let NameBindingKind :: Import { import, .. } = binding. kind
1058+ && matches ! ( import. kind, ImportKind :: MacroExport )
1059+ {
1060+ self . macro_expanded_macro_export_errors . insert ( ( path_span, binding. span ) ) ;
1061+ }
1062+
1063+ self . record_use ( ident, binding, used) ;
1064+ return Ok ( binding) ;
1065+ }
1066+
1067+ // Checks if a single import can define the `Ident` corresponding to `binding`.
1068+ // This is used to check whether we can definitively accept a glob as a resolution.
1069+ fn single_import_can_define_name (
1070+ & mut self ,
1071+ resolution : & RefMut < ' _ , NameResolution < ' ra > > ,
1072+ binding : Option < NameBinding < ' ra > > ,
1073+ ns : Namespace ,
1074+ ignore_import : Option < Import < ' ra > > ,
1075+ ignore_binding : Option < NameBinding < ' ra > > ,
1076+ parent_scope : & ParentScope < ' ra > ,
1077+ ) -> bool {
1078+ for single_import in & resolution. single_imports {
1079+ if ignore_import == Some ( * single_import) {
1080+ continue ;
1081+ }
1082+ if !self . is_accessible_from ( single_import. vis , parent_scope. module ) {
1083+ continue ;
1084+ }
1085+ if let Some ( ignored) = ignore_binding
1086+ && let NameBindingKind :: Import { import, .. } = ignored. kind
1087+ && import == * single_import
1088+ {
1089+ continue ;
1090+ }
1091+
1092+ let Some ( module) = single_import. imported_module . get ( ) else {
1093+ return true ;
1094+ } ;
1095+ let ImportKind :: Single { source, target, target_bindings, .. } = & single_import. kind
1096+ else {
1097+ unreachable ! ( ) ;
1098+ } ;
1099+ if source != target {
1100+ if target_bindings. iter ( ) . all ( |binding| binding. get ( ) . is_none ( ) ) {
1101+ return true ;
1102+ } else if target_bindings[ ns] . get ( ) . is_none ( ) && binding. is_some ( ) {
1103+ return true ;
1104+ }
1105+ }
1106+
1107+ match self . resolve_ident_in_module (
1108+ module,
1109+ * source,
1110+ ns,
1111+ & single_import. parent_scope ,
1112+ None ,
1113+ ignore_binding,
1114+ ignore_import,
1115+ ) {
1116+ Err ( ( Determined , _) ) => continue ,
1117+ Ok ( binding)
1118+ if !self . is_accessible_from ( binding. vis , single_import. parent_scope . module ) =>
1119+ {
1120+ continue ;
1121+ }
1122+ Ok ( _) | Err ( ( Undetermined , _) ) => {
1123+ return true ;
1124+ }
1125+ }
1126+ }
1127+
1128+ false
1129+ }
1130+
11041131 /// Validate a local resolution (from ribs).
11051132 #[ instrument( level = "debug" , skip( self , all_ribs) ) ]
11061133 fn validate_res_from_ribs (
0 commit comments