Skip to content

Commit 2b4e34a

Browse files
committed
first attempt
1 parent 7f2065a commit 2b4e34a

File tree

2 files changed

+138
-28
lines changed

2 files changed

+138
-28
lines changed

compiler/rustc_resolve/src/ident.rs

Lines changed: 136 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use Determinacy::*;
1+
'''use Determinacy::*;
22
use Namespace::*;
33
use rustc_ast::{self as ast, NodeId};
44
use rustc_errors::ErrorGuaranteed;
@@ -110,7 +110,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
110110
};
111111
let mut scope = match ns {
112112
_ if is_absolute_path => Scope::CrateRoot,
113-
TypeNS | ValueNS => Scope::Module(module, None),
113+
TypeNS | ValueNS => Scope::NonGlob(module, None),
114114
MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
115115
};
116116
let mut ctxt = ctxt.normalize_to_macros_2_0();
@@ -138,7 +138,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
138138
true
139139
}
140140
Scope::CrateRoot => true,
141-
Scope::Module(..) => true,
141+
Scope::NonGlob(..) | Scope::Glob(..) => true,
142142
Scope::MacroUsePrelude => use_prelude || rust_2015,
143143
Scope::BuiltinAttrs => true,
144144
Scope::ExternPrelude => use_prelude || is_absolute_path,
@@ -175,7 +175,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
175175
MacroRulesScope::Invocation(invoc_id) => {
176176
Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules)
177177
}
178-
MacroRulesScope::Empty => Scope::Module(module, None),
178+
MacroRulesScope::Empty => Scope::NonGlob(module, None),
179179
},
180180
Scope::CrateRoot => match ns {
181181
TypeNS => {
@@ -184,16 +184,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
184184
}
185185
ValueNS | MacroNS => break,
186186
},
187-
Scope::Module(module, prev_lint_id) => {
187+
Scope::NonGlob(module, _) => Scope::Glob(module),
188+
Scope::Glob(module) => {
188189
use_prelude = !module.no_implicit_prelude;
189190
let derive_fallback_lint_id = match scope_set {
190191
ScopeSet::Late(.., lint_id) => lint_id,
191192
_ => None,
192193
};
193194
match self.hygienic_lexical_parent(module, &mut ctxt, derive_fallback_lint_id) {
194-
Some((parent_module, lint_id)) => {
195-
Scope::Module(parent_module, lint_id.or(prev_lint_id))
196-
}
195+
Some((parent_module, lint_id)) => Scope::NonGlob(parent_module, lint_id),
197196
None => {
198197
ctxt.adjust(ExpnId::root());
199198
match ns {
@@ -312,7 +311,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
312311
// Walk backwards up the ribs in scope.
313312
let mut module = self.graph_root;
314313
for (i, rib) in ribs.iter().enumerate().rev() {
315-
debug!("walk rib\n{:?}", rib.bindings);
314+
debug!("walk rib
315+
{:?}", rib.bindings);
316316
// Use the rib kind to determine whether we are resolving parameters
317317
// (macro 2.0 hygiene) or local variables (`macro_rules` hygiene).
318318
let rib_ident = if rib.kind.contains_params() { normalized_ident } else { ident };
@@ -344,7 +344,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
344344
_ => break,
345345
}
346346

347-
let item = self.resolve_ident_in_module_unadjusted(
347+
let item = self.resolve_ident_in_module_unadjusted_non_glob(
348348
ModuleOrUniformRoot::Module(module),
349349
ident,
350350
ns,
@@ -515,9 +515,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
515515
Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
516516
}
517517
}
518-
Scope::Module(module, derive_fallback_lint_id) => {
518+
Scope::NonGlob(module, derive_fallback_lint_id) => {
519519
let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
520-
let binding = this.resolve_ident_in_module_unadjusted(
520+
let binding = this.resolve_ident_in_module_unadjusted_non_glob(
521521
ModuleOrUniformRoot::Module(module),
522522
ident,
523523
ns,
@@ -563,6 +563,42 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
563563
Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
564564
}
565565
}
566+
Scope::Glob(module) => {
567+
let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
568+
let binding = this.resolve_ident_in_module_unadjusted_glob(
569+
ModuleOrUniformRoot::Module(module),
570+
ident,
571+
ns,
572+
adjusted_parent_scope,
573+
if matches!(scope_set, ScopeSet::Late(..)) {
574+
Shadowing::Unrestricted
575+
} else {
576+
Shadowing::Restricted
577+
},
578+
finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
579+
ignore_binding,
580+
ignore_import,
581+
);
582+
match binding {
583+
Ok(binding) => {
584+
let misc_flags = if module == this.graph_root {
585+
Flags::MISC_SUGGEST_CRATE
586+
} else if module.is_normal() {
587+
Flags::MISC_SUGGEST_SELF
588+
} else {
589+
Flags::empty()
590+
};
591+
Ok((binding, Flags::MODULE | misc_flags))
592+
}
593+
Err((Determinacy::Undetermined, Weak::No)) => {
594+
return Some(Err(Determinacy::determined(force)));
595+
}
596+
Err((Determinacy::Undetermined, Weak::Yes)) => {
597+
Err(Determinacy::Undetermined)
598+
}
599+
Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
600+
}
601+
}
566602
Scope::MacroUsePrelude => {
567603
match this.macro_use_prelude.get(&ident.name).cloned() {
568604
Some(binding) => Ok((binding, Flags::MISC_FROM_PRELUDE)),
@@ -590,7 +626,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
590626
Scope::StdLibPrelude => {
591627
let mut result = Err(Determinacy::Determined);
592628
if let Some(prelude) = this.prelude
593-
&& let Ok(binding) = this.resolve_ident_in_module_unadjusted(
629+
&& let Ok(binding) = this.resolve_ident_in_module_unadjusted_non_glob(
594630
ModuleOrUniformRoot::Module(prelude),
595631
ident,
596632
ns,
@@ -785,7 +821,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
785821
// No adjustments
786822
}
787823
}
788-
self.resolve_ident_in_module_unadjusted(
824+
self.resolve_ident_in_module_unadjusted_non_glob(
789825
module,
790826
ident,
791827
ns,
@@ -800,7 +836,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
800836
/// Attempts to resolve `ident` in namespaces `ns` of `module`.
801837
/// Invariant: if `finalize` is `Some`, expansion and import resolution must be complete.
802838
#[instrument(level = "debug", skip(self))]
803-
fn resolve_ident_in_module_unadjusted(
839+
fn resolve_ident_in_module_unadjusted_non_glob(
804840
&mut self,
805841
module: ModuleOrUniformRoot<'ra>,
806842
ident: Ident,
@@ -871,19 +907,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
871907
let resolution =
872908
self.resolution(module, key).try_borrow_mut().map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports.
873909

874-
// If the primary binding is unusable, search further and return the shadowed glob
875-
// binding if it exists. What we really want here is having two separate scopes in
876-
// a module - one for non-globs and one for globs, but until that's done use this
877-
// hack to avoid inconsistent resolution ICEs during import validation.
878-
let binding = [resolution.non_glob_binding, resolution.glob_binding]
879-
.into_iter()
880-
.find_map(|binding| if binding == ignore_binding { None } else { binding });
910+
let binding = resolution.non_glob_binding;
911+
if let Some(binding) = binding {
912+
if binding == ignore_binding {
913+
return Err((Determined, Weak::No));
914+
}
915+
}
881916

882917
if let Some(finalize) = finalize {
883918
return self.finalize_module_binding(
884919
ident,
885920
binding,
886-
if resolution.non_glob_binding.is_some() { resolution.glob_binding } else { None },
921+
resolution.glob_binding,
887922
parent_scope,
888923
finalize,
889924
shadowing,
@@ -896,9 +931,82 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
896931
};
897932

898933
// Items and single imports are not shadowable, if we have one, then it's determined.
899-
if let Some(binding) = binding
900-
&& !binding.is_glob_import()
901-
{
934+
if let Some(binding) = binding {
935+
return check_usable(self, binding);
936+
}
937+
938+
// --- From now on we have no resolution. ---
939+
940+
// Check if one of single imports can still define the name,
941+
// if it can then our result is not determined and can be invalidated.
942+
if self.single_import_can_define_name(
943+
&resolution,
944+
binding,
945+
ns,
946+
ignore_import,
947+
ignore_binding,
948+
parent_scope,
949+
) {
950+
return Err((Undetermined, Weak::No));
951+
}
952+
953+
// Check if one of unexpanded macros can still define the name,
954+
// if it can then our "no resolution" result is not determined and can be invalidated.
955+
if !module.unexpanded_invocations.borrow().is_empty() {
956+
return Err((Undetermined, Weak::Yes));
957+
}
958+
959+
// No resolution and no one else can define the name - determinate error.
960+
Err((Determined, Weak::No))
961+
}
962+
963+
fn resolve_ident_in_module_unadjusted_glob(
964+
&mut self,
965+
module: ModuleOrUniformRoot<'ra>,
966+
ident: Ident,
967+
ns: Namespace,
968+
parent_scope: &ParentScope<'ra>,
969+
shadowing: Shadowing,
970+
finalize: Option<Finalize>,
971+
// This binding should be ignored during in-module resolution, so that we don't get
972+
// "self-confirming" import resolutions during import validation and checking.
973+
ignore_binding: Option<NameBinding<'ra>>,
974+
ignore_import: Option<Import<'ra>>,
975+
) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
976+
let module = match module {
977+
ModuleOrUniformRoot::Module(module) => module,
978+
_ => return Err((Determined, Weak::No)),
979+
};
980+
981+
let key = BindingKey::new(ident, ns);
982+
let resolution =
983+
self.resolution(module, key).try_borrow_mut().map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports.
984+
985+
let binding = resolution.glob_binding;
986+
if let Some(binding) = binding {
987+
if binding == ignore_binding {
988+
return Err((Determined, Weak::No));
989+
}
990+
}
991+
992+
if let Some(finalize) = finalize {
993+
return self.finalize_module_binding(
994+
ident,
995+
binding,
996+
None,
997+
parent_scope,
998+
finalize,
999+
shadowing,
1000+
);
1001+
}
1002+
1003+
let check_usable = |this: &mut Self, binding: NameBinding<'ra>| {
1004+
let usable = this.is_accessible_from(binding.vis, parent_scope.module);
1005+
if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
1006+
};
1007+
1008+
// Items and single imports are not shadowable, if we have one, then it's determined.
1009+
if let Some(binding) = binding {
9021010
return check_usable(self, binding);
9031011
}
9041012

@@ -977,7 +1085,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
9771085
Some(None) => {}
9781086
None => continue,
9791087
};
980-
let result = self.resolve_ident_in_module_unadjusted(
1088+
let result = self.resolve_ident_in_module_unadjusted_non_glob(
9811089
ModuleOrUniformRoot::Module(module),
9821090
ident,
9831091
ns,
@@ -1724,3 +1832,4 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
17241832
})
17251833
}
17261834
}
1835+
''

compiler/rustc_resolve/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ enum Scope<'ra> {
122122
CrateRoot,
123123
// The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK`
124124
// lint if it should be reported.
125-
Module(Module<'ra>, Option<NodeId>),
125+
NonGlob(Module<'ra>, Option<NodeId>),
126+
Glob(Module<'ra>),
126127
MacroUsePrelude,
127128
BuiltinAttrs,
128129
ExternPrelude,

0 commit comments

Comments
 (0)