Rollup merge of #144368 - petrochenkov:rmrootscope, r=b-naber

resolve: Remove `Scope::CrateRoot`

Use `Scope::Module` with the crate root module inside instead, which should be identical.
This is a simplification by itself, but it will be even larger simplification if something like https://github.com/rust-lang/rust/pull/144131 is implemented, because `Scope::CrateRoot` is also a module with two actual scopes in it (for globs and non-globs).

I also did some renamings for consistency:
- `ScopeSet::AbsolutePath` -> `ScopeSet::ModuleAndExternPrelude`
- `ModuleOrUniformRoot::CrateRootAndExternPrelude` -> `ModuleOrUniformRoot::ModuleAndExternPrelude`
- `is_absolute_path` -> `module_and_extern_prelude`
This commit is contained in:
Matthias Krüger
2025-07-25 11:16:38 +02:00
committed by GitHub
4 changed files with 39 additions and 57 deletions

View File

@@ -1076,11 +1076,6 @@ 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);
this.add_module_candidates(root_module, &mut suggestions, filter_fn, None);
}
Scope::Module(module, _) => { Scope::Module(module, _) => {
this.add_module_candidates(module, &mut suggestions, filter_fn, None); this.add_module_candidates(module, &mut suggestions, filter_fn, None);
} }

View File

@@ -93,20 +93,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// 6. Language prelude: builtin attributes (closed, controlled). // 6. Language prelude: builtin attributes (closed, controlled).
let rust_2015 = ctxt.edition().is_rust_2015(); let rust_2015 = ctxt.edition().is_rust_2015();
let (ns, macro_kind, is_absolute_path) = match scope_set { let (ns, macro_kind) = match scope_set {
ScopeSet::All(ns) => (ns, None, false), ScopeSet::All(ns)
ScopeSet::AbsolutePath(ns) => (ns, None, true), | ScopeSet::ModuleAndExternPrelude(ns, _)
ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false), | ScopeSet::Late(ns, ..) => (ns, None),
ScopeSet::Late(ns, ..) => (ns, None, false), ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
}; };
let module = match scope_set { let module = match scope_set {
// Start with the specified module. // Start with the specified module.
ScopeSet::Late(_, module, _) => module, ScopeSet::Late(_, module, _) | ScopeSet::ModuleAndExternPrelude(_, module) => module,
// Jump out of trait or enum modules, they do not act as scopes. // Jump out of trait or enum modules, they do not act as scopes.
_ => parent_scope.module.nearest_item_scope(), _ => parent_scope.module.nearest_item_scope(),
}; };
let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..));
let mut scope = match ns { let mut scope = match ns {
_ if is_absolute_path => Scope::CrateRoot, _ if module_and_extern_prelude => Scope::Module(module, None),
TypeNS | ValueNS => Scope::Module(module, None), TypeNS | ValueNS => Scope::Module(module, None),
MacroNS => Scope::DeriveHelpers(parent_scope.expansion), MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
}; };
@@ -134,11 +135,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} }
true true
} }
Scope::CrateRoot => true,
Scope::Module(..) => true, Scope::Module(..) => true,
Scope::MacroUsePrelude => use_prelude || rust_2015, Scope::MacroUsePrelude => use_prelude || rust_2015,
Scope::BuiltinAttrs => true, Scope::BuiltinAttrs => true,
Scope::ExternPrelude => use_prelude || is_absolute_path, Scope::ExternPrelude => use_prelude || module_and_extern_prelude,
Scope::ToolPrelude => use_prelude, Scope::ToolPrelude => use_prelude,
Scope::StdLibPrelude => use_prelude || ns == MacroNS, Scope::StdLibPrelude => use_prelude || ns == MacroNS,
Scope::BuiltinTypes => true, Scope::BuiltinTypes => true,
@@ -174,7 +174,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} }
MacroRulesScope::Empty => Scope::Module(module, None), MacroRulesScope::Empty => Scope::Module(module, None),
}, },
Scope::CrateRoot => match ns { Scope::Module(..) if module_and_extern_prelude => match ns {
TypeNS => { TypeNS => {
ctxt.adjust(ExpnId::root()); ctxt.adjust(ExpnId::root());
Scope::ExternPrelude Scope::ExternPrelude
@@ -203,7 +203,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} }
Scope::MacroUsePrelude => Scope::StdLibPrelude, Scope::MacroUsePrelude => Scope::StdLibPrelude,
Scope::BuiltinAttrs => break, // nowhere else to search Scope::BuiltinAttrs => break, // nowhere else to search
Scope::ExternPrelude if is_absolute_path => break, Scope::ExternPrelude if module_and_extern_prelude => break,
Scope::ExternPrelude => Scope::ToolPrelude, Scope::ExternPrelude => Scope::ToolPrelude,
Scope::ToolPrelude => Scope::StdLibPrelude, Scope::ToolPrelude => Scope::StdLibPrelude,
Scope::StdLibPrelude => match ns { Scope::StdLibPrelude => match ns {
@@ -404,10 +404,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} }
let (ns, macro_kind) = match scope_set { let (ns, macro_kind) = match scope_set {
ScopeSet::All(ns) => (ns, None), ScopeSet::All(ns)
ScopeSet::AbsolutePath(ns) => (ns, None), | ScopeSet::ModuleAndExternPrelude(ns, _)
| ScopeSet::Late(ns, ..) => (ns, None),
ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)), ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
ScopeSet::Late(ns, ..) => (ns, None),
}; };
// This is *the* result, resolution from the scope closest to the resolved identifier. // This is *the* result, resolution from the scope closest to the resolved identifier.
@@ -487,31 +487,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined), MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined),
_ => Err(Determinacy::Determined), _ => Err(Determinacy::Determined),
}, },
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(
ModuleOrUniformRoot::Module(root_module),
ident,
ns,
parent_scope,
finalize,
ignore_binding,
ignore_import,
);
match binding {
Ok(binding) => Ok((binding, Flags::MODULE | Flags::MISC_SUGGEST_CRATE)),
Err((Determinacy::Undetermined, Weak::No)) => {
return Some(Err(Determinacy::determined(force)));
}
Err((Determinacy::Undetermined, Weak::Yes)) => {
Err(Determinacy::Undetermined)
}
Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
}
}
Scope::Module(module, derive_fallback_lint_id) => { Scope::Module(module, derive_fallback_lint_id) => {
let adjusted_parent_scope = &ParentScope { module, ..*parent_scope }; let (adjusted_parent_scope, finalize) =
if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) {
(parent_scope, finalize)
} else {
(
&ParentScope { module, ..*parent_scope },
finalize.map(|f| Finalize { used: Used::Scope, ..f }),
)
};
let binding = this.resolve_ident_in_module_unadjusted( let binding = this.resolve_ident_in_module_unadjusted(
ModuleOrUniformRoot::Module(module), ModuleOrUniformRoot::Module(module),
ident, ident,
@@ -522,7 +507,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} else { } else {
Shadowing::Restricted Shadowing::Restricted
}, },
finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }), finalize,
ignore_binding, ignore_binding,
ignore_import, ignore_import,
); );
@@ -776,7 +761,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ModuleOrUniformRoot::ExternPrelude => { ModuleOrUniformRoot::ExternPrelude => {
ident.span.normalize_to_macros_2_0_and_adjust(ExpnId::root()); ident.span.normalize_to_macros_2_0_and_adjust(ExpnId::root());
} }
ModuleOrUniformRoot::CrateRootAndExternPrelude | ModuleOrUniformRoot::CurrentScope => { ModuleOrUniformRoot::ModuleAndExternPrelude(..) | ModuleOrUniformRoot::CurrentScope => {
// No adjustments // No adjustments
} }
} }
@@ -810,11 +795,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
) -> Result<NameBinding<'ra>, (Determinacy, Weak)> { ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
let module = match module { let module = match module {
ModuleOrUniformRoot::Module(module) => module, ModuleOrUniformRoot::Module(module) => module,
ModuleOrUniformRoot::CrateRootAndExternPrelude => { ModuleOrUniformRoot::ModuleAndExternPrelude(module) => {
assert_eq!(shadowing, Shadowing::Unrestricted); assert_eq!(shadowing, Shadowing::Unrestricted);
let binding = self.early_resolve_ident_in_lexical_scope( let binding = self.early_resolve_ident_in_lexical_scope(
ident, ident,
ScopeSet::AbsolutePath(ns), ScopeSet::ModuleAndExternPrelude(ns, module),
parent_scope, parent_scope,
finalize, finalize,
finalize.is_some(), finalize.is_some(),
@@ -1531,7 +1516,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
&& self.tcx.sess.at_least_rust_2018() && self.tcx.sess.at_least_rust_2018()
{ {
// `::a::b` from 2015 macro on 2018 global edition // `::a::b` from 2015 macro on 2018 global edition
module = Some(ModuleOrUniformRoot::CrateRootAndExternPrelude); let crate_root = self.resolve_crate_root(ident);
module = Some(ModuleOrUniformRoot::ModuleAndExternPrelude(crate_root));
continue; continue;
} }
if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate { if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {

View File

@@ -181,10 +181,10 @@ pub(crate) struct ImportData<'ra> {
/// ///
/// | `module_path` | `imported_module` | remark | /// | `module_path` | `imported_module` | remark |
/// |-|-|-| /// |-|-|-|
/// |`use prefix::foo`| `ModuleOrUniformRoot::Module(prefix)` | - | /// |`use prefix::foo`| `ModuleOrUniformRoot::Module(prefix)` | - |
/// |`use ::foo` | `ModuleOrUniformRoot::ExternPrelude` | 2018+ editions | /// |`use ::foo` | `ModuleOrUniformRoot::ExternPrelude` | 2018+ editions |
/// |`use ::foo` | `ModuleOrUniformRoot::CrateRootAndExternPrelude` | a special case in 2015 edition | /// |`use ::foo` | `ModuleOrUniformRoot::ModuleAndExternPrelude` | a special case in 2015 edition |
/// |`use foo` | `ModuleOrUniformRoot::CurrentScope` | - | /// |`use foo` | `ModuleOrUniformRoot::CurrentScope` | - |
pub imported_module: Cell<Option<ModuleOrUniformRoot<'ra>>>, pub imported_module: Cell<Option<ModuleOrUniformRoot<'ra>>>,
pub vis: Visibility, pub vis: Visibility,
} }

View File

@@ -119,7 +119,6 @@ enum Scope<'ra> {
DeriveHelpers(LocalExpnId), DeriveHelpers(LocalExpnId),
DeriveHelpersCompat, DeriveHelpersCompat,
MacroRules(MacroRulesScopeRef<'ra>), MacroRules(MacroRulesScopeRef<'ra>),
CrateRoot,
// The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK` // The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK`
// lint if it should be reported. // lint if it should be reported.
Module(Module<'ra>, Option<NodeId>), Module(Module<'ra>, Option<NodeId>),
@@ -139,8 +138,8 @@ enum Scope<'ra> {
enum ScopeSet<'ra> { enum ScopeSet<'ra> {
/// All scopes with the given namespace. /// All scopes with the given namespace.
All(Namespace), All(Namespace),
/// Crate root, then extern prelude (used for mixed 2015-2018 mode in macros). /// A module, then extern prelude (used for mixed 2015-2018 mode in macros).
AbsolutePath(Namespace), ModuleAndExternPrelude(Namespace, Module<'ra>),
/// All scopes with macro namespace and the given macro kind restriction. /// All scopes with macro namespace and the given macro kind restriction.
Macro(MacroKind), Macro(MacroKind),
/// All scopes with the given namespace, used for partially performing late resolution. /// All scopes with the given namespace, used for partially performing late resolution.
@@ -419,8 +418,10 @@ enum ModuleOrUniformRoot<'ra> {
/// Regular module. /// Regular module.
Module(Module<'ra>), Module(Module<'ra>),
/// Virtual module that denotes resolution in crate root with fallback to extern prelude. /// Virtual module that denotes resolution in a module with fallback to extern prelude.
CrateRootAndExternPrelude, /// Used for paths starting with `::` coming from 2015 edition macros
/// used in 2018+ edition crates.
ModuleAndExternPrelude(Module<'ra>),
/// Virtual module that denotes resolution in extern prelude. /// Virtual module that denotes resolution in extern prelude.
/// Used for paths starting with `::` on 2018 edition. /// Used for paths starting with `::` on 2018 edition.