Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve tweaks #132761

Merged
merged 9 commits into from
Nov 19, 2024
3 changes: 2 additions & 1 deletion compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,9 +641,10 @@ impl<'a> Parser<'a> {
return true;
}

// Do an ASCII case-insensitive match, because all keywords are ASCII.
if case == Case::Insensitive
&& let Some((ident, IdentIsRaw::No)) = self.token.ident()
&& ident.as_str().to_lowercase() == kw.as_str().to_lowercase()
&& ident.as_str().eq_ignore_ascii_case(kw.as_str())
{
true
} else {
Expand Down
12 changes: 5 additions & 7 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -535,14 +535,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
filter_fn: &impl Fn(Res) -> bool,
ctxt: Option<SyntaxContext>,
) {
for (key, resolution) in self.resolutions(module).borrow().iter() {
if let Some(binding) = resolution.borrow().binding {
let res = binding.res();
if filter_fn(res) && ctxt.map_or(true, |ctxt| ctxt == key.ident.span.ctxt()) {
names.push(TypoSuggestion::typo_from_ident(key.ident, res));
}
module.for_each_child(self, |_this, ident, _ns, binding| {
let res = binding.res();
if filter_fn(res) && ctxt.map_or(true, |ctxt| ctxt == ident.span.ctxt()) {
names.push(TypoSuggestion::typo_from_ident(ident, res));
}
}
});
}

/// Combines an error with provided span and emits it.
Expand Down
112 changes: 40 additions & 72 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ impl From<UsePrelude> for bool {
}
}

#[derive(Debug, PartialEq)]
enum Shadowing {
Restricted,
Unrestricted,
}

impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
/// A generic scope visitor.
/// Visits scopes in order to resolve some identifier in them or perform other actions.
Expand Down Expand Up @@ -311,13 +317,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {

// Walk backwards up the ribs in scope.
let mut module = self.graph_root;
for i in (0..ribs.len()).rev() {
debug!("walk rib\n{:?}", ribs[i].bindings);
for (i, rib) in ribs.iter().enumerate().rev() {
debug!("walk rib\n{:?}", rib.bindings);
// Use the rib kind to determine whether we are resolving parameters
// (macro 2.0 hygiene) or local variables (`macro_rules` hygiene).
let rib_ident = if ribs[i].kind.contains_params() { normalized_ident } else { ident };
if let Some((original_rib_ident_def, res)) = ribs[i].bindings.get_key_value(&rib_ident)
{
let rib_ident = if rib.kind.contains_params() { normalized_ident } else { ident };
if let Some((original_rib_ident_def, res)) = rib.bindings.get_key_value(&rib_ident) {
// The ident resolves to a type parameter or local variable.
return Some(LexicalScopeBinding::Res(self.validate_res_from_ribs(
i,
Expand All @@ -329,7 +334,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
)));
}

module = match ribs[i].kind {
module = match rib.kind {
RibKind::Module(module) => module,
RibKind::MacroDefinition(def) if def == self.macro_def(ident.span.ctxt()) => {
// If an invocation of this macro created `ident`, give up on `ident`
Expand All @@ -350,6 +355,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ident,
ns,
parent_scope,
Shadowing::Unrestricted,
finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
ignore_binding,
None,
Expand Down Expand Up @@ -494,7 +500,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Scope::CrateRoot => {
let root_ident = Ident::new(kw::PathRoot, ident.span);
let root_module = this.resolve_crate_root(root_ident);
let binding = this.resolve_ident_in_module_ext(
let binding = this.resolve_ident_in_module(
ModuleOrUniformRoot::Module(root_module),
ident,
ns,
Expand All @@ -516,12 +522,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
Scope::Module(module, derive_fallback_lint_id) => {
let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
let binding = this.resolve_ident_in_module_unadjusted_ext(
let binding = this.resolve_ident_in_module_unadjusted(
ModuleOrUniformRoot::Module(module),
ident,
ns,
adjusted_parent_scope,
!matches!(scope_set, ScopeSet::Late(..)),
if matches!(scope_set, ScopeSet::Late(..)) {
Shadowing::Unrestricted
} else {
Shadowing::Restricted
},
finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
ignore_binding,
ignore_import,
Expand Down Expand Up @@ -590,6 +600,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ident,
ns,
parent_scope,
Shadowing::Unrestricted,
None,
ignore_binding,
ignore_import,
Expand Down Expand Up @@ -748,35 +759,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
parent_scope: &ParentScope<'ra>,
ignore_import: Option<Import<'ra>>,
) -> Result<NameBinding<'ra>, Determinacy> {
self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, None, None, ignore_import)
self.resolve_ident_in_module(module, ident, ns, parent_scope, None, None, ignore_import)
.map_err(|(determinacy, _)| determinacy)
}

#[instrument(level = "debug", skip(self))]
pub(crate) fn resolve_ident_in_module(
&mut self,
module: ModuleOrUniformRoot<'ra>,
ident: Ident,
ns: Namespace,
parent_scope: &ParentScope<'ra>,
finalize: Option<Finalize>,
ignore_binding: Option<NameBinding<'ra>>,
ignore_import: Option<Import<'ra>>,
) -> Result<NameBinding<'ra>, Determinacy> {
self.resolve_ident_in_module_ext(
module,
ident,
ns,
parent_scope,
finalize,
ignore_binding,
ignore_import,
)
.map_err(|(determinacy, _)| determinacy)
}

#[instrument(level = "debug", skip(self))]
fn resolve_ident_in_module_ext(
&mut self,
module: ModuleOrUniformRoot<'ra>,
mut ident: Ident,
Expand All @@ -803,52 +791,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// No adjustments
}
}
self.resolve_ident_in_module_unadjusted_ext(
self.resolve_ident_in_module_unadjusted(
module,
ident,
ns,
adjusted_parent_scope,
false,
Shadowing::Unrestricted,
finalize,
ignore_binding,
ignore_import,
)
}

#[instrument(level = "debug", skip(self))]
fn resolve_ident_in_module_unadjusted(
&mut self,
module: ModuleOrUniformRoot<'ra>,
ident: Ident,
ns: Namespace,
parent_scope: &ParentScope<'ra>,
finalize: Option<Finalize>,
ignore_binding: Option<NameBinding<'ra>>,
ignore_import: Option<Import<'ra>>,
) -> Result<NameBinding<'ra>, Determinacy> {
self.resolve_ident_in_module_unadjusted_ext(
module,
ident,
ns,
parent_scope,
false,
finalize,
ignore_binding,
ignore_import,
)
.map_err(|(determinacy, _)| determinacy)
}

/// Attempts to resolve `ident` in namespaces `ns` of `module`.
/// Invariant: if `finalize` is `Some`, expansion and import resolution must be complete.
#[instrument(level = "debug", skip(self))]
fn resolve_ident_in_module_unadjusted_ext(
fn resolve_ident_in_module_unadjusted(
nnethercote marked this conversation as resolved.
Show resolved Hide resolved
&mut self,
module: ModuleOrUniformRoot<'ra>,
ident: Ident,
ns: Namespace,
parent_scope: &ParentScope<'ra>,
restricted_shadowing: bool,
shadowing: Shadowing,
finalize: Option<Finalize>,
// This binding should be ignored during in-module resolution, so that we don't get
// "self-confirming" import resolutions during import validation and checking.
Expand All @@ -858,7 +822,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let module = match module {
ModuleOrUniformRoot::Module(module) => module,
ModuleOrUniformRoot::CrateRootAndExternPrelude => {
assert!(!restricted_shadowing);
assert_eq!(shadowing, Shadowing::Unrestricted);
let binding = self.early_resolve_ident_in_lexical_scope(
ident,
ScopeSet::AbsolutePath(ns),
Expand All @@ -871,7 +835,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
return binding.map_err(|determinacy| (determinacy, Weak::No));
}
ModuleOrUniformRoot::ExternPrelude => {
assert!(!restricted_shadowing);
assert_eq!(shadowing, Shadowing::Unrestricted);
return if ns != TypeNS {
Err((Determined, Weak::No))
} else if let Some(binding) = self.extern_prelude_get(ident, finalize.is_some()) {
Expand All @@ -884,7 +848,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
};
}
ModuleOrUniformRoot::CurrentScope => {
assert!(!restricted_shadowing);
assert_eq!(shadowing, Shadowing::Unrestricted);
if ns == TypeNS {
if ident.name == kw::Crate || ident.name == kw::DollarCrate {
let module = self.resolve_crate_root(ident);
Expand Down Expand Up @@ -943,7 +907,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {

// Forbid expanded shadowing to avoid time travel.
if let Some(shadowed_glob) = resolution.shadowed_glob
&& restricted_shadowing
&& shadowing == Shadowing::Restricted
&& binding.expansion != LocalExpnId::ROOT
&& binding.res() != shadowed_glob.res()
{
Expand All @@ -958,7 +922,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
});
}

if !restricted_shadowing
if shadowing == Shadowing::Unrestricted
&& binding.expansion != LocalExpnId::ROOT
&& let NameBindingKind::Import { import, .. } = binding.kind
&& matches!(import.kind, ImportKind::MacroExport)
Expand Down Expand Up @@ -1047,13 +1011,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ignore_binding,
ignore_import,
) {
Err(Determined) => continue,
Err((Determined, _)) => continue,
Ok(binding)
if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) =>
{
continue;
}
Ok(_) | Err(Undetermined) => return Err((Undetermined, Weak::No)),
Ok(_) | Err((Undetermined, _)) => return Err((Undetermined, Weak::No)),
}
}

Expand All @@ -1070,7 +1034,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// and prohibit access to macro-expanded `macro_export` macros instead (unless restricted
// shadowing is enabled, see `macro_expanded_macro_export_errors`).
if let Some(binding) = binding {
if binding.determined() || ns == MacroNS || restricted_shadowing {
if binding.determined() || ns == MacroNS || shadowing == Shadowing::Restricted {
return check_usable(self, binding);
} else {
return Err((Undetermined, Weak::No));
Expand Down Expand Up @@ -1122,19 +1086,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ident,
ns,
adjusted_parent_scope,
Shadowing::Unrestricted,
None,
ignore_binding,
ignore_import,
);

match result {
Err(Determined) => continue,
Err((Determined, _)) => continue,
Ok(binding)
if !self.is_accessible_from(binding.vis, glob_import.parent_scope.module) =>
{
continue;
}
Ok(_) | Err(Undetermined) => return Err((Undetermined, Weak::Yes)),
Ok(_) | Err((Undetermined, _)) => return Err((Undetermined, Weak::Yes)),
}
}

Expand Down Expand Up @@ -1200,7 +1165,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// Still doesn't deal with upvars
if let Some(span) = finalize {
let (span, resolution_error) = match item {
None if rib_ident.as_str() == "self" => (span, LowercaseSelf),
None if rib_ident.name == kw::SelfLower => {
(span, LowercaseSelf)
}
None => {
// If we have a `let name = expr;`, we have the span for
// `name` and use that to see if it is followed by a type
Expand Down Expand Up @@ -1563,6 +1530,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ignore_binding,
ignore_import,
)
.map_err(|(determinacy, _)| determinacy)
} else if let Some(ribs) = ribs
&& let Some(TypeNS | ValueNS) = opt_ns
{
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1688,9 +1688,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
}
}

let normalized_ident = ident.normalize_to_macros_2_0();
let mut outer_res = None;
for rib in lifetime_rib_iter {
let normalized_ident = ident.normalize_to_macros_2_0();
if let Some((&outer, _)) = rib.bindings.get_key_value(&normalized_ident) {
outer_res = Some(outer);
break;
Expand Down
17 changes: 5 additions & 12 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1082,8 +1082,6 @@ pub struct Resolver<'ra, 'tcx> {
binding_parent_modules: FxHashMap<NameBinding<'ra>, Module<'ra>>,

underscore_disambiguator: u32,
/// Disambiguator for anonymous adts.
empty_disambiguator: u32,

/// Maps glob imports to the names of items actually imported.
glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
Expand Down Expand Up @@ -1462,7 +1460,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
module_children: Default::default(),
trait_map: NodeMap::default(),
underscore_disambiguator: 0,
empty_disambiguator: 0,
empty_module,
module_map,
block_map: Default::default(),
Expand Down Expand Up @@ -1809,12 +1806,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
assoc_item: Option<(Symbol, Namespace)>,
) -> bool {
match (trait_module, assoc_item) {
(Some(trait_module), Some((name, ns))) => {
self.resolutions(trait_module).borrow().iter().any(|resolution| {
let (&BindingKey { ident: assoc_ident, ns: assoc_ns, .. }, _) = resolution;
assoc_ns == ns && assoc_ident.name == name
})
}
(Some(trait_module), Some((name, ns))) => self
.resolutions(trait_module)
.borrow()
.iter()
.any(|(key, _name_resolution)| key.ns == ns && key.ident.name == name),
_ => true,
}
}
Expand Down Expand Up @@ -1842,9 +1838,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let disambiguator = if ident.name == kw::Underscore {
self.underscore_disambiguator += 1;
self.underscore_disambiguator
} else if ident.name == kw::Empty {
self.empty_disambiguator += 1;
self.empty_disambiguator
} else {
0
};
Expand Down
Loading