Skip to content

Commit

Permalink
Auto merge of #60462 - eddyb:def-1-a-mere-resolution, r=petrochenkov
Browse files Browse the repository at this point in the history
rustc: factor out most of hir::def::Def's variants into DefKind, and rename to Res.

The first two commits are about introducing `DefKind`, both to simplify/orthogonalize `hir::def::Def`, and to allow reasoning about the kind of a definition without dealing with the redundant `DefId`.
(There are likely more changes to be made, such as adding enough `DefKind` variants for `tcx.def_kind(def_id)` to return just `DefKind`, not `Option<DefKind>`, but this is pretty big as-is)

The third commit frees up the `Def` name (which we may want to use in the future for "definitions", in the sense of "entities with a `DefId`") by renaming `hir::def::Def` to `Res` ("resolution").
IMO this fits, as it represents all the possible name resolution results, not just "definitions (with a `DefId`)".

Quick examples:
```rust
// Before:
if tcx.describe_def(def_id) == Some(Def::Struct(def_id)) {...}
if let Def::Struct(def_id) = path.def {...}
```
```rust
// After:
if tcx.def_kind(def_id) == Some(DefKind::Struct) {...}
if let Res::Def(DefKind::Struct, def_id) = path.res {...}
```

r? @petrochenkov cc @rust-lang/compiler
  • Loading branch information
bors committed May 3, 2019
2 parents a340455 + ff174fe commit 13fde05
Show file tree
Hide file tree
Showing 61 changed files with 1,840 additions and 1,692 deletions.
286 changes: 144 additions & 142 deletions src/librustc/hir/def.rs

Large diffs are not rendered by default.

135 changes: 69 additions & 66 deletions src/librustc/hir/lowering.rs

Large diffs are not rendered by default.

106 changes: 43 additions & 63 deletions src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use syntax::ext::base::MacroKind;
use syntax_pos::{Span, DUMMY_SP};

use crate::hir::*;
use crate::hir::DefKind;
use crate::hir::itemlikevisit::ItemLikeVisitor;
use crate::hir::print::Nested;
use crate::util::nodemap::FxHashMap;
Expand Down Expand Up @@ -309,74 +310,68 @@ impl<'hir> Map<'hir> {
self.definitions.as_local_node_id(def_id.to_def_id()).unwrap()
}

pub fn describe_def(&self, node_id: NodeId) -> Option<Def> {
fn def_kind(&self, node_id: NodeId) -> Option<DefKind> {
let node = if let Some(node) = self.find(node_id) {
node
} else {
return None
};

match node {
Some(match node {
Node::Item(item) => {
let def_id = || self.local_def_id_from_hir_id(item.hir_id);

match item.node {
ItemKind::Static(..) => Some(Def::Static(def_id())),
ItemKind::Const(..) => Some(Def::Const(def_id())),
ItemKind::Fn(..) => Some(Def::Fn(def_id())),
ItemKind::Mod(..) => Some(Def::Mod(def_id())),
ItemKind::Existential(..) => Some(Def::Existential(def_id())),
ItemKind::Ty(..) => Some(Def::TyAlias(def_id())),
ItemKind::Enum(..) => Some(Def::Enum(def_id())),
ItemKind::Struct(..) => Some(Def::Struct(def_id())),
ItemKind::Union(..) => Some(Def::Union(def_id())),
ItemKind::Trait(..) => Some(Def::Trait(def_id())),
ItemKind::TraitAlias(..) => Some(Def::TraitAlias(def_id())),
ItemKind::Static(..) => DefKind::Static,
ItemKind::Const(..) => DefKind::Const,
ItemKind::Fn(..) => DefKind::Fn,
ItemKind::Mod(..) => DefKind::Mod,
ItemKind::Existential(..) => DefKind::Existential,
ItemKind::Ty(..) => DefKind::TyAlias,
ItemKind::Enum(..) => DefKind::Enum,
ItemKind::Struct(..) => DefKind::Struct,
ItemKind::Union(..) => DefKind::Union,
ItemKind::Trait(..) => DefKind::Trait,
ItemKind::TraitAlias(..) => DefKind::TraitAlias,
ItemKind::ExternCrate(_) |
ItemKind::Use(..) |
ItemKind::ForeignMod(..) |
ItemKind::GlobalAsm(..) |
ItemKind::Impl(..) => None,
ItemKind::Impl(..) => return None,
}
}
Node::ForeignItem(item) => {
let def_id = self.local_def_id_from_hir_id(item.hir_id);
match item.node {
ForeignItemKind::Fn(..) => Some(Def::Fn(def_id)),
ForeignItemKind::Static(..) => Some(Def::Static(def_id)),
ForeignItemKind::Type => Some(Def::ForeignTy(def_id)),
ForeignItemKind::Fn(..) => DefKind::Fn,
ForeignItemKind::Static(..) => DefKind::Static,
ForeignItemKind::Type => DefKind::ForeignTy,
}
}
Node::TraitItem(item) => {
let def_id = self.local_def_id_from_hir_id(item.hir_id);
match item.node {
TraitItemKind::Const(..) => Some(Def::AssociatedConst(def_id)),
TraitItemKind::Method(..) => Some(Def::Method(def_id)),
TraitItemKind::Type(..) => Some(Def::AssociatedTy(def_id)),
TraitItemKind::Const(..) => DefKind::AssociatedConst,
TraitItemKind::Method(..) => DefKind::Method,
TraitItemKind::Type(..) => DefKind::AssociatedTy,
}
}
Node::ImplItem(item) => {
let def_id = self.local_def_id_from_hir_id(item.hir_id);
match item.node {
ImplItemKind::Const(..) => Some(Def::AssociatedConst(def_id)),
ImplItemKind::Method(..) => Some(Def::Method(def_id)),
ImplItemKind::Type(..) => Some(Def::AssociatedTy(def_id)),
ImplItemKind::Existential(..) => Some(Def::AssociatedExistential(def_id)),
ImplItemKind::Const(..) => DefKind::AssociatedConst,
ImplItemKind::Method(..) => DefKind::Method,
ImplItemKind::Type(..) => DefKind::AssociatedTy,
ImplItemKind::Existential(..) => DefKind::AssociatedExistential,
}
}
Node::Variant(variant) => {
let def_id = self.local_def_id_from_hir_id(variant.node.id);
Some(Def::Variant(def_id))
}
Node::Variant(_) => DefKind::Variant,
Node::Ctor(variant_data) => {
// FIXME(eddyb) is this even possible, if we have a `Node::Ctor`?
if variant_data.ctor_hir_id().is_none() {
return None;
}
let ctor_of = match self.find(self.get_parent_node(node_id)) {
Some(Node::Item(..)) => def::CtorOf::Struct,
Some(Node::Variant(..)) => def::CtorOf::Variant,
_ => unreachable!(),
};
variant_data.ctor_hir_id()
.map(|hir_id| self.local_def_id_from_hir_id(hir_id))
.map(|def_id| Def::Ctor(def_id, ctor_of, def::CtorKind::from_hir(variant_data)))
DefKind::Ctor(ctor_of, def::CtorKind::from_hir(variant_data))
}
Node::AnonConst(_) |
Node::Field(_) |
Expand All @@ -387,35 +382,20 @@ impl<'hir> Map<'hir> {
Node::TraitRef(_) |
Node::Pat(_) |
Node::Binding(_) |
Node::Local(_) |
Node::Lifetime(_) |
Node::Visibility(_) |
Node::Block(_) |
Node::Crate => None,
Node::Local(local) => {
Some(Def::Local(local.hir_id))
}
Node::MacroDef(macro_def) => {
Some(Def::Macro(self.local_def_id_from_hir_id(macro_def.hir_id),
MacroKind::Bang))
}
Node::Crate => return None,
Node::MacroDef(_) => DefKind::Macro(MacroKind::Bang),
Node::GenericParam(param) => {
Some(match param.kind {
GenericParamKind::Lifetime { .. } => {
Def::Local(param.hir_id)
},
GenericParamKind::Type { .. } => Def::TyParam(
self.local_def_id_from_hir_id(param.hir_id)),
GenericParamKind::Const { .. } => Def::ConstParam(
self.local_def_id_from_hir_id(param.hir_id)),
})
match param.kind {
GenericParamKind::Lifetime { .. } => return None,
GenericParamKind::Type { .. } => DefKind::TyParam,
GenericParamKind::Const { .. } => DefKind::ConstParam,
}
}
}
}

// FIXME(@ljedrz): replace the NodeId variant
pub fn describe_def_by_hir_id(&self, hir_id: HirId) -> Option<Def> {
let node_id = self.hir_to_node_id(hir_id);
self.describe_def(node_id)
})
}

fn entry_count(&self) -> usize {
Expand Down Expand Up @@ -1473,11 +1453,11 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
node_id_to_string(map, node_id, include_id)
}

pub fn describe_def(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option<Def> {
pub fn def_kind(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option<DefKind> {
if let Some(node_id) = tcx.hir().as_local_node_id(def_id) {
tcx.hir().describe_def(node_id)
tcx.hir().def_kind(node_id)
} else {
bug!("Calling local describe_def query provider for upstream DefId: {:?}",
bug!("Calling local def_kind query provider for upstream DefId: {:?}",
def_id)
}
}
45 changes: 24 additions & 21 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub use self::PrimTy::*;
pub use self::UnOp::*;
pub use self::UnsafeSource::*;

use crate::hir::def::Def;
use crate::hir::def::{Res, DefKind};
use crate::hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
use crate::util::nodemap::{NodeMap, FxHashSet};
use crate::mir::mono::Linkage;
Expand Down Expand Up @@ -296,8 +296,8 @@ impl Lifetime {
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
pub struct Path {
pub span: Span,
/// The definition that the path resolved to.
pub def: Def,
/// The resolution for the path.
pub res: Res,
/// The segments in the path: the things separated by `::`.
pub segments: HirVec<PathSegment>,
}
Expand Down Expand Up @@ -327,13 +327,13 @@ pub struct PathSegment {
/// The identifier portion of this path segment.
#[stable_hasher(project(name))]
pub ident: Ident,
// `id` and `def` are optional. We currently only use these in save-analysis,
// `id` and `res` are optional. We currently only use these in save-analysis,
// any path segments without these will not have save-analysis info and
// therefore will not have 'jump to def' in IDEs, but otherwise will not be
// affected. (In general, we don't bother to get the defs for synthesized
// segments, only for segments which have come from the AST).
pub hir_id: Option<HirId>,
pub def: Option<Def>,
pub res: Option<Res>,

/// Type/lifetime parameters attached to this path. They come in
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
Expand All @@ -355,7 +355,7 @@ impl PathSegment {
PathSegment {
ident,
hir_id: None,
def: None,
res: None,
infer_types: true,
args: None,
}
Expand All @@ -364,14 +364,14 @@ impl PathSegment {
pub fn new(
ident: Ident,
hir_id: Option<HirId>,
def: Option<Def>,
res: Option<Res>,
args: GenericArgs,
infer_types: bool,
) -> Self {
PathSegment {
ident,
hir_id,
def,
res,
infer_types,
args: if args.is_empty() {
None
Expand Down Expand Up @@ -1393,8 +1393,11 @@ impl Expr {
pub fn is_place_expr(&self) -> bool {
match self.node {
ExprKind::Path(QPath::Resolved(_, ref path)) => {
match path.def {
Def::Local(..) | Def::Upvar(..) | Def::Static(..) | Def::Err => true,
match path.res {
Res::Local(..)
| Res::Upvar(..)
| Res::Def(DefKind::Static, _)
| Res::Err => true,
_ => false,
}
}
Expand Down Expand Up @@ -2139,7 +2142,7 @@ pub enum UseKind {
/// resolve maps each TraitRef's ref_id to its defining trait; that's all
/// that the ref_id is for. Note that ref_id's value is not the NodeId of the
/// trait being referred to but just a unique NodeId that serves as a key
/// within the DefMap.
/// within the ResMap.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct TraitRef {
pub path: Path,
Expand All @@ -2151,10 +2154,10 @@ pub struct TraitRef {
impl TraitRef {
/// Gets the `DefId` of the referenced trait. It _must_ actually be a trait or trait alias.
pub fn trait_def_id(&self) -> DefId {
match self.path.def {
Def::Trait(did) => did,
Def::TraitAlias(did) => did,
Def::Err => {
match self.path.res {
Res::Def(DefKind::Trait, did) => did,
Res::Def(DefKind::TraitAlias, did) => did,
Res::Err => {
FatalError.raise();
}
_ => unreachable!(),
Expand Down Expand Up @@ -2476,7 +2479,7 @@ impl ForeignItemKind {
#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
pub struct Freevar<Id = HirId> {
/// The variable being accessed free.
pub def: def::Def<Id>,
pub res: Res<Id>,

// First span where it is accessed (there can be multiple).
pub span: Span
Expand All @@ -2485,15 +2488,15 @@ pub struct Freevar<Id = HirId> {
impl<Id: fmt::Debug + Copy> Freevar<Id> {
pub fn map_id<R>(self, map: impl FnMut(Id) -> R) -> Freevar<R> {
Freevar {
def: self.def.map_id(map),
res: self.res.map_id(map),
span: self.span,
}
}

pub fn var_id(&self) -> Id {
match self.def {
Def::Local(id) | Def::Upvar(id, ..) => id,
_ => bug!("Freevar::var_id: bad def ({:?})", self.def)
match self.res {
Res::Local(id) | Res::Upvar(id, ..) => id,
_ => bug!("Freevar::var_id: bad res ({:?})", self.res)
}
}
}
Expand All @@ -2518,7 +2521,7 @@ pub type GlobMap = NodeMap<FxHashSet<Name>>;

pub fn provide(providers: &mut Providers<'_>) {
check_attr::provide(providers);
providers.describe_def = map::describe_def;
providers.def_kind = map::def_kind;
}

#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
Expand Down
12 changes: 6 additions & 6 deletions src/librustc/hir/pat_util.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::hir::def::{CtorOf, Def};
use crate::hir::def::{CtorOf, Res, DefKind};
use crate::hir::def_id::DefId;
use crate::hir::{self, HirId, PatKind};
use syntax::ast;
Expand Down Expand Up @@ -54,8 +54,8 @@ impl hir::Pat {
PatKind::Path(hir::QPath::Resolved(_, ref path)) |
PatKind::TupleStruct(hir::QPath::Resolved(_, ref path), ..) |
PatKind::Struct(hir::QPath::Resolved(_, ref path), ..) => {
match path.def {
Def::Variant(..) => true,
match path.res {
Res::Def(DefKind::Variant, _) => true,
_ => false
}
}
Expand Down Expand Up @@ -124,9 +124,9 @@ impl hir::Pat {
PatKind::Path(hir::QPath::Resolved(_, ref path)) |
PatKind::TupleStruct(hir::QPath::Resolved(_, ref path), ..) |
PatKind::Struct(hir::QPath::Resolved(_, ref path), ..) => {
match path.def {
Def::Variant(id) => variants.push(id),
Def::Ctor(id, CtorOf::Variant, ..) => variants.push(id),
match path.res {
Res::Def(DefKind::Variant, id) => variants.push(id),
Res::Def(DefKind::Ctor(CtorOf::Variant, ..), id) => variants.push(id),
_ => ()
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/lint/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyTyKind {

fn lint_ty_kind_usage(cx: &LateContext<'_, '_>, segment: &PathSegment) -> bool {
if segment.ident.as_str() == "TyKind" {
if let Some(def) = segment.def {
if let Some(did) = def.opt_def_id() {
if let Some(res) = segment.res {
if let Some(did) = res.opt_def_id() {
return cx.match_def_path(did, &["rustc", "ty", "sty", "TyKind"]);
}
}
Expand All @@ -184,7 +184,7 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_, '_>, ty: &Ty) -> Option<String> {
match &ty.node {
TyKind::Path(qpath) => {
if let QPath::Resolved(_, path) = qpath {
let did = path.def.opt_def_id()?;
let did = path.res.opt_def_id()?;
if cx.match_def_path(did, &["rustc", "ty", "Ty"]) {
return Some(format!("Ty{}", gen_args(path.segments.last().unwrap())));
} else if cx.match_def_path(did, &["rustc", "ty", "context", "TyCtxt"]) {
Expand Down
Loading

0 comments on commit 13fde05

Please sign in to comment.