Rollup merge of #156135 - oli-obk:def_id_to_node_id_reduction, r=petrochenkov

Remove most uses of def_id_to_node_id

Especially those happening during normal resolving, where we are actually looking at current parent scopes. It allows follow-up refactorings to not have a way to go from `NodeId` to `DefId` until macro expansion is done

r? @petrochenkov
This commit is contained in:
Guillaume Gomez
2026-05-05 02:50:14 +02:00
committed by GitHub
6 changed files with 65 additions and 48 deletions
@@ -9,8 +9,9 @@ use std::sync::Arc;
use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
use rustc_ast::{
self as ast, AssocItem, AssocItemKind, Block, ConstItem, Delegation, Fn, ForeignItem,
ForeignItemKind, Inline, Item, ItemKind, NodeId, StaticItem, StmtKind, TraitAlias, TyAlias,
self as ast, AssocItem, AssocItemKind, Block, ConstItem, DUMMY_NODE_ID, Delegation, Fn,
ForeignItem, ForeignItemKind, Inline, Item, ItemKind, NodeId, StaticItem, StmtKind, TraitAlias,
TyAlias,
};
use rustc_attr_parsing::AttributeParser;
use rustc_expand::base::ResolverExpand;
@@ -168,7 +169,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let expn_id = self.cstore().expn_that_defined_untracked(self.tcx, def_id);
let module = self.new_extern_module(
parent,
ModuleKind::Def(def_kind, def_id, Some(self.tcx.item_name(def_id))),
ModuleKind::Def(
def_kind,
def_id,
DUMMY_NODE_ID,
Some(self.tcx.item_name(def_id)),
),
expn_id,
self.def_span(def_id),
// FIXME: Account for `#[no_implicit_prelude]` attributes.
@@ -251,7 +257,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// Any inherited visibility resolved directly inside an enum or trait
// (i.e. variants, fields, and trait items) inherits from the visibility
// of the enum or trait.
ModuleKind::Def(DefKind::Enum | DefKind::Trait, def_id, _) => {
ModuleKind::Def(DefKind::Enum | DefKind::Trait, def_id, _, _) => {
self.tcx.visibility(def_id).expect_local()
}
// Otherwise, the visibility is restricted to the nearest parent `mod` item.
@@ -848,7 +854,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
}
let module = self.r.new_local_module(
Some(parent),
ModuleKind::Def(def_kind, def_id, Some(ident.name)),
ModuleKind::Def(def_kind, def_id, item.id, Some(ident.name)),
expansion.to_expn_id(),
item.span,
parent.no_implicit_prelude
@@ -882,7 +888,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
let module = self.r.new_local_module(
Some(parent),
ModuleKind::Def(def_kind, def_id, Some(ident.name)),
ModuleKind::Def(def_kind, def_id, item.id, Some(ident.name)),
expansion.to_expn_id(),
item.span,
parent.no_implicit_prelude,
+22 -21
View File
@@ -5,7 +5,8 @@ use std::ops::ControlFlow;
use itertools::Itertools as _;
use rustc_ast::visit::{self, Visitor};
use rustc_ast::{
self as ast, CRATE_NODE_ID, Crate, ItemKind, ModKind, NodeId, Path, join_path_idents,
self as ast, CRATE_NODE_ID, Crate, DUMMY_NODE_ID, ItemKind, ModKind, NodeId, Path,
join_path_idents,
};
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -192,11 +193,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
fn report_with_use_injections(&mut self, krate: &Crate) {
for UseError { mut err, candidates, def_id, instead, suggestion, path, is_call } in
for UseError { mut err, candidates, node_id, instead, suggestion, path, is_call } in
mem::take(&mut self.use_injections)
{
let (span, found_use) = if let Some(def_id) = def_id.as_local() {
UsePlacementFinder::check(krate, self.def_id_to_node_id(def_id))
let (span, found_use) = if node_id != DUMMY_NODE_ID {
UsePlacementFinder::check(krate, node_id)
} else {
(None, FoundUse::No)
};
@@ -242,7 +243,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let container = match old_binding.parent_module.unwrap().kind {
// Avoid using TyCtxt::def_kind_descr in the resolver, because it
// indirectly *calls* the resolver, and would cause a query cycle.
ModuleKind::Def(kind, def_id, _) => kind.descr(def_id),
ModuleKind::Def(kind, def_id, _, _) => kind.descr(def_id),
ModuleKind::Block => "block",
};
@@ -1705,9 +1706,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let import_suggestions =
self.lookup_import_candidates(ident, Namespace::MacroNS, parent_scope, is_expected);
let (span, found_use) = match parent_scope.module.nearest_parent_mod().as_local() {
Some(def_id) => UsePlacementFinder::check(krate, self.def_id_to_node_id(def_id)),
None => (None, FoundUse::No),
let (span, found_use) = match parent_scope.module.nearest_parent_mod_node_id() {
DUMMY_NODE_ID => (None, FoundUse::No),
node_id => UsePlacementFinder::check(krate, node_id),
};
show_candidates(
self.tcx,
@@ -1764,7 +1765,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
if ident.name == kw::Default
&& let ModuleKind::Def(DefKind::Enum, def_id, _) = parent_scope.module.kind
&& let ModuleKind::Def(DefKind::Enum, def_id, _, _) = parent_scope.module.kind
{
let span = self.def_span(def_id);
let source_map = self.tcx.sess.source_map();
@@ -1892,19 +1893,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
missing a `derive` attribute",
ident.name,
);
let sugg_span = if let ModuleKind::Def(DefKind::Enum, id, _) = parent_scope.module.kind
{
let span = self.def_span(id);
if span.from_expansion() {
None
let sugg_span =
if let ModuleKind::Def(DefKind::Enum, id, _, _) = parent_scope.module.kind {
let span = self.def_span(id);
if span.from_expansion() {
None
} else {
// For enum variants sugg_span is empty but we can get the enum's Span.
Some(span.shrink_to_lo())
}
} else {
// For enum variants sugg_span is empty but we can get the enum's Span.
Some(span.shrink_to_lo())
}
} else {
// For items this `Span` will be populated, everything else it'll be None.
sugg_span
};
// For items this `Span` will be populated, everything else it'll be None.
sugg_span
};
match sugg_span {
Some(span) => {
err.span_suggestion_verbose(
+1 -1
View File
@@ -644,7 +644,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
}
Scope::ModuleGlobs(module, _)
if let ModuleKind::Def(_, def_id, _) = module.kind
if let ModuleKind::Def(_, def_id, _, _) = module.kind
&& !def_id.is_local() =>
{
// Fast path: external module decoding only creates non-glob declarations.
+6 -5
View File
@@ -1941,7 +1941,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
&& let Some((module, _)) = &self.current_trait_ref
&& let Some(ty) = &self.diag_metadata.current_self_type
&& Some(true) == self.diag_metadata.in_non_gat_assoc_type
&& let crate::ModuleKind::Def(DefKind::Trait, trait_id, _) = module.kind
&& let crate::ModuleKind::Def(DefKind::Trait, trait_id, _, _) =
module.kind
{
if def_id_matches_path(
self.r.tcx,
@@ -4514,7 +4515,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
parent_qself,
);
let def_id = this.parent_scope.module.nearest_parent_mod();
let node_id = this.parent_scope.module.nearest_parent_mod_node_id();
let instead = res.is_some();
let (suggestion, const_err) = if let Some((start, end)) =
this.diag_metadata.in_range
@@ -4556,7 +4557,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
let ue = UseError {
err,
candidates,
def_id,
node_id,
instead,
suggestion,
path: path.into(),
@@ -4645,7 +4646,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
parent_err.cancel();
let def_id = this.parent_scope.module.nearest_parent_mod();
let node_id = this.parent_scope.module.nearest_parent_mod_node_id();
if this.should_report_errs() {
if candidates.is_empty() {
@@ -4670,7 +4671,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
this.r.use_injections.push(UseError {
err,
candidates,
def_id,
node_id,
instead: false,
suggestion: None,
path: prefix_path.into(),
+23 -14
View File
@@ -543,7 +543,7 @@ enum ModuleKind {
/// The crate root will have `None` for the symbol.
/// * A trait or an enum (it implicitly contains associated types, methods and variant
/// constructors).
Def(DefKind, DefId, Option<Symbol>),
Def(DefKind, DefId, NodeId, Option<Symbol>),
}
impl ModuleKind {
@@ -557,7 +557,7 @@ impl ModuleKind {
fn opt_def_id(&self) -> Option<DefId> {
match self {
ModuleKind::Def(_, def_id, _) => Some(*def_id),
ModuleKind::Def(_, def_id, _, _) => Some(*def_id),
_ => None,
}
}
@@ -726,7 +726,7 @@ impl<'ra> ModuleData<'ra> {
self_decl: Option<Decl<'ra>>,
) -> Self {
let is_foreign = match kind {
ModuleKind::Def(_, def_id, _) => !def_id.is_local(),
ModuleKind::Def(_, def_id, _, _) => !def_id.is_local(),
ModuleKind::Block => false,
};
ModuleData {
@@ -756,7 +756,7 @@ impl<'ra> ModuleData<'ra> {
fn res(&self) -> Option<Res> {
match self.kind {
ModuleKind::Def(kind, def_id, _) => Some(Res::Def(kind, def_id)),
ModuleKind::Def(kind, def_id, _, _) => Some(Res::Def(kind, def_id)),
_ => None,
}
}
@@ -813,11 +813,11 @@ impl<'ra> Module<'ra> {
// `self` resolves to the first module ancestor that `is_normal`.
fn is_normal(self) -> bool {
matches!(self.kind, ModuleKind::Def(DefKind::Mod, _, _))
matches!(self.kind, ModuleKind::Def(DefKind::Mod, _, _, _))
}
fn is_trait(self) -> bool {
matches!(self.kind, ModuleKind::Def(DefKind::Trait, _, _))
matches!(self.kind, ModuleKind::Def(DefKind::Trait, _, _, _))
}
fn nearest_item_scope(self) -> Module<'ra> {
@@ -833,11 +833,20 @@ impl<'ra> Module<'ra> {
/// This may be the crate root.
fn nearest_parent_mod(self) -> DefId {
match self.kind {
ModuleKind::Def(DefKind::Mod, def_id, _) => def_id,
ModuleKind::Def(DefKind::Mod, def_id, _, _) => def_id,
_ => self.parent.expect("non-root module without parent").nearest_parent_mod(),
}
}
/// The [`NodeId`] of the nearest `mod` item ancestor (which may be this module).
/// This may be the crate root.
fn nearest_parent_mod_node_id(self) -> NodeId {
match self.kind {
ModuleKind::Def(DefKind::Mod, _, node_id, _) => node_id,
_ => self.parent.expect("non-root module without parent").nearest_parent_mod_node_id(),
}
}
fn is_ancestor_of(self, mut other: Self) -> bool {
while self != other {
if let Some(parent) = other.parent {
@@ -852,7 +861,7 @@ impl<'ra> Module<'ra> {
#[track_caller]
fn expect_local(self) -> LocalModule<'ra> {
match self.kind {
ModuleKind::Def(_, def_id, _) if !def_id.is_local() => {
ModuleKind::Def(_, def_id, _, _) if !def_id.is_local() => {
panic!("`Module::expect_local` is called on a non-local module: {self:?}")
}
ModuleKind::Def(..) | ModuleKind::Block => LocalModule(self.0),
@@ -862,7 +871,7 @@ impl<'ra> Module<'ra> {
#[track_caller]
fn expect_extern(self) -> ExternModule<'ra> {
match self.kind {
ModuleKind::Def(_, def_id, _) if !def_id.is_local() => ExternModule(self.0),
ModuleKind::Def(_, def_id, _, _) if !def_id.is_local() => ExternModule(self.0),
ModuleKind::Def(..) | ModuleKind::Block => {
panic!("`Module::expect_extern` is called on a local module: {self:?}")
}
@@ -992,8 +1001,8 @@ struct UseError<'a> {
err: Diag<'a>,
/// Candidates which user could `use` to access the missing type.
candidates: Vec<ImportSuggestion>,
/// The `DefId` of the module to place the use-statements in.
def_id: DefId,
/// The `NodeId` of the module to place the use-statements in.
node_id: NodeId,
/// Whether the diagnostic should say "instead" (as in `consider importing ... instead`).
instead: bool,
/// Extra free-form suggestion.
@@ -1551,7 +1560,7 @@ impl<'ra> ResolverArenas<'ra> {
no_implicit_prelude: bool,
) -> Module<'ra> {
let self_decl = match kind {
ModuleKind::Def(def_kind, def_id, _) => Some(self.new_def_decl(
ModuleKind::Def(def_kind, def_id, _, _) => Some(self.new_def_decl(
Res::Def(def_kind, def_id),
vis,
span,
@@ -1732,7 +1741,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let root_def_id = CRATE_DEF_ID.to_def_id();
let graph_root = arenas.new_module(
None,
ModuleKind::Def(DefKind::Mod, root_def_id, None),
ModuleKind::Def(DefKind::Mod, root_def_id, CRATE_NODE_ID, None),
Visibility::Public,
ExpnId::root(),
crate_span,
@@ -1743,7 +1752,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let local_module_map = FxIndexMap::from_iter([(CRATE_DEF_ID, graph_root)]);
let empty_module = arenas.new_module(
None,
ModuleKind::Def(DefKind::Mod, root_def_id, None),
ModuleKind::Def(DefKind::Mod, root_def_id, CRATE_NODE_ID, None),
Visibility::Public,
ExpnId::root(),
DUMMY_SP,
+1 -1
View File
@@ -1185,7 +1185,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.get_mut().record_use(ident, fallback_binding, Used::Other);
} else {
let location = match parent_scope.module.kind {
ModuleKind::Def(kind, def_id, name) => {
ModuleKind::Def(kind, def_id, _, name) => {
if let Some(name) = name {
format!("{} `{name}`", kind.descr(def_id))
} else {