1
+ use std:: cell:: RefMut ;
2
+
1
3
use Determinacy :: * ;
2
4
use Namespace :: * ;
3
5
use rustc_ast:: { self as ast, NodeId } ;
@@ -13,7 +15,7 @@ use rustc_span::{Ident, Span, kw, sym};
13
15
use tracing:: { debug, instrument} ;
14
16
15
17
use crate :: errors:: { ParamKindInEnumDiscriminant , ParamKindInNonTrivialAnonConst } ;
16
- use crate :: imports:: Import ;
18
+ use crate :: imports:: { Import , NameResolution } ;
17
19
use crate :: late:: { ConstantHasGenerics , NoConstantGenericsReason , PathSource , Rib , RibKind } ;
18
20
use crate :: macros:: { MacroRulesScope , sub_namespace_match} ;
19
21
use crate :: {
@@ -37,7 +39,7 @@ impl From<UsePrelude> for bool {
37
39
}
38
40
}
39
41
40
- #[ derive( Debug , PartialEq ) ]
42
+ #[ derive( Debug , PartialEq , Clone , Copy ) ]
41
43
enum Shadowing {
42
44
Restricted ,
43
45
Unrestricted ,
@@ -879,53 +881,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
879
881
. into_iter ( )
880
882
. find_map ( |binding| if binding == ignore_binding { None } else { binding } ) ;
881
883
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
+ ) ;
929
893
}
930
894
931
895
let check_usable = |this : & mut Self , binding : NameBinding < ' ra > | {
@@ -944,75 +908,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
944
908
945
909
// Check if one of single imports can still define the name,
946
910
// 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 ) ) ;
1016
920
}
1017
921
1018
922
// 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> {
1101
1005
Err ( ( Determined , Weak :: No ) )
1102
1006
}
1103
1007
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
+
1104
1131
/// Validate a local resolution (from ribs).
1105
1132
#[ instrument( level = "debug" , skip( self , all_ribs) ) ]
1106
1133
fn validate_res_from_ribs (
0 commit comments