resolve: Feed the def_kind
query immediately on DefId
creation
This commit is contained in:
parent
46a24ed2f4
commit
f0dc906319
15 changed files with 162 additions and 173 deletions
|
@ -2,6 +2,7 @@ use crate::{ImplTraitContext, Resolver};
|
|||
use rustc_ast::visit::{self, FnKind};
|
||||
use rustc_ast::*;
|
||||
use rustc_expand::expand::AstFragment;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::definitions::*;
|
||||
use rustc_span::hygiene::LocalExpnId;
|
||||
|
@ -26,13 +27,20 @@ struct DefCollector<'a, 'b, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
|
||||
fn create_def(&mut self, node_id: NodeId, data: DefPathData, span: Span) -> LocalDefId {
|
||||
fn create_def(
|
||||
&mut self,
|
||||
node_id: NodeId,
|
||||
data: DefPathData,
|
||||
def_kind: DefKind,
|
||||
span: Span,
|
||||
) -> LocalDefId {
|
||||
let parent_def = self.parent_def;
|
||||
debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def);
|
||||
self.resolver.create_def(
|
||||
parent_def,
|
||||
node_id,
|
||||
data,
|
||||
def_kind,
|
||||
self.expansion.to_expn_id(),
|
||||
span.with_parent(None),
|
||||
)
|
||||
|
@ -68,7 +76,8 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
|
|||
self.visit_macro_invoc(field.id);
|
||||
} else {
|
||||
let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name);
|
||||
let def = self.create_def(field.id, DefPathData::ValueNs(name), field.span);
|
||||
let def =
|
||||
self.create_def(field.id, DefPathData::ValueNs(name), DefKind::Field, field.span);
|
||||
self.with_parent(def, |this| visit::walk_field_def(this, field));
|
||||
}
|
||||
}
|
||||
|
@ -87,34 +96,43 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
|||
|
||||
// Pick the def data. This need not be unique, but the more
|
||||
// information we encapsulate into, the better
|
||||
let def_data = match &i.kind {
|
||||
ItemKind::Impl { .. } => DefPathData::Impl,
|
||||
ItemKind::ForeignMod(..) => DefPathData::ForeignMod,
|
||||
ItemKind::Mod(..)
|
||||
| ItemKind::Trait(..)
|
||||
| ItemKind::TraitAlias(..)
|
||||
| ItemKind::Enum(..)
|
||||
| ItemKind::Struct(..)
|
||||
| ItemKind::Union(..)
|
||||
| ItemKind::ExternCrate(..)
|
||||
| ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name),
|
||||
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => {
|
||||
DefPathData::ValueNs(i.ident.name)
|
||||
let mut opt_macro_data = None;
|
||||
let ty_data = DefPathData::TypeNs(i.ident.name);
|
||||
let value_data = DefPathData::ValueNs(i.ident.name);
|
||||
let (def_data, def_kind) = match &i.kind {
|
||||
ItemKind::Impl(i) => {
|
||||
(DefPathData::Impl, DefKind::Impl { of_trait: i.of_trait.is_some() })
|
||||
}
|
||||
ItemKind::ForeignMod(..) => (DefPathData::ForeignMod, DefKind::ForeignMod),
|
||||
ItemKind::Mod(..) => (ty_data, DefKind::Mod),
|
||||
ItemKind::Trait(..) => (ty_data, DefKind::Trait),
|
||||
ItemKind::TraitAlias(..) => (ty_data, DefKind::TraitAlias),
|
||||
ItemKind::Enum(..) => (ty_data, DefKind::Enum),
|
||||
ItemKind::Struct(..) => (ty_data, DefKind::Struct),
|
||||
ItemKind::Union(..) => (ty_data, DefKind::Union),
|
||||
ItemKind::ExternCrate(..) => (ty_data, DefKind::ExternCrate),
|
||||
ItemKind::TyAlias(..) => (ty_data, DefKind::TyAlias),
|
||||
ItemKind::Static(s) => (value_data, DefKind::Static(s.mutability)),
|
||||
ItemKind::Const(..) => (value_data, DefKind::Const),
|
||||
ItemKind::Fn(..) => (value_data, DefKind::Fn),
|
||||
ItemKind::MacroDef(..) => {
|
||||
let macro_data = self.resolver.compile_macro(i, self.resolver.tcx.sess.edition());
|
||||
let macro_kind = macro_data.ext.macro_kind();
|
||||
opt_macro_data = Some(macro_data);
|
||||
(DefPathData::MacroNs(i.ident.name), DefKind::Macro(macro_kind))
|
||||
}
|
||||
ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident.name),
|
||||
ItemKind::MacCall(..) => {
|
||||
visit::walk_item(self, i);
|
||||
return self.visit_macro_invoc(i.id);
|
||||
}
|
||||
ItemKind::GlobalAsm(..) => DefPathData::GlobalAsm,
|
||||
ItemKind::GlobalAsm(..) => (DefPathData::GlobalAsm, DefKind::GlobalAsm),
|
||||
ItemKind::Use(..) => {
|
||||
return visit::walk_item(self, i);
|
||||
}
|
||||
};
|
||||
let def_id = self.create_def(i.id, def_data, i.span);
|
||||
let def_id = self.create_def(i.id, def_data, def_kind, i.span);
|
||||
|
||||
if let ItemKind::MacroDef(..) = i.kind {
|
||||
let macro_data = self.resolver.compile_macro(i, self.resolver.tcx.sess.edition());
|
||||
if let Some(macro_data) = opt_macro_data {
|
||||
self.resolver.macro_map.insert(def_id.to_def_id(), macro_data);
|
||||
}
|
||||
|
||||
|
@ -123,8 +141,13 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
|||
match i.kind {
|
||||
ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => {
|
||||
// If this is a unit or tuple-like struct, register the constructor.
|
||||
if let Some(ctor_node_id) = struct_def.ctor_node_id() {
|
||||
this.create_def(ctor_node_id, DefPathData::Ctor, i.span);
|
||||
if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(struct_def) {
|
||||
this.create_def(
|
||||
ctor_node_id,
|
||||
DefPathData::Ctor,
|
||||
DefKind::Ctor(CtorOf::Struct, ctor_kind),
|
||||
i.span,
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -151,7 +174,12 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
|||
// then the closure_def will never be used, and we should avoid generating a
|
||||
// def-id for it.
|
||||
if let Some(body) = body {
|
||||
let closure_def = self.create_def(closure_id, DefPathData::ClosureExpr, span);
|
||||
let closure_def = self.create_def(
|
||||
closure_id,
|
||||
DefPathData::ClosureExpr,
|
||||
DefKind::Closure,
|
||||
span,
|
||||
);
|
||||
self.with_parent(closure_def, |this| this.visit_block(body));
|
||||
}
|
||||
return;
|
||||
|
@ -162,18 +190,23 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
|||
}
|
||||
|
||||
fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) {
|
||||
self.create_def(id, DefPathData::Use, use_tree.span);
|
||||
self.create_def(id, DefPathData::Use, DefKind::Use, use_tree.span);
|
||||
visit::walk_use_tree(self, use_tree, id);
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
|
||||
if let ForeignItemKind::MacCall(_) = foreign_item.kind {
|
||||
return self.visit_macro_invoc(foreign_item.id);
|
||||
}
|
||||
let def_kind = match foreign_item.kind {
|
||||
ForeignItemKind::Static(_, mt, _) => DefKind::Static(mt),
|
||||
ForeignItemKind::Fn(_) => DefKind::Fn,
|
||||
ForeignItemKind::TyAlias(_) => DefKind::ForeignTy,
|
||||
ForeignItemKind::MacCall(_) => return self.visit_macro_invoc(foreign_item.id),
|
||||
};
|
||||
|
||||
// FIXME: The namespace is incorrect for foreign types.
|
||||
let def = self.create_def(
|
||||
foreign_item.id,
|
||||
DefPathData::ValueNs(foreign_item.ident.name),
|
||||
def_kind,
|
||||
foreign_item.span,
|
||||
);
|
||||
|
||||
|
@ -186,10 +219,16 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
|||
if v.is_placeholder {
|
||||
return self.visit_macro_invoc(v.id);
|
||||
}
|
||||
let def = self.create_def(v.id, DefPathData::TypeNs(v.ident.name), v.span);
|
||||
let def =
|
||||
self.create_def(v.id, DefPathData::TypeNs(v.ident.name), DefKind::Variant, v.span);
|
||||
self.with_parent(def, |this| {
|
||||
if let Some(ctor_node_id) = v.data.ctor_node_id() {
|
||||
this.create_def(ctor_node_id, DefPathData::Ctor, v.span);
|
||||
if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(&v.data) {
|
||||
this.create_def(
|
||||
ctor_node_id,
|
||||
DefPathData::Ctor,
|
||||
DefKind::Ctor(CtorOf::Variant, ctor_kind),
|
||||
v.span,
|
||||
);
|
||||
}
|
||||
visit::walk_variant(this, v)
|
||||
});
|
||||
|
@ -210,12 +249,14 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
|||
return;
|
||||
}
|
||||
let name = param.ident.name;
|
||||
let def_path_data = match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => DefPathData::LifetimeNs(name),
|
||||
GenericParamKind::Type { .. } => DefPathData::TypeNs(name),
|
||||
GenericParamKind::Const { .. } => DefPathData::ValueNs(name),
|
||||
let (def_path_data, def_kind) = match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => {
|
||||
(DefPathData::LifetimeNs(name), DefKind::LifetimeParam)
|
||||
}
|
||||
GenericParamKind::Type { .. } => (DefPathData::TypeNs(name), DefKind::TyParam),
|
||||
GenericParamKind::Const { .. } => (DefPathData::ValueNs(name), DefKind::ConstParam),
|
||||
};
|
||||
self.create_def(param.id, def_path_data, param.ident.span);
|
||||
self.create_def(param.id, def_path_data, def_kind, param.ident.span);
|
||||
|
||||
// impl-Trait can happen inside generic parameters, like
|
||||
// ```
|
||||
|
@ -229,13 +270,14 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
|||
}
|
||||
|
||||
fn visit_assoc_item(&mut self, i: &'a AssocItem, ctxt: visit::AssocCtxt) {
|
||||
let def_data = match &i.kind {
|
||||
AssocItemKind::Fn(..) | AssocItemKind::Const(..) => DefPathData::ValueNs(i.ident.name),
|
||||
AssocItemKind::Type(..) => DefPathData::TypeNs(i.ident.name),
|
||||
let (def_data, def_kind) = match &i.kind {
|
||||
AssocItemKind::Fn(..) => (DefPathData::ValueNs(i.ident.name), DefKind::AssocFn),
|
||||
AssocItemKind::Const(..) => (DefPathData::ValueNs(i.ident.name), DefKind::AssocConst),
|
||||
AssocItemKind::Type(..) => (DefPathData::TypeNs(i.ident.name), DefKind::AssocTy),
|
||||
AssocItemKind::MacCall(..) => return self.visit_macro_invoc(i.id),
|
||||
};
|
||||
|
||||
let def = self.create_def(i.id, def_data, i.span);
|
||||
let def = self.create_def(i.id, def_data, def_kind, i.span);
|
||||
self.with_parent(def, |this| visit::walk_assoc_item(this, i, ctxt));
|
||||
}
|
||||
|
||||
|
@ -247,7 +289,12 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
|||
}
|
||||
|
||||
fn visit_anon_const(&mut self, constant: &'a AnonConst) {
|
||||
let def = self.create_def(constant.id, DefPathData::AnonConst, constant.value.span);
|
||||
let def = self.create_def(
|
||||
constant.id,
|
||||
DefPathData::AnonConst,
|
||||
DefKind::AnonConst,
|
||||
constant.value.span,
|
||||
);
|
||||
self.with_parent(def, |this| visit::walk_anon_const(this, constant));
|
||||
}
|
||||
|
||||
|
@ -257,15 +304,31 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
|||
ExprKind::Closure(ref closure) => {
|
||||
// Async closures desugar to closures inside of closures, so
|
||||
// we must create two defs.
|
||||
let closure_def = self.create_def(expr.id, DefPathData::ClosureExpr, expr.span);
|
||||
let closure_def =
|
||||
self.create_def(expr.id, DefPathData::ClosureExpr, DefKind::Closure, expr.span);
|
||||
match closure.asyncness {
|
||||
Async::Yes { closure_id, .. } => {
|
||||
self.create_def(closure_id, DefPathData::ClosureExpr, expr.span)
|
||||
}
|
||||
Async::Yes { closure_id, .. } => self.create_def(
|
||||
closure_id,
|
||||
DefPathData::ClosureExpr,
|
||||
DefKind::Closure,
|
||||
expr.span,
|
||||
),
|
||||
Async::No => closure_def,
|
||||
}
|
||||
}
|
||||
ExprKind::Gen(_, _, _) => self.create_def(expr.id, DefPathData::ClosureExpr, expr.span),
|
||||
ExprKind::Gen(_, _, _) => {
|
||||
self.create_def(expr.id, DefPathData::ClosureExpr, DefKind::Closure, expr.span)
|
||||
}
|
||||
ExprKind::ConstBlock(ref constant) => {
|
||||
let def = self.create_def(
|
||||
constant.id,
|
||||
DefPathData::AnonConst,
|
||||
DefKind::InlineConst,
|
||||
constant.value.span,
|
||||
);
|
||||
self.with_parent(def, |this| visit::walk_anon_const(this, constant));
|
||||
return;
|
||||
}
|
||||
_ => self.parent_def,
|
||||
};
|
||||
|
||||
|
|
|
@ -1034,9 +1034,6 @@ pub struct Resolver<'a, 'tcx> {
|
|||
used_extern_options: FxHashSet<Symbol>,
|
||||
macro_names: FxHashSet<Ident>,
|
||||
builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
|
||||
/// A small map keeping true kinds of built-in macros that appear to be fn-like on
|
||||
/// the surface (`macro` items in libcore), but are actually attributes or derives.
|
||||
builtin_macro_kinds: FxHashMap<LocalDefId, MacroKind>,
|
||||
registered_tools: &'tcx RegisteredTools,
|
||||
macro_use_prelude: FxHashMap<Symbol, NameBinding<'a>>,
|
||||
macro_map: FxHashMap<DefId, MacroData>,
|
||||
|
@ -1216,6 +1213,7 @@ impl<'tcx> Resolver<'_, 'tcx> {
|
|||
parent: LocalDefId,
|
||||
node_id: ast::NodeId,
|
||||
data: DefPathData,
|
||||
def_kind: DefKind,
|
||||
expn_id: ExpnId,
|
||||
span: Span,
|
||||
) -> LocalDefId {
|
||||
|
@ -1230,6 +1228,9 @@ impl<'tcx> Resolver<'_, 'tcx> {
|
|||
// FIXME: remove `def_span` body, pass in the right spans here and call `tcx.at().create_def()`
|
||||
let def_id = self.tcx.untracked().definitions.write().create_def(parent, data);
|
||||
|
||||
let feed = self.tcx.feed_local_def_id(def_id);
|
||||
feed.def_kind(def_kind);
|
||||
|
||||
// Create the definition.
|
||||
if expn_id != ExpnId::root() {
|
||||
self.expn_that_defined.insert(def_id, expn_id);
|
||||
|
@ -1403,7 +1404,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
used_extern_options: Default::default(),
|
||||
macro_names: FxHashSet::default(),
|
||||
builtin_macros: Default::default(),
|
||||
builtin_macro_kinds: Default::default(),
|
||||
registered_tools,
|
||||
macro_use_prelude: FxHashMap::default(),
|
||||
macro_map: FxHashMap::default(),
|
||||
|
@ -1542,7 +1542,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
node_id_to_def_id: self.node_id_to_def_id,
|
||||
def_id_to_node_id: self.def_id_to_node_id,
|
||||
trait_map: self.trait_map,
|
||||
builtin_macro_kinds: self.builtin_macro_kinds,
|
||||
lifetime_elision_allowed: self.lifetime_elision_allowed,
|
||||
lint_buffer: Steal::new(self.lint_buffer),
|
||||
};
|
||||
|
|
|
@ -950,10 +950,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
BuiltinMacroState::NotYetSeen(builtin_ext) => {
|
||||
ext.kind = builtin_ext;
|
||||
rule_spans = Vec::new();
|
||||
if item.id != ast::DUMMY_NODE_ID {
|
||||
self.builtin_macro_kinds
|
||||
.insert(self.local_def_id(item.id), ext.macro_kind());
|
||||
}
|
||||
}
|
||||
BuiltinMacroState::AlreadySeen(span) => {
|
||||
struct_span_err!(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue