mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-16 14:07:04 +00:00
Auto merge of #60462 - eddyb:def-1-a-mere-resolution, r=petrochenkov
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
This commit is contained in:
commit
13fde05b12
@ -11,12 +11,12 @@ use std::fmt::Debug;
|
||||
|
||||
use self::Namespace::*;
|
||||
|
||||
/// Encodes if a `Def::Ctor` is the constructor of an enum variant or a struct.
|
||||
/// Encodes if a `DefKind::Ctor` is the constructor of an enum variant or a struct.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
|
||||
pub enum CtorOf {
|
||||
/// This `Def::Ctor` is a synthesized constructor of a tuple or unit struct.
|
||||
/// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit struct.
|
||||
Struct,
|
||||
/// This `Def::Ctor` is a synthesized constructor of a tuple or unit variant.
|
||||
/// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit variant.
|
||||
Variant,
|
||||
}
|
||||
|
||||
@ -45,41 +45,99 @@ pub enum NonMacroAttrKind {
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
|
||||
pub enum Def<Id = hir::HirId> {
|
||||
pub enum DefKind {
|
||||
// Type namespace
|
||||
Mod(DefId),
|
||||
/// `DefId` refers to the struct itself, `Def::Ctor` refers to its constructor if it exists.
|
||||
Struct(DefId),
|
||||
Union(DefId),
|
||||
Enum(DefId),
|
||||
/// `DefId` refers to the variant itself, `Def::Ctor` refers to its constructor if it exists.
|
||||
Variant(DefId),
|
||||
Trait(DefId),
|
||||
Mod,
|
||||
/// Refers to the struct itself, `DefKind::Ctor` refers to its constructor if it exists.
|
||||
Struct,
|
||||
Union,
|
||||
Enum,
|
||||
/// Refers to the variant itself, `DefKind::Ctor` refers to its constructor if it exists.
|
||||
Variant,
|
||||
Trait,
|
||||
/// `existential type Foo: Bar;`
|
||||
Existential(DefId),
|
||||
Existential,
|
||||
/// `type Foo = Bar;`
|
||||
TyAlias(DefId),
|
||||
ForeignTy(DefId),
|
||||
TraitAlias(DefId),
|
||||
AssociatedTy(DefId),
|
||||
TyAlias,
|
||||
ForeignTy,
|
||||
TraitAlias,
|
||||
AssociatedTy,
|
||||
/// `existential type Foo: Bar;`
|
||||
AssociatedExistential(DefId),
|
||||
AssociatedExistential,
|
||||
TyParam,
|
||||
|
||||
// Value namespace
|
||||
Fn,
|
||||
Const,
|
||||
ConstParam,
|
||||
Static,
|
||||
/// Refers to the struct or enum variant's constructor.
|
||||
Ctor(CtorOf, CtorKind),
|
||||
Method,
|
||||
AssociatedConst,
|
||||
|
||||
// Macro namespace
|
||||
Macro(MacroKind),
|
||||
}
|
||||
|
||||
impl DefKind {
|
||||
pub fn descr(self) -> &'static str {
|
||||
match self {
|
||||
DefKind::Fn => "function",
|
||||
DefKind::Mod => "module",
|
||||
DefKind::Static => "static",
|
||||
DefKind::Enum => "enum",
|
||||
DefKind::Variant => "variant",
|
||||
DefKind::Ctor(CtorOf::Variant, CtorKind::Fn) => "tuple variant",
|
||||
DefKind::Ctor(CtorOf::Variant, CtorKind::Const) => "unit variant",
|
||||
DefKind::Ctor(CtorOf::Variant, CtorKind::Fictive) => "struct variant",
|
||||
DefKind::Struct => "struct",
|
||||
DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct",
|
||||
DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",
|
||||
DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive) =>
|
||||
bug!("impossible struct constructor"),
|
||||
DefKind::Existential => "existential type",
|
||||
DefKind::TyAlias => "type alias",
|
||||
DefKind::TraitAlias => "trait alias",
|
||||
DefKind::AssociatedTy => "associated type",
|
||||
DefKind::AssociatedExistential => "associated existential type",
|
||||
DefKind::Union => "union",
|
||||
DefKind::Trait => "trait",
|
||||
DefKind::ForeignTy => "foreign type",
|
||||
DefKind::Method => "method",
|
||||
DefKind::Const => "constant",
|
||||
DefKind::AssociatedConst => "associated constant",
|
||||
DefKind::TyParam => "type parameter",
|
||||
DefKind::ConstParam => "const parameter",
|
||||
DefKind::Macro(macro_kind) => macro_kind.descr(),
|
||||
}
|
||||
}
|
||||
|
||||
/// An English article for the def.
|
||||
pub fn article(&self) -> &'static str {
|
||||
match *self {
|
||||
DefKind::AssociatedTy
|
||||
| DefKind::AssociatedConst
|
||||
| DefKind::AssociatedExistential
|
||||
| DefKind::Enum
|
||||
| DefKind::Existential => "an",
|
||||
DefKind::Macro(macro_kind) => macro_kind.article(),
|
||||
_ => "a",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
|
||||
pub enum Res<Id = hir::HirId> {
|
||||
Def(DefKind, DefId),
|
||||
|
||||
// Type namespace
|
||||
PrimTy(hir::PrimTy),
|
||||
TyParam(DefId),
|
||||
SelfTy(Option<DefId> /* trait */, Option<DefId> /* impl */),
|
||||
ToolMod, // e.g., `rustfmt` in `#[rustfmt::skip]`
|
||||
|
||||
// Value namespace
|
||||
Fn(DefId),
|
||||
Const(DefId),
|
||||
ConstParam(DefId),
|
||||
Static(DefId),
|
||||
/// `DefId` refers to the struct or enum variant's constructor.
|
||||
Ctor(DefId, CtorOf, CtorKind),
|
||||
SelfCtor(DefId /* impl */), // `DefId` refers to the impl
|
||||
Method(DefId),
|
||||
AssociatedConst(DefId),
|
||||
|
||||
Local(Id),
|
||||
Upvar(Id, // `HirId` of closed over local
|
||||
usize, // index in the `freevars` list of the closure
|
||||
@ -87,46 +145,45 @@ pub enum Def<Id = hir::HirId> {
|
||||
Label(ast::NodeId),
|
||||
|
||||
// Macro namespace
|
||||
Macro(DefId, MacroKind),
|
||||
NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]`
|
||||
|
||||
// Both namespaces
|
||||
// All namespaces
|
||||
Err,
|
||||
}
|
||||
|
||||
/// The result of resolving a path before lowering to HIR.
|
||||
/// `base_def` is definition of resolved part of the
|
||||
/// `base_res` is the resolution of the resolved part of the
|
||||
/// path, `unresolved_segments` is the number of unresolved
|
||||
/// segments.
|
||||
///
|
||||
/// ```text
|
||||
/// module::Type::AssocX::AssocY::MethodOrAssocType
|
||||
/// ^~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/// base_def unresolved_segments = 3
|
||||
/// base_res unresolved_segments = 3
|
||||
///
|
||||
/// <T as Trait>::AssocX::AssocY::MethodOrAssocType
|
||||
/// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/// base_def unresolved_segments = 2
|
||||
/// base_res unresolved_segments = 2
|
||||
/// ```
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct PathResolution {
|
||||
base_def: Def<NodeId>,
|
||||
base_res: Res<NodeId>,
|
||||
unresolved_segments: usize,
|
||||
}
|
||||
|
||||
impl PathResolution {
|
||||
pub fn new(def: Def<NodeId>) -> Self {
|
||||
PathResolution { base_def: def, unresolved_segments: 0 }
|
||||
pub fn new(res: Res<NodeId>) -> Self {
|
||||
PathResolution { base_res: res, unresolved_segments: 0 }
|
||||
}
|
||||
|
||||
pub fn with_unresolved_segments(def: Def<NodeId>, mut unresolved_segments: usize) -> Self {
|
||||
if def == Def::Err { unresolved_segments = 0 }
|
||||
PathResolution { base_def: def, unresolved_segments: unresolved_segments }
|
||||
pub fn with_unresolved_segments(res: Res<NodeId>, mut unresolved_segments: usize) -> Self {
|
||||
if res == Res::Err { unresolved_segments = 0 }
|
||||
PathResolution { base_res: res, unresolved_segments: unresolved_segments }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn base_def(&self) -> Def<NodeId> {
|
||||
self.base_def
|
||||
pub fn base_res(&self) -> Res<NodeId> {
|
||||
self.base_res
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -213,7 +270,7 @@ impl<T> PerNS<Option<T>> {
|
||||
}
|
||||
|
||||
/// Definition mapping
|
||||
pub type DefMap = NodeMap<PathResolution>;
|
||||
pub type ResMap = NodeMap<PathResolution>;
|
||||
|
||||
/// This is the replacement export map. It maps a module to all of the exports
|
||||
/// within.
|
||||
@ -227,9 +284,9 @@ pub type ImportMap = NodeMap<PerNS<Option<PathResolution>>>;
|
||||
pub struct Export<Id> {
|
||||
/// The name of the target.
|
||||
pub ident: ast::Ident,
|
||||
/// The definition of the target.
|
||||
pub def: Def<Id>,
|
||||
/// The span of the target definition.
|
||||
/// The resolution of the target.
|
||||
pub res: Res<Id>,
|
||||
/// The span of the target.
|
||||
pub span: Span,
|
||||
/// The visibility of the export.
|
||||
/// We include non-`pub` exports for hygienic macros that get used from extern crates.
|
||||
@ -240,7 +297,7 @@ impl<Id> Export<Id> {
|
||||
pub fn map_id<R>(self, map: impl FnMut(Id) -> R) -> Export<R> {
|
||||
Export {
|
||||
ident: self.ident,
|
||||
def: self.def.map_id(map),
|
||||
res: self.res.map_id(map),
|
||||
span: self.span,
|
||||
vis: self.vis,
|
||||
}
|
||||
@ -277,140 +334,85 @@ impl NonMacroAttrKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Id> Def<Id> {
|
||||
impl<Id> Res<Id> {
|
||||
/// Return the `DefId` of this `Def` if it has an id, else panic.
|
||||
pub fn def_id(&self) -> DefId
|
||||
where
|
||||
Id: Debug,
|
||||
{
|
||||
self.opt_def_id().unwrap_or_else(|| {
|
||||
bug!("attempted .def_id() on invalid def: {:?}", self)
|
||||
bug!("attempted .def_id() on invalid res: {:?}", self)
|
||||
})
|
||||
}
|
||||
|
||||
/// Return `Some(..)` with the `DefId` of this `Def` if it has a id, else `None`.
|
||||
/// Return `Some(..)` with the `DefId` of this `Res` if it has a id, else `None`.
|
||||
pub fn opt_def_id(&self) -> Option<DefId> {
|
||||
match *self {
|
||||
Def::Fn(id) | Def::Mod(id) | Def::Static(id) |
|
||||
Def::Variant(id) | Def::Ctor(id, ..) | Def::Enum(id) |
|
||||
Def::TyAlias(id) | Def::TraitAlias(id) |
|
||||
Def::AssociatedTy(id) | Def::TyParam(id) | Def::ConstParam(id) | Def::Struct(id) |
|
||||
Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
|
||||
Def::AssociatedConst(id) | Def::Macro(id, ..) |
|
||||
Def::Existential(id) | Def::AssociatedExistential(id) | Def::ForeignTy(id) => {
|
||||
Some(id)
|
||||
}
|
||||
Res::Def(_, id) => Some(id),
|
||||
|
||||
Def::Local(..) |
|
||||
Def::Upvar(..) |
|
||||
Def::Label(..) |
|
||||
Def::PrimTy(..) |
|
||||
Def::SelfTy(..) |
|
||||
Def::SelfCtor(..) |
|
||||
Def::ToolMod |
|
||||
Def::NonMacroAttr(..) |
|
||||
Def::Err => {
|
||||
Res::Local(..) |
|
||||
Res::Upvar(..) |
|
||||
Res::Label(..) |
|
||||
Res::PrimTy(..) |
|
||||
Res::SelfTy(..) |
|
||||
Res::SelfCtor(..) |
|
||||
Res::ToolMod |
|
||||
Res::NonMacroAttr(..) |
|
||||
Res::Err => {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the `DefId` of this `Def` if it represents a module.
|
||||
/// Return the `DefId` of this `Res` if it represents a module.
|
||||
pub fn mod_def_id(&self) -> Option<DefId> {
|
||||
match *self {
|
||||
Def::Mod(id) => Some(id),
|
||||
Res::Def(DefKind::Mod, id) => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// A human readable name for the def kind ("function", "module", etc.).
|
||||
/// A human readable name for the res kind ("function", "module", etc.).
|
||||
pub fn kind_name(&self) -> &'static str {
|
||||
match *self {
|
||||
Def::Fn(..) => "function",
|
||||
Def::Mod(..) => "module",
|
||||
Def::Static(..) => "static",
|
||||
Def::Enum(..) => "enum",
|
||||
Def::Variant(..) => "variant",
|
||||
Def::Ctor(_, CtorOf::Variant, CtorKind::Fn) => "tuple variant",
|
||||
Def::Ctor(_, CtorOf::Variant, CtorKind::Const) => "unit variant",
|
||||
Def::Ctor(_, CtorOf::Variant, CtorKind::Fictive) => "struct variant",
|
||||
Def::Struct(..) => "struct",
|
||||
Def::Ctor(_, CtorOf::Struct, CtorKind::Fn) => "tuple struct",
|
||||
Def::Ctor(_, CtorOf::Struct, CtorKind::Const) => "unit struct",
|
||||
Def::Ctor(_, CtorOf::Struct, CtorKind::Fictive) =>
|
||||
bug!("impossible struct constructor"),
|
||||
Def::Existential(..) => "existential type",
|
||||
Def::TyAlias(..) => "type alias",
|
||||
Def::TraitAlias(..) => "trait alias",
|
||||
Def::AssociatedTy(..) => "associated type",
|
||||
Def::AssociatedExistential(..) => "associated existential type",
|
||||
Def::SelfCtor(..) => "self constructor",
|
||||
Def::Union(..) => "union",
|
||||
Def::Trait(..) => "trait",
|
||||
Def::ForeignTy(..) => "foreign type",
|
||||
Def::Method(..) => "method",
|
||||
Def::Const(..) => "constant",
|
||||
Def::AssociatedConst(..) => "associated constant",
|
||||
Def::TyParam(..) => "type parameter",
|
||||
Def::ConstParam(..) => "const parameter",
|
||||
Def::PrimTy(..) => "builtin type",
|
||||
Def::Local(..) => "local variable",
|
||||
Def::Upvar(..) => "closure capture",
|
||||
Def::Label(..) => "label",
|
||||
Def::SelfTy(..) => "self type",
|
||||
Def::Macro(.., macro_kind) => macro_kind.descr(),
|
||||
Def::ToolMod => "tool module",
|
||||
Def::NonMacroAttr(attr_kind) => attr_kind.descr(),
|
||||
Def::Err => "unresolved item",
|
||||
Res::Def(kind, _) => kind.descr(),
|
||||
Res::SelfCtor(..) => "self constructor",
|
||||
Res::PrimTy(..) => "builtin type",
|
||||
Res::Local(..) => "local variable",
|
||||
Res::Upvar(..) => "closure capture",
|
||||
Res::Label(..) => "label",
|
||||
Res::SelfTy(..) => "self type",
|
||||
Res::ToolMod => "tool module",
|
||||
Res::NonMacroAttr(attr_kind) => attr_kind.descr(),
|
||||
Res::Err => "unresolved item",
|
||||
}
|
||||
}
|
||||
|
||||
/// An English article for the def.
|
||||
/// An English article for the res.
|
||||
pub fn article(&self) -> &'static str {
|
||||
match *self {
|
||||
Def::AssociatedTy(..) | Def::AssociatedConst(..) | Def::AssociatedExistential(..) |
|
||||
Def::Enum(..) | Def::Existential(..) | Def::Err => "an",
|
||||
Def::Macro(.., macro_kind) => macro_kind.article(),
|
||||
Res::Def(kind, _) => kind.article(),
|
||||
Res::Err => "an",
|
||||
_ => "a",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_id<R>(self, mut map: impl FnMut(Id) -> R) -> Def<R> {
|
||||
pub fn map_id<R>(self, mut map: impl FnMut(Id) -> R) -> Res<R> {
|
||||
match self {
|
||||
Def::Fn(id) => Def::Fn(id),
|
||||
Def::Mod(id) => Def::Mod(id),
|
||||
Def::Static(id) => Def::Static(id),
|
||||
Def::Enum(id) => Def::Enum(id),
|
||||
Def::Variant(id) => Def::Variant(id),
|
||||
Def::Ctor(a, b, c) => Def::Ctor(a, b, c),
|
||||
Def::Struct(id) => Def::Struct(id),
|
||||
Def::Existential(id) => Def::Existential(id),
|
||||
Def::TyAlias(id) => Def::TyAlias(id),
|
||||
Def::TraitAlias(id) => Def::TraitAlias(id),
|
||||
Def::AssociatedTy(id) => Def::AssociatedTy(id),
|
||||
Def::AssociatedExistential(id) => Def::AssociatedExistential(id),
|
||||
Def::SelfCtor(id) => Def::SelfCtor(id),
|
||||
Def::Union(id) => Def::Union(id),
|
||||
Def::Trait(id) => Def::Trait(id),
|
||||
Def::ForeignTy(id) => Def::ForeignTy(id),
|
||||
Def::Method(id) => Def::Method(id),
|
||||
Def::Const(id) => Def::Const(id),
|
||||
Def::AssociatedConst(id) => Def::AssociatedConst(id),
|
||||
Def::TyParam(id) => Def::TyParam(id),
|
||||
Def::ConstParam(id) => Def::ConstParam(id),
|
||||
Def::PrimTy(id) => Def::PrimTy(id),
|
||||
Def::Local(id) => Def::Local(map(id)),
|
||||
Def::Upvar(id, index, closure) => Def::Upvar(
|
||||
Res::Def(kind, id) => Res::Def(kind, id),
|
||||
Res::SelfCtor(id) => Res::SelfCtor(id),
|
||||
Res::PrimTy(id) => Res::PrimTy(id),
|
||||
Res::Local(id) => Res::Local(map(id)),
|
||||
Res::Upvar(id, index, closure) => Res::Upvar(
|
||||
map(id),
|
||||
index,
|
||||
closure
|
||||
),
|
||||
Def::Label(id) => Def::Label(id),
|
||||
Def::SelfTy(a, b) => Def::SelfTy(a, b),
|
||||
Def::Macro(id, macro_kind) => Def::Macro(id, macro_kind),
|
||||
Def::ToolMod => Def::ToolMod,
|
||||
Def::NonMacroAttr(attr_kind) => Def::NonMacroAttr(attr_kind),
|
||||
Def::Err => Def::Err,
|
||||
Res::Label(id) => Res::Label(id),
|
||||
Res::SelfTy(a, b) => Res::SelfTy(a, b),
|
||||
Res::ToolMod => Res::ToolMod,
|
||||
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
|
||||
Res::Err => Res::Err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ use crate::hir::{self, ParamName};
|
||||
use crate::hir::HirVec;
|
||||
use crate::hir::map::{DefKey, DefPathData, Definitions};
|
||||
use crate::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX};
|
||||
use crate::hir::def::{Def, PathResolution, PerNS};
|
||||
use crate::hir::def::{Res, DefKind, PathResolution, PerNS};
|
||||
use crate::hir::{GenericArg, ConstArg};
|
||||
use crate::lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
|
||||
ELIDED_LIFETIMES_IN_PATHS};
|
||||
@ -812,29 +812,29 @@ impl<'a> LoweringContext<'a> {
|
||||
self.lower_node_id(self.sess.next_node_id())
|
||||
}
|
||||
|
||||
fn lower_def(&mut self, def: Def<NodeId>) -> Def {
|
||||
def.map_id(|id| {
|
||||
fn lower_res(&mut self, res: Res<NodeId>) -> Res {
|
||||
res.map_id(|id| {
|
||||
self.lower_node_id_generic(id, |_| {
|
||||
panic!("expected node_id to be lowered already for def {:#?}", def)
|
||||
panic!("expected node_id to be lowered already for res {:#?}", res)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn expect_full_def(&mut self, id: NodeId) -> Def<NodeId> {
|
||||
self.resolver.get_resolution(id).map_or(Def::Err, |pr| {
|
||||
fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
|
||||
self.resolver.get_resolution(id).map_or(Res::Err, |pr| {
|
||||
if pr.unresolved_segments() != 0 {
|
||||
bug!("path not fully resolved: {:?}", pr);
|
||||
}
|
||||
pr.base_def()
|
||||
pr.base_res()
|
||||
})
|
||||
}
|
||||
|
||||
fn expect_full_def_from_use(&mut self, id: NodeId) -> impl Iterator<Item = Def<NodeId>> {
|
||||
fn expect_full_res_from_use(&mut self, id: NodeId) -> impl Iterator<Item = Res<NodeId>> {
|
||||
self.resolver.get_import(id).present_items().map(|pr| {
|
||||
if pr.unresolved_segments() != 0 {
|
||||
bug!("path not fully resolved: {:?}", pr);
|
||||
}
|
||||
pr.base_def()
|
||||
pr.base_res()
|
||||
})
|
||||
}
|
||||
|
||||
@ -1136,7 +1136,7 @@ impl<'a> LoweringContext<'a> {
|
||||
output,
|
||||
c_variadic: false
|
||||
};
|
||||
// Lower the arguments before the body otherwise the body will call `lower_def` expecting
|
||||
// Lower the arguments before the body otherwise the body will call `lower_res` expecting
|
||||
// the argument to have been assigned an id already.
|
||||
let arguments = self.lower_args(Some(&decl));
|
||||
let body_expr = body(self);
|
||||
@ -1251,7 +1251,7 @@ impl<'a> LoweringContext<'a> {
|
||||
fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination {
|
||||
let target_id = match destination {
|
||||
Some((id, _)) => {
|
||||
if let Def::Label(loop_id) = self.expect_full_def(id) {
|
||||
if let Res::Label(loop_id) = self.expect_full_res(id) {
|
||||
Ok(self.lower_node_id(loop_id))
|
||||
} else {
|
||||
Err(hir::LoopIdError::UnresolvedLabel)
|
||||
@ -1417,12 +1417,12 @@ impl<'a> LoweringContext<'a> {
|
||||
return ty;
|
||||
}
|
||||
TyKind::ImplicitSelf => {
|
||||
let def = self.expect_full_def(t.id);
|
||||
let def = self.lower_def(def);
|
||||
let res = self.expect_full_res(t.id);
|
||||
let res = self.lower_res(res);
|
||||
hir::TyKind::Path(hir::QPath::Resolved(
|
||||
None,
|
||||
P(hir::Path {
|
||||
def,
|
||||
res,
|
||||
segments: hir_vec![hir::PathSegment::from_ident(
|
||||
keywords::SelfUpper.ident()
|
||||
)],
|
||||
@ -1500,7 +1500,7 @@ impl<'a> LoweringContext<'a> {
|
||||
None,
|
||||
P(hir::Path {
|
||||
span,
|
||||
def: Def::TyParam(DefId::local(def_index)),
|
||||
res: Res::Def(DefKind::TyParam, DefId::local(def_index)),
|
||||
segments: hir_vec![hir::PathSegment::from_ident(ident)],
|
||||
}),
|
||||
))
|
||||
@ -1844,11 +1844,11 @@ impl<'a> LoweringContext<'a> {
|
||||
|
||||
let resolution = self.resolver
|
||||
.get_resolution(id)
|
||||
.unwrap_or_else(|| PathResolution::new(Def::Err));
|
||||
.unwrap_or_else(|| PathResolution::new(Res::Err));
|
||||
|
||||
let proj_start = p.segments.len() - resolution.unresolved_segments();
|
||||
let path = P(hir::Path {
|
||||
def: self.lower_def(resolution.base_def()),
|
||||
res: self.lower_res(resolution.base_res()),
|
||||
segments: p.segments[..proj_start]
|
||||
.iter()
|
||||
.enumerate()
|
||||
@ -1869,40 +1869,43 @@ impl<'a> LoweringContext<'a> {
|
||||
krate: def_id.krate,
|
||||
index: this.def_key(def_id).parent.expect("missing parent"),
|
||||
};
|
||||
let type_def_id = match resolution.base_def() {
|
||||
Def::AssociatedTy(def_id) if i + 2 == proj_start => {
|
||||
let type_def_id = match resolution.base_res() {
|
||||
Res::Def(DefKind::AssociatedTy, def_id) if i + 2 == proj_start => {
|
||||
Some(parent_def_id(self, def_id))
|
||||
}
|
||||
Def::Variant(def_id) if i + 1 == proj_start => {
|
||||
Res::Def(DefKind::Variant, def_id) if i + 1 == proj_start => {
|
||||
Some(parent_def_id(self, def_id))
|
||||
}
|
||||
Def::Struct(def_id)
|
||||
| Def::Union(def_id)
|
||||
| Def::Enum(def_id)
|
||||
| Def::TyAlias(def_id)
|
||||
| Def::Trait(def_id) if i + 1 == proj_start =>
|
||||
Res::Def(DefKind::Struct, def_id)
|
||||
| Res::Def(DefKind::Union, def_id)
|
||||
| Res::Def(DefKind::Enum, def_id)
|
||||
| Res::Def(DefKind::TyAlias, def_id)
|
||||
| Res::Def(DefKind::Trait, def_id) if i + 1 == proj_start =>
|
||||
{
|
||||
Some(def_id)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
let parenthesized_generic_args = match resolution.base_def() {
|
||||
let parenthesized_generic_args = match resolution.base_res() {
|
||||
// `a::b::Trait(Args)`
|
||||
Def::Trait(..) if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
|
||||
Res::Def(DefKind::Trait, _)
|
||||
if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
|
||||
// `a::b::Trait(Args)::TraitItem`
|
||||
Def::Method(..) | Def::AssociatedConst(..) | Def::AssociatedTy(..)
|
||||
Res::Def(DefKind::Method, _)
|
||||
| Res::Def(DefKind::AssociatedConst, _)
|
||||
| Res::Def(DefKind::AssociatedTy, _)
|
||||
if i + 2 == proj_start =>
|
||||
{
|
||||
ParenthesizedGenericArgs::Ok
|
||||
}
|
||||
// Avoid duplicated errors.
|
||||
Def::Err => ParenthesizedGenericArgs::Ok,
|
||||
Res::Err => ParenthesizedGenericArgs::Ok,
|
||||
// An error
|
||||
Def::Struct(..)
|
||||
| Def::Enum(..)
|
||||
| Def::Union(..)
|
||||
| Def::TyAlias(..)
|
||||
| Def::Variant(..) if i + 1 == proj_start =>
|
||||
Res::Def(DefKind::Struct, _)
|
||||
| Res::Def(DefKind::Enum, _)
|
||||
| Res::Def(DefKind::Union, _)
|
||||
| Res::Def(DefKind::TyAlias, _)
|
||||
| Res::Def(DefKind::Variant, _) if i + 1 == proj_start =>
|
||||
{
|
||||
ParenthesizedGenericArgs::Err
|
||||
}
|
||||
@ -1997,13 +2000,13 @@ impl<'a> LoweringContext<'a> {
|
||||
|
||||
fn lower_path_extra(
|
||||
&mut self,
|
||||
def: Def,
|
||||
res: Res,
|
||||
p: &Path,
|
||||
param_mode: ParamMode,
|
||||
explicit_owner: Option<NodeId>,
|
||||
) -> hir::Path {
|
||||
hir::Path {
|
||||
def,
|
||||
res,
|
||||
segments: p.segments
|
||||
.iter()
|
||||
.map(|segment| {
|
||||
@ -2023,9 +2026,9 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
|
||||
fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path {
|
||||
let def = self.expect_full_def(id);
|
||||
let def = self.lower_def(def);
|
||||
self.lower_path_extra(def, p, param_mode, None)
|
||||
let res = self.expect_full_res(id);
|
||||
let res = self.lower_res(res);
|
||||
self.lower_path_extra(res, p, param_mode, None)
|
||||
}
|
||||
|
||||
fn lower_path_segment(
|
||||
@ -2156,7 +2159,7 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
let def = self.expect_full_def(segment.id);
|
||||
let res = self.expect_full_res(segment.id);
|
||||
let id = if let Some(owner) = explicit_owner {
|
||||
self.lower_node_id_with_owner(segment.id, owner)
|
||||
} else {
|
||||
@ -2170,7 +2173,7 @@ impl<'a> LoweringContext<'a> {
|
||||
hir::PathSegment::new(
|
||||
segment.ident,
|
||||
Some(id),
|
||||
Some(self.lower_def(def)),
|
||||
Some(self.lower_res(res)),
|
||||
generic_args,
|
||||
infer_types,
|
||||
)
|
||||
@ -2788,9 +2791,9 @@ impl<'a> LoweringContext<'a> {
|
||||
if path.segments.len() == 1
|
||||
&& bound_pred.bound_generic_params.is_empty() =>
|
||||
{
|
||||
if let Some(Def::TyParam(def_id)) = self.resolver
|
||||
if let Some(Res::Def(DefKind::TyParam, def_id)) = self.resolver
|
||||
.get_resolution(bound_pred.bounded_ty.id)
|
||||
.map(|d| d.base_def())
|
||||
.map(|d| d.base_res())
|
||||
{
|
||||
if let Some(node_id) =
|
||||
self.resolver.definitions().as_local_node_id(def_id)
|
||||
@ -3242,7 +3245,7 @@ impl<'a> LoweringContext<'a> {
|
||||
});
|
||||
|
||||
if let Some(ref trait_ref) = trait_ref {
|
||||
if let Def::Trait(def_id) = trait_ref.path.def {
|
||||
if let Res::Def(DefKind::Trait, def_id) = trait_ref.path.res {
|
||||
this.trait_impls.entry(def_id).or_default().push(
|
||||
lowered_trait_impl_id);
|
||||
}
|
||||
@ -3339,17 +3342,17 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
let mut defs = self.expect_full_def_from_use(id);
|
||||
let mut resolutions = self.expect_full_res_from_use(id);
|
||||
// We want to return *something* from this function, so hold onto the first item
|
||||
// for later.
|
||||
let ret_def = self.lower_def(defs.next().unwrap_or(Def::Err));
|
||||
let ret_res = self.lower_res(resolutions.next().unwrap_or(Res::Err));
|
||||
|
||||
// Here, we are looping over namespaces, if they exist for the definition
|
||||
// being imported. We only handle type and value namespaces because we
|
||||
// won't be dealing with macros in the rest of the compiler.
|
||||
// Essentially a single `use` which imports two names is desugared into
|
||||
// two imports.
|
||||
for (def, &new_node_id) in defs.zip([id1, id2].iter()) {
|
||||
for (res, &new_node_id) in resolutions.zip([id1, id2].iter()) {
|
||||
let vis = vis.clone();
|
||||
let ident = ident.clone();
|
||||
let mut path = path.clone();
|
||||
@ -3360,9 +3363,9 @@ impl<'a> LoweringContext<'a> {
|
||||
|
||||
self.with_hir_id_owner(new_node_id, |this| {
|
||||
let new_id = this.lower_node_id(new_node_id);
|
||||
let def = this.lower_def(def);
|
||||
let res = this.lower_res(res);
|
||||
let path =
|
||||
this.lower_path_extra(def, &path, ParamMode::Explicit, None);
|
||||
this.lower_path_extra(res, &path, ParamMode::Explicit, None);
|
||||
let item = hir::ItemKind::Use(P(path), hir::UseKind::Single);
|
||||
let vis_kind = match vis.node {
|
||||
hir::VisibilityKind::Public => hir::VisibilityKind::Public,
|
||||
@ -3392,7 +3395,7 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
|
||||
let path =
|
||||
P(self.lower_path_extra(ret_def, &path, ParamMode::Explicit, None));
|
||||
P(self.lower_path_extra(ret_res, &path, ParamMode::Explicit, None));
|
||||
hir::ItemKind::Use(path, hir::UseKind::Single)
|
||||
}
|
||||
UseTreeKind::Glob => {
|
||||
@ -3510,9 +3513,9 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
let def = self.expect_full_def_from_use(id).next().unwrap_or(Def::Err);
|
||||
let def = self.lower_def(def);
|
||||
let path = P(self.lower_path_extra(def, &prefix, ParamMode::Explicit, None));
|
||||
let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
|
||||
let res = self.lower_res(res);
|
||||
let path = P(self.lower_path_extra(res, &prefix, ParamMode::Explicit, None));
|
||||
hir::ItemKind::Use(path, hir::UseKind::ListStem)
|
||||
}
|
||||
}
|
||||
@ -3766,7 +3769,7 @@ impl<'a> LoweringContext<'a> {
|
||||
},
|
||||
UseTreeKind::Glob => {}
|
||||
UseTreeKind::Simple(_, id1, id2) => {
|
||||
for (_, &id) in self.expect_full_def_from_use(base_id)
|
||||
for (_, &id) in self.expect_full_res_from_use(base_id)
|
||||
.skip(1)
|
||||
.zip([id1, id2].iter())
|
||||
{
|
||||
@ -3943,11 +3946,11 @@ impl<'a> LoweringContext<'a> {
|
||||
let node = match p.node {
|
||||
PatKind::Wild => hir::PatKind::Wild,
|
||||
PatKind::Ident(ref binding_mode, ident, ref sub) => {
|
||||
match self.resolver.get_resolution(p.id).map(|d| d.base_def()) {
|
||||
match self.resolver.get_resolution(p.id).map(|d| d.base_res()) {
|
||||
// `None` can occur in body-less function signatures
|
||||
def @ None | def @ Some(Def::Local(_)) => {
|
||||
let canonical_id = match def {
|
||||
Some(Def::Local(id)) => id,
|
||||
res @ None | res @ Some(Res::Local(_)) => {
|
||||
let canonical_id = match res {
|
||||
Some(Res::Local(id)) => id,
|
||||
_ => p.id,
|
||||
};
|
||||
|
||||
@ -3958,11 +3961,11 @@ impl<'a> LoweringContext<'a> {
|
||||
sub.as_ref().map(|x| self.lower_pat(x)),
|
||||
)
|
||||
}
|
||||
Some(def) => hir::PatKind::Path(hir::QPath::Resolved(
|
||||
Some(res) => hir::PatKind::Path(hir::QPath::Resolved(
|
||||
None,
|
||||
P(hir::Path {
|
||||
span: ident.span,
|
||||
def: self.lower_def(def),
|
||||
res: self.lower_res(res),
|
||||
segments: hir_vec![hir::PathSegment::from_ident(ident)],
|
||||
}),
|
||||
)),
|
||||
@ -4954,11 +4957,11 @@ impl<'a> LoweringContext<'a> {
|
||||
} else {
|
||||
self.lower_node_id(id)
|
||||
};
|
||||
let def = self.expect_full_def(id);
|
||||
let def = self.lower_def(def);
|
||||
let res = self.expect_full_res(id);
|
||||
let res = self.lower_res(res);
|
||||
hir::VisibilityKind::Restricted {
|
||||
path: P(self.lower_path_extra(
|
||||
def,
|
||||
res,
|
||||
path,
|
||||
ParamMode::Explicit,
|
||||
explicit_owner,
|
||||
@ -5070,7 +5073,7 @@ impl<'a> LoweringContext<'a> {
|
||||
None,
|
||||
P(hir::Path {
|
||||
span,
|
||||
def: Def::Local(binding),
|
||||
res: Res::Local(binding),
|
||||
segments: hir_vec![hir::PathSegment::from_ident(ident)],
|
||||
}),
|
||||
));
|
||||
@ -5276,8 +5279,8 @@ impl<'a> LoweringContext<'a> {
|
||||
let node = match qpath {
|
||||
hir::QPath::Resolved(None, path) => {
|
||||
// Turn trait object paths into `TyKind::TraitObject` instead.
|
||||
match path.def {
|
||||
Def::Trait(_) | Def::TraitAlias(_) => {
|
||||
match path.res {
|
||||
Res::Def(DefKind::Trait, _) | Res::Def(DefKind::TraitAlias, _) => {
|
||||
let principal = hir::PolyTraitRef {
|
||||
bound_generic_params: hir::HirVec::new(),
|
||||
trait_ref: hir::TraitRef {
|
||||
|
@ -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;
|
||||
@ -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(_) |
|
||||
@ -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 {
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
@ -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>,
|
||||
}
|
||||
@ -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
|
||||
@ -355,7 +355,7 @@ impl PathSegment {
|
||||
PathSegment {
|
||||
ident,
|
||||
hir_id: None,
|
||||
def: None,
|
||||
res: None,
|
||||
infer_types: true,
|
||||
args: None,
|
||||
}
|
||||
@ -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
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
@ -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,
|
||||
@ -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!(),
|
||||
@ -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
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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)]
|
||||
|
@ -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;
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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),
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
@ -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"]);
|
||||
}
|
||||
}
|
||||
@ -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"]) {
|
||||
|
@ -7,7 +7,7 @@ use crate::hir::{self, PatKind, TyKind};
|
||||
use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
|
||||
use crate::hir::itemlikevisit::ItemLikeVisitor;
|
||||
|
||||
use crate::hir::def::{CtorOf, Def};
|
||||
use crate::hir::def::{CtorOf, Res, DefKind};
|
||||
use crate::hir::CodegenFnAttrFlags;
|
||||
use crate::hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use crate::lint;
|
||||
@ -68,15 +68,17 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_definition(&mut self, def: Def) {
|
||||
match def {
|
||||
Def::Const(_) | Def::AssociatedConst(..) | Def::TyAlias(_) => {
|
||||
self.check_def_id(def.def_id());
|
||||
fn handle_res(&mut self, res: Res) {
|
||||
match res {
|
||||
Res::Def(DefKind::Const, _)
|
||||
| Res::Def(DefKind::AssociatedConst, _)
|
||||
| Res::Def(DefKind::TyAlias, _) => {
|
||||
self.check_def_id(res.def_id());
|
||||
}
|
||||
_ if self.in_pat => {},
|
||||
Def::PrimTy(..) | Def::SelfTy(..) | Def::SelfCtor(..) |
|
||||
Def::Local(..) | Def::Upvar(..) => {}
|
||||
Def::Ctor(ctor_def_id, CtorOf::Variant, ..) => {
|
||||
Res::PrimTy(..) | Res::SelfTy(..) | Res::SelfCtor(..) |
|
||||
Res::Local(..) | Res::Upvar(..) => {}
|
||||
Res::Def(DefKind::Ctor(CtorOf::Variant, ..), ctor_def_id) => {
|
||||
let variant_id = self.tcx.parent(ctor_def_id).unwrap();
|
||||
let enum_id = self.tcx.parent(variant_id).unwrap();
|
||||
self.check_def_id(enum_id);
|
||||
@ -84,16 +86,16 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||
self.check_def_id(variant_id);
|
||||
}
|
||||
}
|
||||
Def::Variant(variant_id) => {
|
||||
Res::Def(DefKind::Variant, variant_id) => {
|
||||
let enum_id = self.tcx.parent(variant_id).unwrap();
|
||||
self.check_def_id(enum_id);
|
||||
if !self.ignore_variant_stack.contains(&variant_id) {
|
||||
self.check_def_id(variant_id);
|
||||
}
|
||||
}
|
||||
Def::ToolMod | Def::NonMacroAttr(..) | Def::Err => {}
|
||||
Res::ToolMod | Res::NonMacroAttr(..) | Res::Err => {}
|
||||
_ => {
|
||||
self.check_def_id(def.def_id());
|
||||
self.check_def_id(res.def_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -117,10 +119,10 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_field_pattern_match(&mut self, lhs: &hir::Pat, def: Def,
|
||||
fn handle_field_pattern_match(&mut self, lhs: &hir::Pat, res: Res,
|
||||
pats: &[source_map::Spanned<hir::FieldPat>]) {
|
||||
let variant = match self.tables.node_type(lhs.hir_id).sty {
|
||||
ty::Adt(adt, _) => adt.variant_of_def(def),
|
||||
ty::Adt(adt, _) => adt.variant_of_res(res),
|
||||
_ => span_bug!(lhs.span, "non-ADT in struct pattern")
|
||||
};
|
||||
for pat in pats {
|
||||
@ -229,8 +231,8 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
||||
match expr.node {
|
||||
hir::ExprKind::Path(ref qpath @ hir::QPath::TypeRelative(..)) => {
|
||||
let def = self.tables.qpath_def(qpath, expr.hir_id);
|
||||
self.handle_definition(def);
|
||||
let res = self.tables.qpath_res(qpath, expr.hir_id);
|
||||
self.handle_res(res);
|
||||
}
|
||||
hir::ExprKind::MethodCall(..) => {
|
||||
self.lookup_and_handle_method(expr.hir_id);
|
||||
@ -268,11 +270,11 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
|
||||
fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
|
||||
match pat.node {
|
||||
PatKind::Struct(hir::QPath::Resolved(_, ref path), ref fields, _) => {
|
||||
self.handle_field_pattern_match(pat, path.def, fields);
|
||||
self.handle_field_pattern_match(pat, path.res, fields);
|
||||
}
|
||||
PatKind::Path(ref qpath @ hir::QPath::TypeRelative(..)) => {
|
||||
let def = self.tables.qpath_def(qpath, pat.hir_id);
|
||||
self.handle_definition(def);
|
||||
let res = self.tables.qpath_res(qpath, pat.hir_id);
|
||||
self.handle_res(res);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
@ -283,7 +285,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, path: &'tcx hir::Path, _: hir::HirId) {
|
||||
self.handle_definition(path.def);
|
||||
self.handle_res(path.res);
|
||||
intravisit::walk_path(self, path);
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ pub use self::MatchMode::*;
|
||||
use self::TrackMatchMode::*;
|
||||
use self::OverloadedCallType::*;
|
||||
|
||||
use crate::hir::def::{CtorOf, Def};
|
||||
use crate::hir::def::{CtorOf, Res, DefKind};
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::infer::InferCtxt;
|
||||
use crate::middle::mem_categorization as mc;
|
||||
@ -862,8 +862,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
|
||||
// Each match binding is effectively an assignment to the
|
||||
// binding being produced.
|
||||
let def = Def::Local(canonical_id);
|
||||
if let Ok(ref binding_cmt) = mc.cat_def(pat.hir_id, pat.span, pat_ty, def) {
|
||||
let def = Res::Local(canonical_id);
|
||||
if let Ok(ref binding_cmt) = mc.cat_res(pat.hir_id, pat.span, pat_ty, def) {
|
||||
delegate.mutate(pat.hir_id, pat.span, binding_cmt, MutateMode::Init);
|
||||
}
|
||||
|
||||
@ -898,23 +898,27 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
PatKind::Struct(ref qpath, ..) => qpath,
|
||||
_ => return
|
||||
};
|
||||
let def = mc.tables.qpath_def(qpath, pat.hir_id);
|
||||
match def {
|
||||
Def::Ctor(variant_ctor_did, CtorOf::Variant, ..) => {
|
||||
let res = mc.tables.qpath_res(qpath, pat.hir_id);
|
||||
match res {
|
||||
Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_did) => {
|
||||
let variant_did = mc.tcx.parent(variant_ctor_did).unwrap();
|
||||
let downcast_cmt = mc.cat_downcast_if_needed(pat, cmt_pat, variant_did);
|
||||
|
||||
debug!("variantctor downcast_cmt={:?} pat={:?}", downcast_cmt, pat);
|
||||
delegate.matched_pat(pat, &downcast_cmt, match_mode);
|
||||
}
|
||||
Def::Variant(variant_did) => {
|
||||
Res::Def(DefKind::Variant, variant_did) => {
|
||||
let downcast_cmt = mc.cat_downcast_if_needed(pat, cmt_pat, variant_did);
|
||||
|
||||
debug!("variant downcast_cmt={:?} pat={:?}", downcast_cmt, pat);
|
||||
delegate.matched_pat(pat, &downcast_cmt, match_mode);
|
||||
}
|
||||
Def::Struct(..) | Def::Ctor(..) | Def::Union(..) |
|
||||
Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => {
|
||||
Res::Def(DefKind::Struct, _)
|
||||
| Res::Def(DefKind::Ctor(..), _)
|
||||
| Res::Def(DefKind::Union, _)
|
||||
| Res::Def(DefKind::TyAlias, _)
|
||||
| Res::Def(DefKind::AssociatedTy, _)
|
||||
| Res::SelfTy(..) => {
|
||||
debug!("struct cmt_pat={:?} pat={:?}", cmt_pat, pat);
|
||||
delegate.matched_pat(pat, &cmt_pat, match_mode);
|
||||
}
|
||||
@ -968,7 +972,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
// caller's perspective
|
||||
let var_hir_id = upvar.var_id();
|
||||
let var_ty = self.mc.node_ty(var_hir_id)?;
|
||||
self.mc.cat_def(closure_hir_id, closure_span, var_ty, upvar.def)
|
||||
self.mc.cat_res(closure_hir_id, closure_span, var_ty, upvar.res)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::hir::def::Def;
|
||||
use crate::hir::def::{Res, DefKind};
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::ty::{self, Ty, TyCtxt};
|
||||
use crate::ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx};
|
||||
@ -152,12 +152,12 @@ impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
||||
let def = if let hir::ExprKind::Path(ref qpath) = expr.node {
|
||||
self.tables.qpath_def(qpath, expr.hir_id)
|
||||
let res = if let hir::ExprKind::Path(ref qpath) = expr.node {
|
||||
self.tables.qpath_res(qpath, expr.hir_id)
|
||||
} else {
|
||||
Def::Err
|
||||
Res::Err
|
||||
};
|
||||
if let Def::Fn(did) = def {
|
||||
if let Res::Def(DefKind::Fn, did) = res {
|
||||
if self.def_id_is_transmute(did) {
|
||||
let typ = self.tables.node_type(expr.hir_id);
|
||||
let sig = typ.fn_sig(self.tcx);
|
||||
|
@ -467,8 +467,8 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
match expr.node {
|
||||
// live nodes required for uses or definitions of variables:
|
||||
hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => {
|
||||
debug!("expr {}: path that leads to {:?}", expr.hir_id, path.def);
|
||||
if let Def::Local(..) = path.def {
|
||||
debug!("expr {}: path that leads to {:?}", expr.hir_id, path.res);
|
||||
if let Res::Local(..) = path.res {
|
||||
ir.add_live_node_for_node(expr.hir_id, ExprNode(expr.span));
|
||||
}
|
||||
intravisit::walk_expr(ir, expr);
|
||||
@ -485,7 +485,7 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
let mut call_caps = Vec::new();
|
||||
ir.tcx.with_freevars(expr.hir_id, |freevars| {
|
||||
call_caps.extend(freevars.iter().filter_map(|fv| {
|
||||
if let Def::Local(rv) = fv.def {
|
||||
if let Res::Local(rv) = fv.res {
|
||||
let fv_ln = ir.add_live_node(FreeVarNode(fv.span));
|
||||
Some(CaptureInfo { ln: fv_ln, var_hid: rv })
|
||||
} else {
|
||||
@ -1347,8 +1347,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
|
||||
fn access_path(&mut self, hir_id: HirId, path: &hir::Path, succ: LiveNode, acc: u32)
|
||||
-> LiveNode {
|
||||
match path.def {
|
||||
Def::Local(hid) => {
|
||||
match path.res {
|
||||
Res::Local(hid) => {
|
||||
let nid = self.ir.tcx.hir().hir_to_node_id(hid);
|
||||
self.access_var(hir_id, nid, succ, acc, path.span)
|
||||
}
|
||||
@ -1541,7 +1541,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
fn check_place(&mut self, expr: &'tcx Expr) {
|
||||
match expr.node {
|
||||
hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => {
|
||||
if let Def::Local(var_hid) = path.def {
|
||||
if let Res::Local(var_hid) = path.res {
|
||||
// Assignment to an immutable variable or argument: only legal
|
||||
// if there is no later assignment. If this local is actually
|
||||
// mutable, then check for a reassignment to flag the mutability
|
||||
|
@ -62,7 +62,7 @@ use crate::middle::region;
|
||||
use crate::hir::def_id::{DefId, LocalDefId};
|
||||
use crate::hir::Node;
|
||||
use crate::infer::InferCtxt;
|
||||
use crate::hir::def::{CtorOf, Def, CtorKind};
|
||||
use crate::hir::def::{CtorOf, Res, DefKind, CtorKind};
|
||||
use crate::ty::adjustment;
|
||||
use crate::ty::{self, DefIdTree, Ty, TyCtxt};
|
||||
use crate::ty::fold::TypeFoldable;
|
||||
@ -665,8 +665,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
hir::ExprKind::Path(ref qpath) => {
|
||||
let def = self.tables.qpath_def(qpath, expr.hir_id);
|
||||
self.cat_def(expr.hir_id, expr.span, expr_ty, def)
|
||||
let res = self.tables.qpath_res(qpath, expr.hir_id);
|
||||
self.cat_res(expr.hir_id, expr.span, expr_ty, res)
|
||||
}
|
||||
|
||||
hir::ExprKind::Type(ref e, _) => {
|
||||
@ -689,22 +689,27 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cat_def(&self,
|
||||
pub fn cat_res(&self,
|
||||
hir_id: hir::HirId,
|
||||
span: Span,
|
||||
expr_ty: Ty<'tcx>,
|
||||
def: Def)
|
||||
res: Res)
|
||||
-> McResult<cmt_<'tcx>> {
|
||||
debug!("cat_def: id={:?} expr={:?} def={:?}",
|
||||
hir_id, expr_ty, def);
|
||||
debug!("cat_res: id={:?} expr={:?} def={:?}",
|
||||
hir_id, expr_ty, res);
|
||||
|
||||
match def {
|
||||
Def::Ctor(..) | Def::Const(..) | Def::ConstParam(..) |
|
||||
Def::AssociatedConst(..) | Def::Fn(..) | Def::Method(..) | Def::SelfCtor(..) => {
|
||||
match res {
|
||||
Res::Def(DefKind::Ctor(..), _)
|
||||
| Res::Def(DefKind::Const, _)
|
||||
| Res::Def(DefKind::ConstParam, _)
|
||||
| Res::Def(DefKind::AssociatedConst, _)
|
||||
| Res::Def(DefKind::Fn, _)
|
||||
| Res::Def(DefKind::Method, _)
|
||||
| Res::SelfCtor(..) => {
|
||||
Ok(self.cat_rvalue_node(hir_id, span, expr_ty))
|
||||
}
|
||||
|
||||
Def::Static(def_id) => {
|
||||
Res::Def(DefKind::Static, def_id) => {
|
||||
// `#[thread_local]` statics may not outlive the current function, but
|
||||
// they also cannot be moved out of.
|
||||
let is_thread_local = self.tcx.get_attrs(def_id)[..]
|
||||
@ -731,12 +736,12 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
Def::Upvar(var_id, _, fn_node_id) => {
|
||||
Res::Upvar(var_id, _, fn_node_id) => {
|
||||
let var_nid = self.tcx.hir().hir_to_node_id(var_id);
|
||||
self.cat_upvar(hir_id, span, var_nid, fn_node_id)
|
||||
}
|
||||
|
||||
Def::Local(vid) => {
|
||||
Res::Local(vid) => {
|
||||
let vnid = self.tcx.hir().hir_to_node_id(vid);
|
||||
Ok(cmt_ {
|
||||
hir_id,
|
||||
@ -1268,20 +1273,21 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
|
||||
match pat.node {
|
||||
PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
|
||||
let def = self.tables.qpath_def(qpath, pat.hir_id);
|
||||
let (cmt, expected_len) = match def {
|
||||
Def::Err => {
|
||||
let res = self.tables.qpath_res(qpath, pat.hir_id);
|
||||
let (cmt, expected_len) = match res {
|
||||
Res::Err => {
|
||||
debug!("access to unresolvable pattern {:?}", pat);
|
||||
return Err(())
|
||||
}
|
||||
Def::Ctor(variant_ctor_did, CtorOf::Variant, CtorKind::Fn) => {
|
||||
Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), variant_ctor_did) => {
|
||||
let variant_did = self.tcx.parent(variant_ctor_did).unwrap();
|
||||
let enum_did = self.tcx.parent(variant_did).unwrap();
|
||||
(self.cat_downcast_if_needed(pat, cmt, variant_did),
|
||||
self.tcx.adt_def(enum_did)
|
||||
.variant_with_ctor_id(variant_ctor_did).fields.len())
|
||||
}
|
||||
Def::Ctor(_, CtorOf::Struct, CtorKind::Fn) | Def::SelfCtor(..) => {
|
||||
Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), _)
|
||||
| Res::SelfCtor(..) => {
|
||||
let ty = self.pat_ty_unadjusted(&pat)?;
|
||||
match ty.sty {
|
||||
ty::Adt(adt_def, _) => {
|
||||
@ -1310,17 +1316,17 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
|
||||
PatKind::Struct(ref qpath, ref field_pats, _) => {
|
||||
// {f1: p1, ..., fN: pN}
|
||||
let def = self.tables.qpath_def(qpath, pat.hir_id);
|
||||
let cmt = match def {
|
||||
Def::Err => {
|
||||
let res = self.tables.qpath_res(qpath, pat.hir_id);
|
||||
let cmt = match res {
|
||||
Res::Err => {
|
||||
debug!("access to unresolvable pattern {:?}", pat);
|
||||
return Err(())
|
||||
}
|
||||
Def::Ctor(variant_ctor_did, CtorOf::Variant, _) => {
|
||||
Res::Def(DefKind::Ctor(CtorOf::Variant, _), variant_ctor_did) => {
|
||||
let variant_did = self.tcx.parent(variant_ctor_did).unwrap();
|
||||
self.cat_downcast_if_needed(pat, cmt, variant_did)
|
||||
}
|
||||
Def::Variant(variant_did) => {
|
||||
Res::Def(DefKind::Variant, variant_did) => {
|
||||
self.cat_downcast_if_needed(pat, cmt, variant_did)
|
||||
}
|
||||
_ => cmt,
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
use crate::hir::{CodegenFnAttrs, CodegenFnAttrFlags};
|
||||
use crate::hir::Node;
|
||||
use crate::hir::def::Def;
|
||||
use crate::hir::def::{Res, DefKind};
|
||||
use crate::hir::def_id::{DefId, CrateNum};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use crate::ty::{self, TyCtxt};
|
||||
@ -92,32 +92,33 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
||||
let def = match expr.node {
|
||||
let res = match expr.node {
|
||||
hir::ExprKind::Path(ref qpath) => {
|
||||
Some(self.tables.qpath_def(qpath, expr.hir_id))
|
||||
Some(self.tables.qpath_res(qpath, expr.hir_id))
|
||||
}
|
||||
hir::ExprKind::MethodCall(..) => {
|
||||
self.tables.type_dependent_def(expr.hir_id)
|
||||
.map(|(kind, def_id)| Res::Def(kind, def_id))
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
|
||||
match def {
|
||||
Some(Def::Local(hir_id)) | Some(Def::Upvar(hir_id, ..)) => {
|
||||
match res {
|
||||
Some(Res::Local(hir_id)) | Some(Res::Upvar(hir_id, ..)) => {
|
||||
self.reachable_symbols.insert(hir_id);
|
||||
}
|
||||
Some(def) => {
|
||||
if let Some((hir_id, def_id)) = def.opt_def_id().and_then(|def_id| {
|
||||
Some(res) => {
|
||||
if let Some((hir_id, def_id)) = res.opt_def_id().and_then(|def_id| {
|
||||
self.tcx.hir().as_local_hir_id(def_id).map(|hir_id| (hir_id, def_id))
|
||||
}) {
|
||||
if self.def_id_represents_local_inlined_item(def_id) {
|
||||
self.worklist.push(hir_id);
|
||||
} else {
|
||||
match def {
|
||||
match res {
|
||||
// If this path leads to a constant, then we need to
|
||||
// recurse into the constant to continue finding
|
||||
// items that are reachable.
|
||||
Def::Const(..) | Def::AssociatedConst(..) => {
|
||||
Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssociatedConst, _) => {
|
||||
self.worklist.push(hir_id);
|
||||
}
|
||||
|
||||
@ -356,8 +357,8 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a,
|
||||
if !self.access_levels.is_reachable(item.hir_id) {
|
||||
self.worklist.extend(impl_item_refs.iter().map(|ii_ref| ii_ref.id.hir_id));
|
||||
|
||||
let trait_def_id = match trait_ref.path.def {
|
||||
Def::Trait(def_id) => def_id,
|
||||
let trait_def_id = match trait_ref.path.res {
|
||||
Res::Def(DefKind::Trait, def_id) => def_id,
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
//! used between functions, and they operate in a purely top-down
|
||||
//! way. Therefore, we break lifetime name resolution into a separate pass.
|
||||
|
||||
use crate::hir::def::Def;
|
||||
use crate::hir::def::{Res, DefKind};
|
||||
use crate::hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
|
||||
use crate::hir::map::Map;
|
||||
use crate::hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, Node, ParamName};
|
||||
@ -925,7 +925,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
for (i, segment) in path.segments.iter().enumerate() {
|
||||
let depth = path.segments.len() - i - 1;
|
||||
if let Some(ref args) = segment.args {
|
||||
self.visit_segment_args(path.def, depth, args);
|
||||
self.visit_segment_args(path.res, depth, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1360,12 +1360,12 @@ fn object_lifetime_defaults_for_item(
|
||||
continue;
|
||||
}
|
||||
|
||||
let def = match data.bounded_ty.node {
|
||||
hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.def,
|
||||
let res = match data.bounded_ty.node {
|
||||
hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.res,
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
if def == Def::TyParam(param_def_id) {
|
||||
if res == Res::Def(DefKind::TyParam, param_def_id) {
|
||||
add_bounds(&mut set, &data.bounds);
|
||||
}
|
||||
}
|
||||
@ -1890,7 +1890,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_segment_args(&mut self, def: Def, depth: usize, generic_args: &'tcx hir::GenericArgs) {
|
||||
fn visit_segment_args(&mut self, res: Res, depth: usize, generic_args: &'tcx hir::GenericArgs) {
|
||||
if generic_args.parenthesized {
|
||||
let was_in_fn_syntax = self.is_in_fn_syntax;
|
||||
self.is_in_fn_syntax = true;
|
||||
@ -1928,14 +1928,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
index: def_key.parent.expect("missing parent"),
|
||||
}
|
||||
};
|
||||
let type_def_id = match def {
|
||||
Def::AssociatedTy(def_id) if depth == 1 => Some(parent_def_id(self, def_id)),
|
||||
Def::Variant(def_id) if depth == 0 => Some(parent_def_id(self, def_id)),
|
||||
Def::Struct(def_id)
|
||||
| Def::Union(def_id)
|
||||
| Def::Enum(def_id)
|
||||
| Def::TyAlias(def_id)
|
||||
| Def::Trait(def_id) if depth == 0 =>
|
||||
let type_def_id = match res {
|
||||
Res::Def(DefKind::AssociatedTy, def_id)
|
||||
if depth == 1 => Some(parent_def_id(self, def_id)),
|
||||
Res::Def(DefKind::Variant, def_id)
|
||||
if depth == 0 => Some(parent_def_id(self, def_id)),
|
||||
Res::Def(DefKind::Struct, def_id)
|
||||
| Res::Def(DefKind::Union, def_id)
|
||||
| Res::Def(DefKind::Enum, def_id)
|
||||
| Res::Def(DefKind::TyAlias, def_id)
|
||||
| Res::Def(DefKind::Trait, def_id) if depth == 0 =>
|
||||
{
|
||||
Some(def_id)
|
||||
}
|
||||
@ -2126,8 +2128,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
if has_self {
|
||||
// Look for `self: &'a Self` - also desugared from `&'a self`,
|
||||
// and if that matches, use it for elision and return early.
|
||||
let is_self_ty = |def: Def| {
|
||||
if let Def::SelfTy(..) = def {
|
||||
let is_self_ty = |res: Res| {
|
||||
if let Res::SelfTy(..) = res {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2135,12 +2137,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
// to the way elision rules were originally specified.
|
||||
let impl_self = impl_self.map(|ty| &ty.node);
|
||||
if let Some(&hir::TyKind::Path(hir::QPath::Resolved(None, ref path))) = impl_self {
|
||||
match path.def {
|
||||
match path.res {
|
||||
// Whitelist the types that unambiguously always
|
||||
// result in the same type constructor being used
|
||||
// (it can't differ between `Self` and `self`).
|
||||
Def::Struct(_) | Def::Union(_) | Def::Enum(_) | Def::PrimTy(_) => {
|
||||
return def == path.def
|
||||
Res::Def(DefKind::Struct, _)
|
||||
| Res::Def(DefKind::Union, _)
|
||||
| Res::Def(DefKind::Enum, _)
|
||||
| Res::PrimTy(_) => {
|
||||
return res == path.res
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -2151,7 +2156,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
|
||||
if let hir::TyKind::Rptr(lifetime_ref, ref mt) = inputs[0].node {
|
||||
if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = mt.ty.node {
|
||||
if is_self_ty(path.def) {
|
||||
if is_self_ty(path.res) {
|
||||
if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.hir_id) {
|
||||
let scope = Scope::Elision {
|
||||
elide: Elide::Exact(lifetime),
|
||||
|
@ -5,7 +5,7 @@ pub use self::StabilityLevel::*;
|
||||
|
||||
use crate::lint::{self, Lint, in_derive_expansion};
|
||||
use crate::hir::{self, Item, Generics, StructField, Variant, HirId};
|
||||
use crate::hir::def::Def;
|
||||
use crate::hir::def::{Res, DefKind};
|
||||
use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
|
||||
use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
|
||||
use crate::ty::query::Providers;
|
||||
@ -525,10 +525,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
// See issue #38412.
|
||||
fn skip_stability_check_due_to_privacy(self, mut def_id: DefId) -> bool {
|
||||
// Check if `def_id` is a trait method.
|
||||
match self.describe_def(def_id) {
|
||||
Some(Def::Method(_)) |
|
||||
Some(Def::AssociatedTy(_)) |
|
||||
Some(Def::AssociatedConst(_)) => {
|
||||
match self.def_kind(def_id) {
|
||||
Some(DefKind::Method) |
|
||||
Some(DefKind::AssociatedTy) |
|
||||
Some(DefKind::AssociatedConst) => {
|
||||
if let ty::TraitContainer(trait_def_id) = self.associated_item(def_id).container {
|
||||
// Trait methods do not declare visibility (even
|
||||
// for visibility info in cstore). Use containing
|
||||
@ -779,7 +779,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
||||
// individually as it's possible to have a stable trait with unstable
|
||||
// items.
|
||||
hir::ItemKind::Impl(.., Some(ref t), _, ref impl_item_refs) => {
|
||||
if let Def::Trait(trait_did) = t.path.def {
|
||||
if let Res::Def(DefKind::Trait, trait_did) = t.path.res {
|
||||
for impl_item_ref in impl_item_refs {
|
||||
let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
|
||||
let trait_item_def_id = self.tcx.associated_items(trait_did)
|
||||
@ -820,7 +820,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, path: &'tcx hir::Path, id: hir::HirId) {
|
||||
if let Some(def_id) = path.def.opt_def_id() {
|
||||
if let Some(def_id) = path.res.opt_def_id() {
|
||||
self.tcx.check_stability(def_id, Some(id), path.span)
|
||||
}
|
||||
intravisit::walk_path(self, path)
|
||||
|
@ -469,7 +469,7 @@ rustc_queries! {
|
||||
cache { true }
|
||||
}
|
||||
|
||||
query describe_def(_: DefId) -> Option<Def> {}
|
||||
query def_kind(_: DefId) -> Option<DefKind> {}
|
||||
query def_span(_: DefId) -> Span {
|
||||
// FIXME(mw): DefSpans are not really inputs since they are derived from
|
||||
// HIR. But at the moment HIR hashing still contains some hacks that allow
|
||||
|
@ -10,7 +10,7 @@ use crate::session::config::{BorrowckMode, OutputFilenames};
|
||||
use crate::session::config::CrateType;
|
||||
use crate::middle;
|
||||
use crate::hir::{TraitCandidate, HirId, ItemKind, ItemLocalId, Node};
|
||||
use crate::hir::def::{Def, Export};
|
||||
use crate::hir::def::{Res, DefKind, Export};
|
||||
use crate::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
|
||||
use crate::hir::map as hir_map;
|
||||
use crate::hir::map::DefPathHash;
|
||||
@ -44,6 +44,7 @@ use crate::ty::steal::Steal;
|
||||
use crate::ty::subst::{UserSubsts, UnpackedKind};
|
||||
use crate::ty::{BoundVar, BindingMode};
|
||||
use crate::ty::CanonicalPolyFnSig;
|
||||
use crate::util::common::ErrorReported;
|
||||
use crate::util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap, ItemLocalSet};
|
||||
use crate::util::nodemap::{FxHashMap, FxHashSet};
|
||||
use errors::DiagnosticBuilder;
|
||||
@ -347,7 +348,7 @@ pub struct TypeckTables<'tcx> {
|
||||
|
||||
/// Resolved definitions for `<T>::X` associated paths and
|
||||
/// method calls, including those of overloaded operators.
|
||||
type_dependent_defs: ItemLocalMap<Def>,
|
||||
type_dependent_defs: ItemLocalMap<Result<(DefKind, DefId), ErrorReported>>,
|
||||
|
||||
/// Resolved field indices for field accesses in expressions (`S { field }`, `obj.field`)
|
||||
/// or patterns (`S { field }`). The index is often useful by itself, but to learn more
|
||||
@ -478,33 +479,35 @@ impl<'tcx> TypeckTables<'tcx> {
|
||||
}
|
||||
|
||||
/// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node.
|
||||
pub fn qpath_def(&self, qpath: &hir::QPath, id: hir::HirId) -> Def {
|
||||
pub fn qpath_res(&self, qpath: &hir::QPath, id: hir::HirId) -> Res {
|
||||
match *qpath {
|
||||
hir::QPath::Resolved(_, ref path) => path.def,
|
||||
hir::QPath::TypeRelative(..) => {
|
||||
validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
|
||||
self.type_dependent_defs.get(&id.local_id).cloned().unwrap_or(Def::Err)
|
||||
}
|
||||
hir::QPath::Resolved(_, ref path) => path.res,
|
||||
hir::QPath::TypeRelative(..) => self.type_dependent_def(id)
|
||||
.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_dependent_defs(&self) -> LocalTableInContext<'_, Def> {
|
||||
pub fn type_dependent_defs(
|
||||
&self,
|
||||
) -> LocalTableInContext<'_, Result<(DefKind, DefId), ErrorReported>> {
|
||||
LocalTableInContext {
|
||||
local_id_root: self.local_id_root,
|
||||
data: &self.type_dependent_defs
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_dependent_def(&self, id: HirId) -> Option<Def> {
|
||||
pub fn type_dependent_def(&self, id: HirId) -> Option<(DefKind, DefId)> {
|
||||
validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
|
||||
self.type_dependent_defs.get(&id.local_id).cloned()
|
||||
self.type_dependent_defs.get(&id.local_id).cloned().and_then(|r| r.ok())
|
||||
}
|
||||
|
||||
pub fn type_dependent_def_id(&self, id: HirId) -> Option<DefId> {
|
||||
self.type_dependent_def(id).map(|def| def.def_id())
|
||||
self.type_dependent_def(id).map(|(_, def_id)| def_id)
|
||||
}
|
||||
|
||||
pub fn type_dependent_defs_mut(&mut self) -> LocalTableInContextMut<'_, Def> {
|
||||
pub fn type_dependent_defs_mut(
|
||||
&mut self,
|
||||
) -> LocalTableInContextMut<'_, Result<(DefKind, DefId), ErrorReported>> {
|
||||
LocalTableInContextMut {
|
||||
local_id_root: self.local_id_root,
|
||||
data: &mut self.type_dependent_defs
|
||||
@ -658,7 +661,7 @@ impl<'tcx> TypeckTables<'tcx> {
|
||||
}
|
||||
|
||||
match self.type_dependent_defs().get(expr.hir_id) {
|
||||
Some(&Def::Method(_)) => true,
|
||||
Some(Ok((DefKind::Method, _))) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ pub use self::fold::TypeFoldable;
|
||||
|
||||
use crate::hir::{map as hir_map, FreevarMap, GlobMap, TraitMap};
|
||||
use crate::hir::{HirId, Node};
|
||||
use crate::hir::def::{Def, CtorOf, CtorKind, ExportMap};
|
||||
use crate::hir::def::{Res, DefKind, CtorOf, CtorKind, ExportMap};
|
||||
use crate::hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_macros::HashStable;
|
||||
@ -191,12 +191,12 @@ pub enum AssociatedKind {
|
||||
}
|
||||
|
||||
impl AssociatedItem {
|
||||
pub fn def(&self) -> Def {
|
||||
pub fn def_kind(&self) -> DefKind {
|
||||
match self.kind {
|
||||
AssociatedKind::Const => Def::AssociatedConst(self.def_id),
|
||||
AssociatedKind::Method => Def::Method(self.def_id),
|
||||
AssociatedKind::Type => Def::AssociatedTy(self.def_id),
|
||||
AssociatedKind::Existential => Def::AssociatedExistential(self.def_id),
|
||||
AssociatedKind::Const => DefKind::AssociatedConst,
|
||||
AssociatedKind::Method => DefKind::Method,
|
||||
AssociatedKind::Type => DefKind::AssociatedTy,
|
||||
AssociatedKind::Existential => DefKind::AssociatedExistential,
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,10 +269,10 @@ impl Visibility {
|
||||
match visibility.node {
|
||||
hir::VisibilityKind::Public => Visibility::Public,
|
||||
hir::VisibilityKind::Crate(_) => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
|
||||
hir::VisibilityKind::Restricted { ref path, .. } => match path.def {
|
||||
hir::VisibilityKind::Restricted { ref path, .. } => match path.res {
|
||||
// If there is no resolution, `resolve` will have already reported an error, so
|
||||
// assume that the visibility is public to avoid reporting more privacy errors.
|
||||
Def::Err => Visibility::Public,
|
||||
Res::Err => Visibility::Public,
|
||||
def => Visibility::Restricted(def.def_id()),
|
||||
},
|
||||
hir::VisibilityKind::Inherited => {
|
||||
@ -812,7 +812,7 @@ pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ClosureUpvar<'tcx> {
|
||||
pub def: Def,
|
||||
pub res: Res,
|
||||
pub span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
}
|
||||
@ -2337,14 +2337,14 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
||||
.expect("variant_index_with_ctor_id: unknown variant").0
|
||||
}
|
||||
|
||||
pub fn variant_of_def(&self, def: Def) -> &VariantDef {
|
||||
match def {
|
||||
Def::Variant(vid) => self.variant_with_id(vid),
|
||||
Def::Ctor(cid, ..) => self.variant_with_ctor_id(cid),
|
||||
Def::Struct(..) | Def::Union(..) |
|
||||
Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) |
|
||||
Def::SelfCtor(..) => self.non_enum_variant(),
|
||||
_ => bug!("unexpected def {:?} in variant_of_def", def)
|
||||
pub fn variant_of_res(&self, res: Res) -> &VariantDef {
|
||||
match res {
|
||||
Res::Def(DefKind::Variant, vid) => self.variant_with_id(vid),
|
||||
Res::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid),
|
||||
Res::Def(DefKind::Struct, _) | Res::Def(DefKind::Union, _) |
|
||||
Res::Def(DefKind::TyAlias, _) | Res::Def(DefKind::AssociatedTy, _) | Res::SelfTy(..) |
|
||||
Res::SelfCtor(..) => self.non_enum_variant(),
|
||||
_ => bug!("unexpected res {:?} in variant_of_res", res)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2805,8 +2805,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
match self.describe_def(def_id).expect("no def for def-id") {
|
||||
Def::AssociatedConst(_) | Def::Method(_) | Def::AssociatedTy(_) => true,
|
||||
match self.def_kind(def_id).expect("no def for def-id") {
|
||||
DefKind::AssociatedConst
|
||||
| DefKind::Method
|
||||
| DefKind::AssociatedTy => true,
|
||||
_ => false,
|
||||
}
|
||||
};
|
||||
@ -2948,27 +2950,27 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `ty::VariantDef` if `def` refers to a struct,
|
||||
/// Returns `ty::VariantDef` if `res` refers to a struct,
|
||||
/// or variant or their constructors, panics otherwise.
|
||||
pub fn expect_variant_def(self, def: Def) -> &'tcx VariantDef {
|
||||
match def {
|
||||
Def::Variant(did) => {
|
||||
pub fn expect_variant_res(self, res: Res) -> &'tcx VariantDef {
|
||||
match res {
|
||||
Res::Def(DefKind::Variant, did) => {
|
||||
let enum_did = self.parent(did).unwrap();
|
||||
self.adt_def(enum_did).variant_with_id(did)
|
||||
}
|
||||
Def::Struct(did) | Def::Union(did) => {
|
||||
Res::Def(DefKind::Struct, did) | Res::Def(DefKind::Union, did) => {
|
||||
self.adt_def(did).non_enum_variant()
|
||||
}
|
||||
Def::Ctor(variant_ctor_did, CtorOf::Variant, ..) => {
|
||||
Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_did) => {
|
||||
let variant_did = self.parent(variant_ctor_did).unwrap();
|
||||
let enum_did = self.parent(variant_did).unwrap();
|
||||
self.adt_def(enum_did).variant_with_ctor_id(variant_ctor_did)
|
||||
}
|
||||
Def::Ctor(ctor_did, CtorOf::Struct, ..) => {
|
||||
Res::Def(DefKind::Ctor(CtorOf::Struct, ..), ctor_did) => {
|
||||
let struct_did = self.parent(ctor_did).expect("struct ctor has no parent");
|
||||
self.adt_def(struct_did).non_enum_variant()
|
||||
}
|
||||
_ => bug!("expect_variant_def used with unexpected def {:?}", def)
|
||||
_ => bug!("expect_variant_res used with unexpected res {:?}", res)
|
||||
}
|
||||
}
|
||||
|
||||
@ -3044,7 +3046,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
/// `DefId` of the impl that the method belongs to; otherwise, returns `None`.
|
||||
pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> {
|
||||
let item = if def_id.krate != LOCAL_CRATE {
|
||||
if let Some(Def::Method(_)) = self.describe_def(def_id) {
|
||||
if let Some(DefKind::Method) = self.def_kind(def_id) {
|
||||
Some(self.associated_item(def_id))
|
||||
} else {
|
||||
None
|
||||
|
@ -359,7 +359,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
|
||||
DefPathData::TypeNs(ref mut name) if Some(visible_parent) != actual_parent => {
|
||||
let reexport = self.tcx().item_children(visible_parent)
|
||||
.iter()
|
||||
.find(|child| child.def.def_id() == def_id)
|
||||
.find(|child| child.res.def_id() == def_id)
|
||||
.map(|child| child.ident.as_interned_str());
|
||||
if let Some(reexport) = reexport {
|
||||
*name = reexport;
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::dep_graph::{self, DepNode};
|
||||
use crate::hir::def_id::{CrateNum, DefId, DefIndex};
|
||||
use crate::hir::def::{Def, Export};
|
||||
use crate::hir::def::{DefKind, Export};
|
||||
use crate::hir::{self, TraitCandidate, ItemLocalId, CodegenFnAttrs};
|
||||
use crate::infer::canonical::{self, Canonical};
|
||||
use crate::lint;
|
||||
|
@ -55,7 +55,7 @@ impl fmt::Debug for ty::AdtDef {
|
||||
impl fmt::Debug for ty::ClosureUpvar<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "ClosureUpvar({:?},{:?})",
|
||||
self.def,
|
||||
self.res,
|
||||
self.ty)
|
||||
}
|
||||
}
|
||||
@ -302,7 +302,7 @@ CloneTypeFoldableAndLiftImpls! {
|
||||
::syntax::ast::FloatTy,
|
||||
::syntax::ast::NodeId,
|
||||
::syntax_pos::symbol::Symbol,
|
||||
crate::hir::def::Def,
|
||||
crate::hir::def::Res,
|
||||
crate::hir::def_id::DefId,
|
||||
crate::hir::InlineAsm,
|
||||
crate::hir::MatchSource,
|
||||
@ -1279,7 +1279,7 @@ TupleStructTypeFoldableImpl! {
|
||||
|
||||
BraceStructTypeFoldableImpl! {
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
|
||||
def, span, ty
|
||||
res, span, ty
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
//! If you define a new `LateLintPass`, you will also need to add it to the
|
||||
//! `late_lint_methods!` invocation in `lib.rs`.
|
||||
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def::{Res, DefKind};
|
||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::{lint, util};
|
||||
@ -154,7 +154,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns {
|
||||
if let PatKind::Struct(ref qpath, ref field_pats, _) = pat.node {
|
||||
let variant = cx.tables.pat_ty(pat).ty_adt_def()
|
||||
.expect("struct pattern type is not an ADT")
|
||||
.variant_of_def(cx.tables.qpath_def(qpath, pat.hir_id));
|
||||
.variant_of_res(cx.tables.qpath_res(qpath, pat.hir_id));
|
||||
for fieldpat in field_pats {
|
||||
if fieldpat.node.is_shorthand {
|
||||
continue;
|
||||
@ -404,7 +404,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
|
||||
hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) => {
|
||||
// If the trait is private, add the impl items to private_traits so they don't get
|
||||
// reported for missing docs.
|
||||
let real_trait = trait_ref.path.def.def_id();
|
||||
let real_trait = trait_ref.path.res.def_id();
|
||||
if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(real_trait) {
|
||||
match cx.tcx.hir().find_by_hir_id(hir_id) {
|
||||
Some(Node::Item(item)) => {
|
||||
@ -912,11 +912,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
|
||||
expr: &hir::Expr)
|
||||
-> Option<(Ty<'tcx>, Ty<'tcx>)> {
|
||||
let def = if let hir::ExprKind::Path(ref qpath) = expr.node {
|
||||
cx.tables.qpath_def(qpath, expr.hir_id)
|
||||
cx.tables.qpath_res(qpath, expr.hir_id)
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
if let Def::Fn(did) = def {
|
||||
if let Res::Def(DefKind::Fn, did) = def {
|
||||
if !def_id_is_transmute(cx, did) {
|
||||
return None;
|
||||
}
|
||||
@ -1071,8 +1071,8 @@ impl TypeAliasBounds {
|
||||
// If this is a type variable, we found a `T::Assoc`.
|
||||
match ty.node {
|
||||
hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => {
|
||||
match path.def {
|
||||
Def::TyParam(_) => true,
|
||||
match path.res {
|
||||
Res::Def(DefKind::TyParam, _) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use rustc::hir::{self, GenericParamKind, PatKind};
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def::{Res, DefKind};
|
||||
use rustc::hir::intravisit::FnKind;
|
||||
use rustc::lint;
|
||||
use rustc::ty;
|
||||
@ -415,7 +415,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals {
|
||||
fn check_pat(&mut self, cx: &LateContext<'_, '_>, p: &hir::Pat) {
|
||||
// Lint for constants that look like binding identifiers (#7526)
|
||||
if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.node {
|
||||
if let Def::Const(..) = path.def {
|
||||
if let Res::Def(DefKind::Const, _) = path.res {
|
||||
if path.segments.len() == 1 {
|
||||
NonUpperCaseGlobals::check_upper_case(
|
||||
cx,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def::{Res, DefKind};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::lint;
|
||||
use rustc::ty;
|
||||
@ -87,14 +87,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
|
||||
|
||||
let mut fn_warned = false;
|
||||
let mut op_warned = false;
|
||||
let maybe_def = match expr.node {
|
||||
let maybe_def_id = match expr.node {
|
||||
hir::ExprKind::Call(ref callee, _) => {
|
||||
match callee.node {
|
||||
hir::ExprKind::Path(ref qpath) => {
|
||||
let def = cx.tables.qpath_def(qpath, callee.hir_id);
|
||||
match def {
|
||||
Def::Fn(_) | Def::Method(_) => Some(def),
|
||||
// `Def::Local` if it was a closure, for which we
|
||||
match cx.tables.qpath_res(qpath, callee.hir_id) {
|
||||
Res::Def(DefKind::Fn, def_id)
|
||||
| Res::Def(DefKind::Method, def_id) => Some(def_id),
|
||||
// `Res::Local` if it was a closure, for which we
|
||||
// do not currently support must-use linting
|
||||
_ => None
|
||||
}
|
||||
@ -103,12 +103,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
|
||||
}
|
||||
},
|
||||
hir::ExprKind::MethodCall(..) => {
|
||||
cx.tables.type_dependent_def(expr.hir_id)
|
||||
cx.tables.type_dependent_def_id(expr.hir_id)
|
||||
},
|
||||
_ => None
|
||||
};
|
||||
if let Some(def) = maybe_def {
|
||||
let def_id = def.def_id();
|
||||
if let Some(def_id) = maybe_def_id {
|
||||
fn_warned = check_must_use(cx, def_id, s.span, "return value of ", "");
|
||||
} else if type_permits_lack_of_use {
|
||||
// We don't warn about unused unit or uninhabited types.
|
||||
|
@ -110,7 +110,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
||||
associated_item_def_ids => {
|
||||
let mut result = vec![];
|
||||
cdata.each_child_of_item(def_id.index,
|
||||
|child| result.push(child.def.def_id()), tcx.sess);
|
||||
|child| result.push(child.res.def_id()), tcx.sess);
|
||||
Lrc::new(result)
|
||||
}
|
||||
associated_item => { cdata.get_associated_item(def_id.index) }
|
||||
@ -138,7 +138,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
||||
is_const_fn_raw => { cdata.is_const_fn_raw(def_id.index) }
|
||||
is_foreign_item => { cdata.is_foreign_item(def_id.index) }
|
||||
static_mutability => { cdata.static_mutability(def_id.index) }
|
||||
describe_def => { cdata.get_def(def_id.index) }
|
||||
def_kind => { cdata.def_kind(def_id.index) }
|
||||
def_span => { cdata.get_span(def_id.index, &tcx.sess) }
|
||||
lookup_stability => {
|
||||
cdata.get_stability(def_id.index).map(|s| tcx.intern_stability(s))
|
||||
@ -355,7 +355,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
|
||||
return;
|
||||
}
|
||||
|
||||
let child = child.def.def_id();
|
||||
let child = child.res.def_id();
|
||||
|
||||
match visible_parent_map.entry(child) {
|
||||
Entry::Occupied(mut entry) => {
|
||||
|
@ -8,7 +8,7 @@ use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash, Definitions};
|
||||
use rustc::hir;
|
||||
use rustc::middle::cstore::LinkagePreference;
|
||||
use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
|
||||
use rustc::hir::def::{self, Def, CtorOf, CtorKind};
|
||||
use rustc::hir::def::{self, Res, DefKind, CtorOf, CtorKind};
|
||||
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, DefIndexAddressSpace,
|
||||
CRATE_DEF_INDEX, LOCAL_CRATE, LocalDefId};
|
||||
use rustc::hir::map::definitions::DefPathTable;
|
||||
@ -399,32 +399,32 @@ impl<'a, 'tcx> MetadataBlob {
|
||||
}
|
||||
|
||||
impl<'tcx> EntryKind<'tcx> {
|
||||
fn to_def(&self, did: DefId) -> Option<Def> {
|
||||
fn def_kind(&self) -> Option<DefKind> {
|
||||
Some(match *self {
|
||||
EntryKind::Const(..) => Def::Const(did),
|
||||
EntryKind::AssociatedConst(..) => Def::AssociatedConst(did),
|
||||
EntryKind::Const(..) => DefKind::Const,
|
||||
EntryKind::AssociatedConst(..) => DefKind::AssociatedConst,
|
||||
EntryKind::ImmStatic |
|
||||
EntryKind::MutStatic |
|
||||
EntryKind::ForeignImmStatic |
|
||||
EntryKind::ForeignMutStatic => Def::Static(did),
|
||||
EntryKind::Struct(_, _) => Def::Struct(did),
|
||||
EntryKind::Union(_, _) => Def::Union(did),
|
||||
EntryKind::ForeignMutStatic => DefKind::Static,
|
||||
EntryKind::Struct(_, _) => DefKind::Struct,
|
||||
EntryKind::Union(_, _) => DefKind::Union,
|
||||
EntryKind::Fn(_) |
|
||||
EntryKind::ForeignFn(_) => Def::Fn(did),
|
||||
EntryKind::Method(_) => Def::Method(did),
|
||||
EntryKind::Type => Def::TyAlias(did),
|
||||
EntryKind::TypeParam => Def::TyParam(did),
|
||||
EntryKind::ConstParam => Def::ConstParam(did),
|
||||
EntryKind::Existential => Def::Existential(did),
|
||||
EntryKind::AssociatedType(_) => Def::AssociatedTy(did),
|
||||
EntryKind::AssociatedExistential(_) => Def::AssociatedExistential(did),
|
||||
EntryKind::Mod(_) => Def::Mod(did),
|
||||
EntryKind::Variant(_) => Def::Variant(did),
|
||||
EntryKind::Trait(_) => Def::Trait(did),
|
||||
EntryKind::TraitAlias(_) => Def::TraitAlias(did),
|
||||
EntryKind::Enum(..) => Def::Enum(did),
|
||||
EntryKind::MacroDef(_) => Def::Macro(did, MacroKind::Bang),
|
||||
EntryKind::ForeignType => Def::ForeignTy(did),
|
||||
EntryKind::ForeignFn(_) => DefKind::Fn,
|
||||
EntryKind::Method(_) => DefKind::Method,
|
||||
EntryKind::Type => DefKind::TyAlias,
|
||||
EntryKind::TypeParam => DefKind::TyParam,
|
||||
EntryKind::ConstParam => DefKind::ConstParam,
|
||||
EntryKind::Existential => DefKind::Existential,
|
||||
EntryKind::AssociatedType(_) => DefKind::AssociatedTy,
|
||||
EntryKind::AssociatedExistential(_) => DefKind::AssociatedExistential,
|
||||
EntryKind::Mod(_) => DefKind::Mod,
|
||||
EntryKind::Variant(_) => DefKind::Variant,
|
||||
EntryKind::Trait(_) => DefKind::Trait,
|
||||
EntryKind::TraitAlias(_) => DefKind::TraitAlias,
|
||||
EntryKind::Enum(..) => DefKind::Enum,
|
||||
EntryKind::MacroDef(_) => DefKind::Macro(MacroKind::Bang),
|
||||
EntryKind::ForeignType => DefKind::ForeignTy,
|
||||
|
||||
EntryKind::ForeignMod |
|
||||
EntryKind::GlobalAsm |
|
||||
@ -507,12 +507,12 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
.expect("no name in item_name")
|
||||
}
|
||||
|
||||
pub fn get_def(&self, index: DefIndex) -> Option<Def> {
|
||||
pub fn def_kind(&self, index: DefIndex) -> Option<DefKind> {
|
||||
if !self.is_proc_macro(index) {
|
||||
self.entry(index).kind.to_def(self.local_def_id(index))
|
||||
self.entry(index).kind.def_kind()
|
||||
} else {
|
||||
let kind = self.proc_macros.as_ref().unwrap()[index.to_proc_macro_index()].1.kind();
|
||||
Some(Def::Macro(self.local_def_id(index), kind))
|
||||
Some(DefKind::Macro(kind))
|
||||
}
|
||||
}
|
||||
|
||||
@ -743,17 +743,14 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
*/
|
||||
if id == CRATE_DEF_INDEX {
|
||||
for (id, &(name, ref ext)) in proc_macros.iter().enumerate() {
|
||||
let def = Def::Macro(
|
||||
DefId {
|
||||
krate: self.cnum,
|
||||
index: DefIndex::from_proc_macro_index(id),
|
||||
},
|
||||
ext.kind()
|
||||
let res = Res::Def(
|
||||
DefKind::Macro(ext.kind()),
|
||||
self.local_def_id(DefIndex::from_proc_macro_index(id)),
|
||||
);
|
||||
let ident = Ident::with_empty_ctxt(name);
|
||||
callback(def::Export {
|
||||
ident: ident,
|
||||
def: def,
|
||||
res: res,
|
||||
vis: ty::Visibility::Public,
|
||||
span: DUMMY_SP,
|
||||
});
|
||||
@ -789,9 +786,9 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
// FIXME(eddyb) Don't encode these in children.
|
||||
EntryKind::ForeignMod => {
|
||||
for child_index in child.children.decode((self, sess)) {
|
||||
if let Some(def) = self.get_def(child_index) {
|
||||
if let Some(kind) = self.def_kind(child_index) {
|
||||
callback(def::Export {
|
||||
def,
|
||||
res: Res::Def(kind, self.local_def_id(child_index)),
|
||||
ident: Ident::from_interned_str(self.item_name(child_index)),
|
||||
vis: self.get_visibility(child_index),
|
||||
span: self.entry(child_index).span.decode((self, sess)),
|
||||
@ -807,30 +804,38 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
|
||||
let def_key = self.def_key(child_index);
|
||||
let span = child.span.decode((self, sess));
|
||||
if let (Some(def), Some(name)) =
|
||||
(self.get_def(child_index), def_key.disambiguated_data.data.get_opt_name()) {
|
||||
if let (Some(kind), Some(name)) =
|
||||
(self.def_kind(child_index), def_key.disambiguated_data.data.get_opt_name()) {
|
||||
let ident = Ident::from_interned_str(name);
|
||||
let vis = self.get_visibility(child_index);
|
||||
callback(def::Export { def, ident, vis, span });
|
||||
let def_id = self.local_def_id(child_index);
|
||||
let res = Res::Def(kind, def_id);
|
||||
callback(def::Export { res, ident, vis, span });
|
||||
// For non-re-export structs and variants add their constructors to children.
|
||||
// Re-export lists automatically contain constructors when necessary.
|
||||
match def {
|
||||
Def::Struct(..) => {
|
||||
match kind {
|
||||
DefKind::Struct => {
|
||||
if let Some(ctor_def_id) = self.get_ctor_def_id(child_index) {
|
||||
let ctor_kind = self.get_ctor_kind(child_index);
|
||||
let ctor_def = Def::Ctor(ctor_def_id, CtorOf::Struct, ctor_kind);
|
||||
let ctor_res = Res::Def(
|
||||
DefKind::Ctor(CtorOf::Struct, ctor_kind),
|
||||
ctor_def_id,
|
||||
);
|
||||
let vis = self.get_visibility(ctor_def_id.index);
|
||||
callback(def::Export { def: ctor_def, vis, ident, span });
|
||||
callback(def::Export { res: ctor_res, vis, ident, span });
|
||||
}
|
||||
}
|
||||
Def::Variant(def_id) => {
|
||||
DefKind::Variant => {
|
||||
// Braced variants, unlike structs, generate unusable names in
|
||||
// value namespace, they are reserved for possible future use.
|
||||
// It's ok to use the variant's id as a ctor id since an
|
||||
// error will be reported on any use of such resolution anyway.
|
||||
let ctor_def_id = self.get_ctor_def_id(child_index).unwrap_or(def_id);
|
||||
let ctor_kind = self.get_ctor_kind(child_index);
|
||||
let ctor_def = Def::Ctor(ctor_def_id, CtorOf::Variant, ctor_kind);
|
||||
let ctor_res = Res::Def(
|
||||
DefKind::Ctor(CtorOf::Variant, ctor_kind),
|
||||
ctor_def_id,
|
||||
);
|
||||
let mut vis = self.get_visibility(ctor_def_id.index);
|
||||
if ctor_def_id == def_id && vis == ty::Visibility::Public {
|
||||
// For non-exhaustive variants lower the constructor visibility to
|
||||
@ -839,11 +844,11 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
// were already encoded in metadata.
|
||||
let attrs = self.get_item_attrs(def_id.index, sess);
|
||||
if attr::contains_name(&attrs, "non_exhaustive") {
|
||||
let crate_def_id = DefId { index: CRATE_DEF_INDEX, ..def_id };
|
||||
let crate_def_id = self.local_def_id(CRATE_DEF_INDEX);
|
||||
vis = ty::Visibility::Restricted(crate_def_id);
|
||||
}
|
||||
}
|
||||
callback(def::Export { def: ctor_def, ident, vis, span });
|
||||
callback(def::Export { res: ctor_res, ident, vis, span });
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -853,8 +858,8 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
|
||||
if let EntryKind::Mod(data) = item.kind {
|
||||
for exp in data.decode((self, sess)).reexports.decode((self, sess)) {
|
||||
match exp.def {
|
||||
Def::Macro(..) => {}
|
||||
match exp.res {
|
||||
Res::Def(DefKind::Macro(..), _) => {}
|
||||
_ if macros_only => continue,
|
||||
_ => {}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ use crate::borrow_check::nll::universal_regions::DefiningTy;
|
||||
use crate::borrow_check::nll::ToRegionVid;
|
||||
use crate::borrow_check::Upvar;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def::{Res, DefKind};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::mir::Mir;
|
||||
@ -491,12 +492,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
ty::Adt(_adt_def, substs),
|
||||
hir::TyKind::Path(hir::QPath::Resolved(None, path)),
|
||||
) => {
|
||||
match path.def {
|
||||
match path.res {
|
||||
// Type parameters of the type alias have no reason to
|
||||
// be the same as those of the ADT.
|
||||
// FIXME: We should be able to do something similar to
|
||||
// match_adt_and_segment in this case.
|
||||
hir::def::Def::TyAlias(_) => (),
|
||||
Res::Def(DefKind::TyAlias, _) => (),
|
||||
_ => if let Some(last_segment) = path.segments.last() {
|
||||
if let Some(name) = self.match_adt_and_segment(
|
||||
substs,
|
||||
|
@ -6,7 +6,7 @@ use std::borrow::{Borrow, Cow};
|
||||
use std::hash::Hash;
|
||||
use std::collections::hash_map::Entry;
|
||||
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def::DefKind;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::mir::interpret::{ConstEvalErr, ErrorHandled};
|
||||
use rustc::mir;
|
||||
@ -634,14 +634,14 @@ pub fn const_eval_raw_provider<'a, 'tcx>(
|
||||
}
|
||||
} else if def_id.is_local() {
|
||||
// constant defined in this crate, we can figure out a lint level!
|
||||
match tcx.describe_def(def_id) {
|
||||
match tcx.def_kind(def_id) {
|
||||
// constants never produce a hard error at the definition site. Anything else is
|
||||
// a backwards compatibility hazard (and will break old versions of winapi for sure)
|
||||
//
|
||||
// note that validation may still cause a hard error on this very same constant,
|
||||
// because any code that existed before validation could not have failed validation
|
||||
// thus preventing such a hard error from being a backwards compatibility hazard
|
||||
Some(Def::Const(_)) | Some(Def::AssociatedConst(_)) => {
|
||||
Some(DefKind::Const) | Some(DefKind::AssociatedConst) => {
|
||||
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
|
||||
err.report_as_lint(
|
||||
tcx.at(tcx.def_span(def_id)),
|
||||
|
@ -4,7 +4,7 @@ use crate::hair::cx::block;
|
||||
use crate::hair::cx::to_ref::ToRef;
|
||||
use crate::hair::util::UserAnnotatedTyHelpers;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use rustc::hir::def::{CtorOf, Def, CtorKind};
|
||||
use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
|
||||
use rustc::mir::interpret::{GlobalId, ErrorHandled, ConstValue};
|
||||
use rustc::ty::{self, AdtKind, Ty};
|
||||
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability, PointerCast};
|
||||
@ -249,10 +249,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
{
|
||||
// Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
|
||||
expr_ty.ty_adt_def().and_then(|adt_def| {
|
||||
match path.def {
|
||||
Def::Ctor(ctor_id, _, CtorKind::Fn) =>
|
||||
match path.res {
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) =>
|
||||
Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id))),
|
||||
Def::SelfCtor(..) => Some((adt_def, VariantIdx::new(0))),
|
||||
Res::SelfCtor(..) => Some((adt_def, VariantIdx::new(0))),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
@ -468,9 +468,9 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
AdtKind::Enum => {
|
||||
let def = cx.tables().qpath_def(qpath, expr.hir_id);
|
||||
match def {
|
||||
Def::Variant(variant_id) => {
|
||||
let res = cx.tables().qpath_res(qpath, expr.hir_id);
|
||||
match res {
|
||||
Res::Def(DefKind::Variant, variant_id) => {
|
||||
assert!(base.is_none());
|
||||
|
||||
let index = adt.variant_index_with_id(variant_id);
|
||||
@ -491,7 +491,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
span_bug!(expr.span, "unexpected def: {:?}", def);
|
||||
span_bug!(expr.span, "unexpected res: {:?}", res);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -531,8 +531,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
|
||||
hir::ExprKind::Path(ref qpath) => {
|
||||
let def = cx.tables().qpath_def(qpath, expr.hir_id);
|
||||
convert_path_expr(cx, expr, def)
|
||||
let res = cx.tables().qpath_res(qpath, expr.hir_id);
|
||||
convert_path_expr(cx, expr, res)
|
||||
}
|
||||
|
||||
hir::ExprKind::InlineAsm(ref asm, ref outputs, ref inputs) => {
|
||||
@ -657,14 +657,17 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
// The correct solution would be to add symbolic computations to miri,
|
||||
// so we wouldn't have to compute and store the actual value
|
||||
let var = if let hir::ExprKind::Path(ref qpath) = source.node {
|
||||
let def = cx.tables().qpath_def(qpath, source.hir_id);
|
||||
let res = cx.tables().qpath_res(qpath, source.hir_id);
|
||||
cx
|
||||
.tables()
|
||||
.node_type(source.hir_id)
|
||||
.ty_adt_def()
|
||||
.and_then(|adt_def| {
|
||||
match def {
|
||||
Def::Ctor(variant_ctor_id, CtorOf::Variant, CtorKind::Const) => {
|
||||
match res {
|
||||
Res::Def(
|
||||
DefKind::Ctor(CtorOf::Variant, CtorKind::Const),
|
||||
variant_ctor_id,
|
||||
) => {
|
||||
let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id);
|
||||
let (d, o) = adt_def.discriminant_def_for_variant(idx);
|
||||
use rustc::ty::util::IntTypeExt;
|
||||
@ -782,37 +785,38 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
fn user_substs_applied_to_def(
|
||||
fn user_substs_applied_to_res(
|
||||
cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
hir_id: hir::HirId,
|
||||
def: &Def,
|
||||
res: Res,
|
||||
) -> Option<ty::CanonicalUserType<'tcx>> {
|
||||
debug!("user_substs_applied_to_def: def={:?}", def);
|
||||
let user_provided_type = match def {
|
||||
debug!("user_substs_applied_to_res: res={:?}", res);
|
||||
let user_provided_type = match res {
|
||||
// A reference to something callable -- e.g., a fn, method, or
|
||||
// a tuple-struct or tuple-variant. This has the type of a
|
||||
// `Fn` but with the user-given substitutions.
|
||||
Def::Fn(_) |
|
||||
Def::Method(_) |
|
||||
Def::Ctor(_, _, CtorKind::Fn) |
|
||||
Def::Const(_) |
|
||||
Def::AssociatedConst(_) => cx.tables().user_provided_types().get(hir_id).map(|u_ty| *u_ty),
|
||||
Res::Def(DefKind::Fn, _) |
|
||||
Res::Def(DefKind::Method, _) |
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) |
|
||||
Res::Def(DefKind::Const, _) |
|
||||
Res::Def(DefKind::AssociatedConst, _) =>
|
||||
cx.tables().user_provided_types().get(hir_id).map(|u_ty| *u_ty),
|
||||
|
||||
// A unit struct/variant which is used as a value (e.g.,
|
||||
// `None`). This has the type of the enum/struct that defines
|
||||
// this variant -- but with the substitutions given by the
|
||||
// user.
|
||||
Def::Ctor(_, _, CtorKind::Const) =>
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Const), _) =>
|
||||
cx.user_substs_applied_to_ty_of_hir_id(hir_id),
|
||||
|
||||
// `Self` is used in expression as a tuple struct constructor or an unit struct constructor
|
||||
Def::SelfCtor(_) =>
|
||||
Res::SelfCtor(_) =>
|
||||
cx.user_substs_applied_to_ty_of_hir_id(hir_id),
|
||||
|
||||
_ =>
|
||||
bug!("user_substs_applied_to_def: unexpected def {:?} at {:?}", def, hir_id)
|
||||
bug!("user_substs_applied_to_res: unexpected res {:?} at {:?}", res, hir_id)
|
||||
};
|
||||
debug!("user_substs_applied_to_def: user_provided_type={:?}", user_provided_type);
|
||||
debug!("user_substs_applied_to_res: user_provided_type={:?}", user_provided_type);
|
||||
user_provided_type
|
||||
}
|
||||
|
||||
@ -826,13 +830,13 @@ fn method_callee<'a, 'gcx, 'tcx>(
|
||||
let (def_id, substs, user_ty) = match overloaded_callee {
|
||||
Some((def_id, substs)) => (def_id, substs, None),
|
||||
None => {
|
||||
let def = cx.tables().type_dependent_def(expr.hir_id)
|
||||
let (kind, def_id) = cx.tables().type_dependent_def(expr.hir_id)
|
||||
.unwrap_or_else(|| {
|
||||
span_bug!(expr.span, "no type-dependent def for method callee")
|
||||
});
|
||||
let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def);
|
||||
let user_ty = user_substs_applied_to_res(cx, expr.hir_id, Res::Def(kind, def_id));
|
||||
debug!("method_callee: user_ty={:?}", user_ty);
|
||||
(def.def_id(), cx.tables().node_substs(expr.hir_id), user_ty)
|
||||
(def_id, cx.tables().node_substs(expr.hir_id), user_ty)
|
||||
}
|
||||
};
|
||||
let ty = cx.tcx().mk_fn_def(def_id, substs);
|
||||
@ -890,16 +894,16 @@ fn convert_arm<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, arm: &'tcx hir::Arm)
|
||||
|
||||
fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
expr: &'tcx hir::Expr,
|
||||
def: Def)
|
||||
res: Res)
|
||||
-> ExprKind<'tcx> {
|
||||
let substs = cx.tables().node_substs(expr.hir_id);
|
||||
match def {
|
||||
match res {
|
||||
// A regular function, constructor function or a constant.
|
||||
Def::Fn(_) |
|
||||
Def::Method(_) |
|
||||
Def::Ctor(_, _, CtorKind::Fn) |
|
||||
Def::SelfCtor(..) => {
|
||||
let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def);
|
||||
Res::Def(DefKind::Fn, _) |
|
||||
Res::Def(DefKind::Method, _) |
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) |
|
||||
Res::SelfCtor(..) => {
|
||||
let user_ty = user_substs_applied_to_res(cx, expr.hir_id, res);
|
||||
debug!("convert_path_expr: user_ty={:?}", user_ty);
|
||||
ExprKind::Literal {
|
||||
literal: cx.tcx.mk_const(ty::Const::zero_sized(
|
||||
@ -909,7 +913,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
Def::ConstParam(def_id) => {
|
||||
Res::Def(DefKind::ConstParam, def_id) => {
|
||||
let node_id = cx.tcx.hir().as_local_node_id(def_id).unwrap();
|
||||
let item_id = cx.tcx.hir().get_parent_node(node_id);
|
||||
let item_def_id = cx.tcx.hir().local_def_id(item_id);
|
||||
@ -928,9 +932,9 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
Def::Const(def_id) |
|
||||
Def::AssociatedConst(def_id) => {
|
||||
let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def);
|
||||
Res::Def(DefKind::Const, def_id) |
|
||||
Res::Def(DefKind::AssociatedConst, def_id) => {
|
||||
let user_ty = user_substs_applied_to_res(cx, expr.hir_id, res);
|
||||
debug!("convert_path_expr: (const) user_ty={:?}", user_ty);
|
||||
ExprKind::Literal {
|
||||
literal: cx.tcx.mk_const(ty::Const {
|
||||
@ -941,7 +945,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
},
|
||||
|
||||
Def::Ctor(def_id, _, CtorKind::Const) => {
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id) => {
|
||||
let user_provided_types = cx.tables.user_provided_types();
|
||||
let user_provided_type = user_provided_types.get(expr.hir_id).map(|u_ty| *u_ty);
|
||||
debug!("convert_path_expr: user_provided_type={:?}", user_provided_type);
|
||||
@ -963,24 +967,24 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
Def::Static(id) => ExprKind::StaticRef { id },
|
||||
Res::Def(DefKind::Static, id) => ExprKind::StaticRef { id },
|
||||
|
||||
Def::Local(..) | Def::Upvar(..) => convert_var(cx, expr, def),
|
||||
Res::Local(..) | Res::Upvar(..) => convert_var(cx, expr, res),
|
||||
|
||||
_ => span_bug!(expr.span, "def `{:?}` not yet implemented", def),
|
||||
_ => span_bug!(expr.span, "res `{:?}` not yet implemented", res),
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
expr: &'tcx hir::Expr,
|
||||
def: Def)
|
||||
res: Res)
|
||||
-> ExprKind<'tcx> {
|
||||
let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
|
||||
|
||||
match def {
|
||||
Def::Local(id) => ExprKind::VarRef { id },
|
||||
match res {
|
||||
Res::Local(id) => ExprKind::VarRef { id },
|
||||
|
||||
Def::Upvar(var_hir_id, index, closure_expr_id) => {
|
||||
Res::Upvar(var_hir_id, index, closure_expr_id) => {
|
||||
debug!("convert_var(upvar({:?}, {:?}, {:?}))",
|
||||
var_hir_id,
|
||||
index,
|
||||
@ -1198,7 +1202,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
temp_lifetime,
|
||||
ty: var_ty,
|
||||
span: closure_expr.span,
|
||||
kind: convert_var(cx, closure_expr, freevar.def),
|
||||
kind: convert_var(cx, closure_expr, freevar.res),
|
||||
};
|
||||
match upvar_capture {
|
||||
ty::UpvarCapture::ByValue => captured_var.to_ref(),
|
||||
|
@ -286,7 +286,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
|
||||
PatKind::Path(hir::QPath::Resolved(None, ref path))
|
||||
if path.segments.len() == 1 && path.segments[0].args.is_none() => {
|
||||
format!("interpreted as {} {} pattern, not new variable",
|
||||
path.def.article(), path.def.kind_name())
|
||||
path.res.article(), path.res.kind_name())
|
||||
}
|
||||
_ => format!("pattern `{}` not covered", pattern_string),
|
||||
};
|
||||
|
@ -18,7 +18,7 @@ use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTyp
|
||||
use rustc::ty::subst::{SubstsRef, Kind};
|
||||
use rustc::ty::layout::VariantIdx;
|
||||
use rustc::hir::{self, PatKind, RangeEnd};
|
||||
use rustc::hir::def::{CtorOf, Def, CtorKind};
|
||||
use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
|
||||
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
|
||||
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
@ -599,7 +599,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
PatKind::TupleStruct(ref qpath, ref subpatterns, ddpos) => {
|
||||
let def = self.tables.qpath_def(qpath, pat.hir_id);
|
||||
let res = self.tables.qpath_res(qpath, pat.hir_id);
|
||||
let adt_def = match ty.sty {
|
||||
ty::Adt(adt_def, _) => adt_def,
|
||||
ty::Error => { // Avoid ICE (#50585)
|
||||
@ -609,7 +609,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
"tuple struct pattern not applied to an ADT {:?}",
|
||||
ty),
|
||||
};
|
||||
let variant_def = adt_def.variant_of_def(def);
|
||||
let variant_def = adt_def.variant_of_res(res);
|
||||
|
||||
let subpatterns =
|
||||
subpatterns.iter()
|
||||
@ -620,11 +620,11 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
})
|
||||
.collect();
|
||||
|
||||
self.lower_variant_or_leaf(def, pat.hir_id, pat.span, ty, subpatterns)
|
||||
self.lower_variant_or_leaf(res, pat.hir_id, pat.span, ty, subpatterns)
|
||||
}
|
||||
|
||||
PatKind::Struct(ref qpath, ref fields, _) => {
|
||||
let def = self.tables.qpath_def(qpath, pat.hir_id);
|
||||
let res = self.tables.qpath_res(qpath, pat.hir_id);
|
||||
let subpatterns =
|
||||
fields.iter()
|
||||
.map(|field| {
|
||||
@ -636,7 +636,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
})
|
||||
.collect();
|
||||
|
||||
self.lower_variant_or_leaf(def, pat.hir_id, pat.span, ty, subpatterns)
|
||||
self.lower_variant_or_leaf(res, pat.hir_id, pat.span, ty, subpatterns)
|
||||
}
|
||||
};
|
||||
|
||||
@ -726,22 +726,22 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
|
||||
fn lower_variant_or_leaf(
|
||||
&mut self,
|
||||
def: Def,
|
||||
res: Res,
|
||||
hir_id: hir::HirId,
|
||||
span: Span,
|
||||
ty: Ty<'tcx>,
|
||||
subpatterns: Vec<FieldPattern<'tcx>>,
|
||||
) -> PatternKind<'tcx> {
|
||||
let def = match def {
|
||||
Def::Ctor(variant_ctor_id, CtorOf::Variant, ..) => {
|
||||
let res = match res {
|
||||
Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => {
|
||||
let variant_id = self.tcx.parent(variant_ctor_id).unwrap();
|
||||
Def::Variant(variant_id)
|
||||
Res::Def(DefKind::Variant, variant_id)
|
||||
},
|
||||
def => def,
|
||||
res => res,
|
||||
};
|
||||
|
||||
let mut kind = match def {
|
||||
Def::Variant(variant_id) => {
|
||||
let mut kind = match res {
|
||||
Res::Def(DefKind::Variant, variant_id) => {
|
||||
let enum_id = self.tcx.parent(variant_id).unwrap();
|
||||
let adt_def = self.tcx.adt_def(enum_id);
|
||||
if adt_def.is_enum() {
|
||||
@ -764,8 +764,13 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
Def::Struct(..) | Def::Ctor(_, CtorOf::Struct, ..) | Def::Union(..) |
|
||||
Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) | Def::SelfCtor(..) => {
|
||||
Res::Def(DefKind::Struct, _)
|
||||
| Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
|
||||
| Res::Def(DefKind::Union, _)
|
||||
| Res::Def(DefKind::TyAlias, _)
|
||||
| Res::Def(DefKind::AssociatedTy, _)
|
||||
| Res::SelfTy(..)
|
||||
| Res::SelfCtor(..) => {
|
||||
PatternKind::Leaf { subpatterns }
|
||||
}
|
||||
|
||||
@ -803,13 +808,13 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
span: Span)
|
||||
-> Pattern<'tcx> {
|
||||
let ty = self.tables.node_type(id);
|
||||
let def = self.tables.qpath_def(qpath, id);
|
||||
let is_associated_const = match def {
|
||||
Def::AssociatedConst(_) => true,
|
||||
let res = self.tables.qpath_res(qpath, id);
|
||||
let is_associated_const = match res {
|
||||
Res::Def(DefKind::AssociatedConst, _) => true,
|
||||
_ => false,
|
||||
};
|
||||
let kind = match def {
|
||||
Def::Const(def_id) | Def::AssociatedConst(def_id) => {
|
||||
let kind = match res {
|
||||
Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssociatedConst, def_id) => {
|
||||
let substs = self.tables.node_substs(id);
|
||||
match ty::Instance::resolve(
|
||||
self.tcx,
|
||||
@ -871,7 +876,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
||||
},
|
||||
}
|
||||
}
|
||||
_ => self.lower_variant_or_leaf(def, id, span, ty, vec![]),
|
||||
_ => self.lower_variant_or_leaf(res, id, span, ty, vec![]),
|
||||
};
|
||||
|
||||
Pattern {
|
||||
|
@ -4,7 +4,7 @@ use std::mem;
|
||||
|
||||
use syntax::source_map::{self, Span, DUMMY_SP};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def::DefKind;
|
||||
use rustc::mir;
|
||||
use rustc::ty::layout::{
|
||||
self, Size, Align, HasDataLayout, LayoutOf, TyLayout
|
||||
@ -501,9 +501,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
|
||||
// entry in `locals` should never be used. Make it dead, to be sure.
|
||||
locals[mir::RETURN_PLACE].value = LocalValue::Dead;
|
||||
// Now mark those locals as dead that we do not want to initialize
|
||||
match self.tcx.describe_def(instance.def_id()) {
|
||||
match self.tcx.def_kind(instance.def_id()) {
|
||||
// statics and constants don't have `Storage*` statements, no need to look for them
|
||||
Some(Def::Static(..)) | Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => {},
|
||||
Some(DefKind::Static)
|
||||
| Some(DefKind::Const)
|
||||
| Some(DefKind::AssociatedConst) => {},
|
||||
_ => {
|
||||
trace!("push_stack_frame: {:?}: num_bbs: {}", span, mir.basic_blocks().len());
|
||||
for block in mir.basic_blocks() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Propagates constants for early reporting of statically known
|
||||
//! assertion failures
|
||||
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def::DefKind;
|
||||
use rustc::mir::{
|
||||
Constant, Location, Place, PlaceBase, Mir, Operand, Rvalue, Local,
|
||||
NullOp, UnOp, StatementKind, Statement, LocalKind, Static, StaticKind,
|
||||
@ -42,8 +42,8 @@ impl MirPass for ConstProp {
|
||||
.expect("Non-local call to local provider is_const_fn");
|
||||
|
||||
let is_fn_like = FnLikeNode::from_node(tcx.hir().get_by_hir_id(hir_id)).is_some();
|
||||
let is_assoc_const = match tcx.describe_def(source.def_id()) {
|
||||
Some(Def::AssociatedConst(_)) => true,
|
||||
let is_assoc_const = match tcx.def_kind(source.def_id()) {
|
||||
Some(DefKind::AssociatedConst) => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
@ -575,22 +575,25 @@ fn write_mir_sig(
|
||||
mir: &Mir<'_>,
|
||||
w: &mut dyn Write,
|
||||
) -> io::Result<()> {
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def::DefKind;
|
||||
|
||||
trace!("write_mir_sig: {:?}", src.instance);
|
||||
let descr = tcx.describe_def(src.def_id());
|
||||
let is_function = match descr {
|
||||
Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::Ctor(..)) => true,
|
||||
let kind = tcx.def_kind(src.def_id());
|
||||
let is_function = match kind {
|
||||
Some(DefKind::Fn)
|
||||
| Some(DefKind::Method)
|
||||
| Some(DefKind::Ctor(..)) => true,
|
||||
_ => tcx.is_closure(src.def_id()),
|
||||
};
|
||||
match (descr, src.promoted) {
|
||||
match (kind, src.promoted) {
|
||||
(_, Some(i)) => write!(w, "{:?} in ", i)?,
|
||||
(Some(Def::Const(_)), _) | (Some(Def::AssociatedConst(_)), _) => write!(w, "const ")?,
|
||||
(Some(Def::Static(def_id)), _) =>
|
||||
write!(w, "static {}", if tcx.is_mutable_static(def_id) { "mut " } else { "" })?,
|
||||
(Some(DefKind::Const), _)
|
||||
| (Some(DefKind::AssociatedConst), _) => write!(w, "const ")?,
|
||||
(Some(DefKind::Static), _) =>
|
||||
write!(w, "static {}", if tcx.is_mutable_static(src.def_id()) { "mut " } else { "" })?,
|
||||
(_, _) if is_function => write!(w, "fn ")?,
|
||||
(None, _) => {}, // things like anon const, not an item
|
||||
_ => bug!("Unexpected def description {:?}", descr),
|
||||
_ => bug!("Unexpected def kind {:?}", kind),
|
||||
}
|
||||
|
||||
ty::print::with_forced_impl_filename_line(|| {
|
||||
|
@ -15,7 +15,7 @@
|
||||
// by borrowck::gather_loans
|
||||
|
||||
use rustc::ty::cast::CastTy;
|
||||
use rustc::hir::def::{Def, CtorKind};
|
||||
use rustc::hir::def::{Res, DefKind, CtorKind};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::expr_use_visitor as euv;
|
||||
use rustc::middle::mem_categorization as mc;
|
||||
@ -319,16 +319,19 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
}
|
||||
}
|
||||
hir::ExprKind::Path(ref qpath) => {
|
||||
let def = v.tables.qpath_def(qpath, e.hir_id);
|
||||
match def {
|
||||
Def::Ctor(..) | Def::Fn(..) | Def::Method(..) | Def::SelfCtor(..) =>
|
||||
let res = v.tables.qpath_res(qpath, e.hir_id);
|
||||
match res {
|
||||
Res::Def(DefKind::Ctor(..), _)
|
||||
| Res::Def(DefKind::Fn, _)
|
||||
| Res::Def(DefKind::Method, _)
|
||||
| Res::SelfCtor(..) =>
|
||||
Promotable,
|
||||
|
||||
// References to a static that are themselves within a static
|
||||
// are inherently promotable with the exception
|
||||
// of "#[thread_local]" statics, which may not
|
||||
// outlive the current function
|
||||
Def::Static(did) => {
|
||||
Res::Def(DefKind::Static, did) => {
|
||||
|
||||
if v.in_static {
|
||||
for attr in &v.tcx.get_attrs(did)[..] {
|
||||
@ -346,8 +349,8 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
Def::Const(did) |
|
||||
Def::AssociatedConst(did) => {
|
||||
Res::Def(DefKind::Const, did) |
|
||||
Res::Def(DefKind::AssociatedConst, did) => {
|
||||
let promotable = if v.tcx.trait_of_item(did).is_some() {
|
||||
// Don't peek inside trait associated constants.
|
||||
NotPromotable
|
||||
@ -381,15 +384,15 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
}
|
||||
// The callee is an arbitrary expression, it doesn't necessarily have a definition.
|
||||
let def = if let hir::ExprKind::Path(ref qpath) = callee.node {
|
||||
v.tables.qpath_def(qpath, callee.hir_id)
|
||||
v.tables.qpath_res(qpath, callee.hir_id)
|
||||
} else {
|
||||
Def::Err
|
||||
Res::Err
|
||||
};
|
||||
let def_result = match def {
|
||||
Def::Ctor(_, _, CtorKind::Fn) |
|
||||
Def::SelfCtor(..) => Promotable,
|
||||
Def::Fn(did) => v.handle_const_fn_call(did),
|
||||
Def::Method(did) => {
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) |
|
||||
Res::SelfCtor(..) => Promotable,
|
||||
Res::Def(DefKind::Fn, did) => v.handle_const_fn_call(did),
|
||||
Res::Def(DefKind::Method, did) => {
|
||||
match v.tcx.associated_item(did).container {
|
||||
ty::ImplContainer(_) => v.handle_const_fn_call(did),
|
||||
ty::TraitContainer(_) => NotPromotable,
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
use rustc::bug;
|
||||
use rustc::hir::{self, Node, PatKind, AssociatedItemKind};
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def::{Res, DefKind};
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
|
||||
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
|
||||
use rustc::hir::itemlikevisit::DeepVisitor;
|
||||
@ -234,7 +234,7 @@ fn def_id_visibility<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
|
||||
Node::Item(item) => match &item.node {
|
||||
hir::ItemKind::Impl(.., None, _, _) => &impl_item.vis,
|
||||
hir::ItemKind::Impl(.., Some(trait_ref), _, _)
|
||||
=> return def_id_visibility(tcx, trait_ref.path.def.def_id()),
|
||||
=> return def_id_visibility(tcx, trait_ref.path.res.def_id()),
|
||||
kind => bug!("unexpected item kind: {:?}", kind),
|
||||
}
|
||||
node => bug!("unexpected node kind: {:?}", node),
|
||||
@ -472,7 +472,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
|
||||
/// to update the visibility of the intermediate use so that it isn't linted
|
||||
/// by `unreachable_pub`.
|
||||
///
|
||||
/// This isn't trivial as `path.def` has the `DefId` of the eventual target
|
||||
/// This isn't trivial as `path.res` has the `DefId` of the eventual target
|
||||
/// of the use statement not of the next intermediate use statement.
|
||||
///
|
||||
/// To do this, consider the last two segments of the path to our intermediate
|
||||
@ -485,8 +485,8 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
|
||||
/// namespaces. See <https://github.com/rust-lang/rust/pull/57922#discussion_r251234202>.
|
||||
fn update_visibility_of_intermediate_use_statements(&mut self, segments: &[hir::PathSegment]) {
|
||||
if let Some([module, segment]) = segments.rchunks_exact(2).next() {
|
||||
if let Some(item) = module.def
|
||||
.and_then(|def| def.mod_def_id())
|
||||
if let Some(item) = module.res
|
||||
.and_then(|res| res.mod_def_id())
|
||||
.and_then(|def_id| self.tcx.hir().as_local_hir_id(def_id))
|
||||
.map(|module_hir_id| self.tcx.hir().expect_item_by_hir_id(module_hir_id))
|
||||
{
|
||||
@ -717,7 +717,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
||||
if let Some(exports) = self.tcx.module_exports(def_id) {
|
||||
for export in exports.iter() {
|
||||
if export.vis == ty::Visibility::Public {
|
||||
if let Some(def_id) = export.def.opt_def_id() {
|
||||
if let Some(def_id) = export.res.opt_def_id() {
|
||||
if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
|
||||
self.update(hir_id, Some(AccessLevel::Exported));
|
||||
}
|
||||
@ -762,7 +762,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
||||
let def_id = self.tcx.hir().local_def_id_from_hir_id(module_id);
|
||||
if let Some(exports) = self.tcx.module_exports(def_id) {
|
||||
for export in exports.iter() {
|
||||
if let Some(hir_id) = self.tcx.hir().as_local_hir_id(export.def.def_id()) {
|
||||
if let Some(hir_id) = self.tcx.hir().as_local_hir_id(export.res.def_id()) {
|
||||
self.update(hir_id, level);
|
||||
}
|
||||
}
|
||||
@ -900,9 +900,9 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> {
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
||||
match expr.node {
|
||||
hir::ExprKind::Struct(ref qpath, ref fields, ref base) => {
|
||||
let def = self.tables.qpath_def(qpath, expr.hir_id);
|
||||
let res = self.tables.qpath_res(qpath, expr.hir_id);
|
||||
let adt = self.tables.expr_ty(expr).ty_adt_def().unwrap();
|
||||
let variant = adt.variant_of_def(def);
|
||||
let variant = adt.variant_of_res(res);
|
||||
if let Some(ref base) = *base {
|
||||
// If the expression uses FRU we need to make sure all the unmentioned fields
|
||||
// are checked for privacy (RFC 736). Rather than computing the set of
|
||||
@ -934,9 +934,9 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> {
|
||||
fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
|
||||
match pat.node {
|
||||
PatKind::Struct(ref qpath, ref fields, _) => {
|
||||
let def = self.tables.qpath_def(qpath, pat.hir_id);
|
||||
let res = self.tables.qpath_res(qpath, pat.hir_id);
|
||||
let adt = self.tables.pat_ty(pat).ty_adt_def().unwrap();
|
||||
let variant = adt.variant_of_def(def);
|
||||
let variant = adt.variant_of_res(res);
|
||||
for field in fields {
|
||||
let use_ctxt = field.node.ident.span;
|
||||
let index = self.tcx.field_index(field.node.hir_id, self.tables);
|
||||
@ -1105,26 +1105,30 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
|
||||
// more code internal visibility at link time. (Access to private functions
|
||||
// is already prohibited by type privacy for function types.)
|
||||
fn visit_qpath(&mut self, qpath: &'tcx hir::QPath, id: hir::HirId, span: Span) {
|
||||
let def = match *qpath {
|
||||
hir::QPath::Resolved(_, ref path) => match path.def {
|
||||
Def::Method(..) | Def::AssociatedConst(..) |
|
||||
Def::AssociatedTy(..) | Def::AssociatedExistential(..) |
|
||||
Def::Static(..) => Some(path.def),
|
||||
_ => None,
|
||||
}
|
||||
hir::QPath::TypeRelative(..) => {
|
||||
self.tables.type_dependent_def(id)
|
||||
}
|
||||
let def = match self.tables.qpath_res(qpath, id) {
|
||||
Res::Def(kind, def_id) => Some((kind, def_id)),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(def) = def {
|
||||
let def_id = def.def_id();
|
||||
let is_local_static = if let Def::Static(..) = def { def_id.is_local() } else { false };
|
||||
let def = def.filter(|(kind, _)| {
|
||||
match kind {
|
||||
DefKind::Method
|
||||
| DefKind::AssociatedConst
|
||||
| DefKind::AssociatedTy
|
||||
| DefKind::AssociatedExistential
|
||||
| DefKind::Static => true,
|
||||
_ => false,
|
||||
}
|
||||
});
|
||||
if let Some((kind, def_id)) = def {
|
||||
let is_local_static = if let DefKind::Static = kind {
|
||||
def_id.is_local()
|
||||
} else { false };
|
||||
if !self.item_is_accessible(def_id) && !is_local_static {
|
||||
let name = match *qpath {
|
||||
hir::QPath::Resolved(_, ref path) => path.to_string(),
|
||||
hir::QPath::TypeRelative(_, ref segment) => segment.ident.to_string(),
|
||||
};
|
||||
let msg = format!("{} `{}` is private", def.kind_name(), name);
|
||||
let msg = format!("{} `{}` is private", kind.descr(), name);
|
||||
self.tcx.sess.span_err(span, &msg);
|
||||
return;
|
||||
}
|
||||
@ -1227,9 +1231,9 @@ struct ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b: 'a, 'tcx: 'b> {
|
||||
|
||||
impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
fn path_is_private_type(&self, path: &hir::Path) -> bool {
|
||||
let did = match path.def {
|
||||
Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => return false,
|
||||
def => def.def_id(),
|
||||
let did = match path.res {
|
||||
Res::PrimTy(..) | Res::SelfTy(..) | Res::Err => return false,
|
||||
res => res.def_id(),
|
||||
};
|
||||
|
||||
// A path can only be private if:
|
||||
@ -1349,7 +1353,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||
let not_private_trait =
|
||||
trait_ref.as_ref().map_or(true, // no trait counts as public trait
|
||||
|tr| {
|
||||
let did = tr.path.def.def_id();
|
||||
let did = tr.path.res.def_id();
|
||||
|
||||
if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) {
|
||||
self.trait_is_public(hir_id)
|
||||
|
@ -44,7 +44,7 @@ use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
use log::debug;
|
||||
|
||||
type Def = def::Def<NodeId>;
|
||||
type Res = def::Res<NodeId>;
|
||||
|
||||
impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, Mark) {
|
||||
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
|
||||
@ -58,10 +58,10 @@ impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, Mark) {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToNameBinding<'a> for (Def, ty::Visibility, Span, Mark) {
|
||||
impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, Mark) {
|
||||
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
|
||||
arenas.alloc_name_binding(NameBinding {
|
||||
kind: NameBindingKind::Def(self.0, false),
|
||||
kind: NameBindingKind::Res(self.0, false),
|
||||
ambiguity: None,
|
||||
vis: self.1,
|
||||
span: self.2,
|
||||
@ -72,10 +72,10 @@ impl<'a> ToNameBinding<'a> for (Def, ty::Visibility, Span, Mark) {
|
||||
|
||||
pub(crate) struct IsMacroExport;
|
||||
|
||||
impl<'a> ToNameBinding<'a> for (Def, ty::Visibility, Span, Mark, IsMacroExport) {
|
||||
impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, Mark, IsMacroExport) {
|
||||
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
|
||||
arenas.alloc_name_binding(NameBinding {
|
||||
kind: NameBindingKind::Def(self.0, true),
|
||||
kind: NameBindingKind::Res(self.0, true),
|
||||
ambiguity: None,
|
||||
vis: self.1,
|
||||
span: self.2,
|
||||
@ -193,7 +193,7 @@ impl<'a> Resolver<'a> {
|
||||
if source.ident.name == keywords::DollarCrate.name() && module_path.is_empty() {
|
||||
let crate_root = self.resolve_crate_root(source.ident);
|
||||
let crate_name = match crate_root.kind {
|
||||
ModuleKind::Def(_, name) => name,
|
||||
ModuleKind::Def(.., name) => name,
|
||||
ModuleKind::Block(..) => unreachable!(),
|
||||
};
|
||||
// HACK(eddyb) unclear how good this is, but keeping `$crate`
|
||||
@ -424,7 +424,7 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
ItemKind::Mod(..) => {
|
||||
let def_id = self.definitions.local_def_id(item.id);
|
||||
let module_kind = ModuleKind::Def(Def::Mod(def_id), ident.name);
|
||||
let module_kind = ModuleKind::Def(DefKind::Mod, def_id, ident.name);
|
||||
let module = self.arenas.alloc_module(ModuleData {
|
||||
no_implicit_prelude: parent.no_implicit_prelude || {
|
||||
attr::contains_name(&item.attrs, "no_implicit_prelude")
|
||||
@ -443,30 +443,33 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
// These items live in the value namespace.
|
||||
ItemKind::Static(..) => {
|
||||
let def = Def::Static(self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
|
||||
let res = Res::Def(DefKind::Static, self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, ValueNS, (res, vis, sp, expansion));
|
||||
}
|
||||
ItemKind::Const(..) => {
|
||||
let def = Def::Const(self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
|
||||
let res = Res::Def(DefKind::Const, self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, ValueNS, (res, vis, sp, expansion));
|
||||
}
|
||||
ItemKind::Fn(..) => {
|
||||
let def = Def::Fn(self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
|
||||
let res = Res::Def(DefKind::Fn, self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, ValueNS, (res, vis, sp, expansion));
|
||||
|
||||
// Functions introducing procedural macros reserve a slot
|
||||
// in the macro namespace as well (see #52225).
|
||||
if attr::contains_name(&item.attrs, "proc_macro") ||
|
||||
attr::contains_name(&item.attrs, "proc_macro_attribute") {
|
||||
let def = Def::Macro(def.def_id(), MacroKind::ProcMacroStub);
|
||||
self.define(parent, ident, MacroNS, (def, vis, sp, expansion));
|
||||
let res = Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), res.def_id());
|
||||
self.define(parent, ident, MacroNS, (res, vis, sp, expansion));
|
||||
}
|
||||
if let Some(attr) = attr::find_by_name(&item.attrs, "proc_macro_derive") {
|
||||
if let Some(trait_attr) =
|
||||
attr.meta_item_list().and_then(|list| list.get(0).cloned()) {
|
||||
if let Some(ident) = trait_attr.ident() {
|
||||
let def = Def::Macro(def.def_id(), MacroKind::ProcMacroStub);
|
||||
self.define(parent, ident, MacroNS, (def, vis, ident.span, expansion));
|
||||
let res = Res::Def(
|
||||
DefKind::Macro(MacroKind::ProcMacroStub),
|
||||
res.def_id(),
|
||||
);
|
||||
self.define(parent, ident, MacroNS, (res, vis, ident.span, expansion));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -474,18 +477,21 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
// These items live in the type namespace.
|
||||
ItemKind::Ty(..) => {
|
||||
let def = Def::TyAlias(self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
|
||||
let res = Res::Def(DefKind::TyAlias, self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, TypeNS, (res, vis, sp, expansion));
|
||||
}
|
||||
|
||||
ItemKind::Existential(_, _) => {
|
||||
let def = Def::Existential(self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
|
||||
let res = Res::Def(DefKind::Existential, self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, TypeNS, (res, vis, sp, expansion));
|
||||
}
|
||||
|
||||
ItemKind::Enum(ref enum_definition, _) => {
|
||||
let def = Def::Enum(self.definitions.local_def_id(item.id));
|
||||
let module_kind = ModuleKind::Def(def, ident.name);
|
||||
let module_kind = ModuleKind::Def(
|
||||
DefKind::Enum,
|
||||
self.definitions.local_def_id(item.id),
|
||||
ident.name,
|
||||
);
|
||||
let module = self.new_module(parent,
|
||||
module_kind,
|
||||
parent.normal_ancestor_id,
|
||||
@ -499,16 +505,16 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
ItemKind::TraitAlias(..) => {
|
||||
let def = Def::TraitAlias(self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
|
||||
let res = Res::Def(DefKind::TraitAlias, self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, TypeNS, (res, vis, sp, expansion));
|
||||
}
|
||||
|
||||
// These items live in both the type and value namespaces.
|
||||
ItemKind::Struct(ref struct_def, _) => {
|
||||
// Define a name in the type namespace.
|
||||
let def_id = self.definitions.local_def_id(item.id);
|
||||
let def = Def::Struct(def_id);
|
||||
self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
|
||||
let res = Res::Def(DefKind::Struct, def_id);
|
||||
self.define(parent, ident, TypeNS, (res, vis, sp, expansion));
|
||||
|
||||
let mut ctor_vis = vis;
|
||||
|
||||
@ -534,17 +540,18 @@ impl<'a> Resolver<'a> {
|
||||
// If this is a tuple or unit struct, define a name
|
||||
// in the value namespace as well.
|
||||
if let Some(ctor_node_id) = struct_def.ctor_id() {
|
||||
let ctor_def = Def::Ctor(self.definitions.local_def_id(ctor_node_id),
|
||||
CtorOf::Struct,
|
||||
CtorKind::from_ast(struct_def));
|
||||
self.define(parent, ident, ValueNS, (ctor_def, ctor_vis, sp, expansion));
|
||||
self.struct_constructors.insert(def.def_id(), (ctor_def, ctor_vis));
|
||||
let ctor_res = Res::Def(
|
||||
DefKind::Ctor(CtorOf::Struct, CtorKind::from_ast(struct_def)),
|
||||
self.definitions.local_def_id(ctor_node_id),
|
||||
);
|
||||
self.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion));
|
||||
self.struct_constructors.insert(res.def_id(), (ctor_res, ctor_vis));
|
||||
}
|
||||
}
|
||||
|
||||
ItemKind::Union(ref vdata, _) => {
|
||||
let def = Def::Union(self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
|
||||
let res = Res::Def(DefKind::Union, self.definitions.local_def_id(item.id));
|
||||
self.define(parent, ident, TypeNS, (res, vis, sp, expansion));
|
||||
|
||||
// Record field names for error reporting.
|
||||
let field_names = vdata.fields().iter().filter_map(|field| {
|
||||
@ -561,7 +568,7 @@ impl<'a> Resolver<'a> {
|
||||
let def_id = self.definitions.local_def_id(item.id);
|
||||
|
||||
// Add all the items within to a new module.
|
||||
let module_kind = ModuleKind::Def(Def::Trait(def_id), ident.name);
|
||||
let module_kind = ModuleKind::Def(DefKind::Trait, def_id, ident.name);
|
||||
let module = self.new_module(parent,
|
||||
module_kind,
|
||||
parent.normal_ancestor_id,
|
||||
@ -586,8 +593,8 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
// Define a name in the type namespace.
|
||||
let def_id = self.definitions.local_def_id(variant.node.id);
|
||||
let def = Def::Variant(def_id);
|
||||
self.define(parent, ident, TypeNS, (def, vis, variant.span, expansion));
|
||||
let res = Res::Def(DefKind::Variant, def_id);
|
||||
self.define(parent, ident, TypeNS, (res, vis, variant.span, expansion));
|
||||
|
||||
// If the variant is marked as non_exhaustive then lower the visibility to within the
|
||||
// crate.
|
||||
@ -605,27 +612,27 @@ impl<'a> Resolver<'a> {
|
||||
let ctor_node_id = variant.node.data.ctor_id().unwrap_or(variant.node.id);
|
||||
let ctor_def_id = self.definitions.local_def_id(ctor_node_id);
|
||||
let ctor_kind = CtorKind::from_ast(&variant.node.data);
|
||||
let ctor_def = Def::Ctor(ctor_def_id, CtorOf::Variant, ctor_kind);
|
||||
self.define(parent, ident, ValueNS, (ctor_def, ctor_vis, variant.span, expansion));
|
||||
let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
|
||||
self.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expansion));
|
||||
}
|
||||
|
||||
/// Constructs the reduced graph for one foreign item.
|
||||
fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, expansion: Mark) {
|
||||
let (def, ns) = match item.node {
|
||||
let (res, ns) = match item.node {
|
||||
ForeignItemKind::Fn(..) => {
|
||||
(Def::Fn(self.definitions.local_def_id(item.id)), ValueNS)
|
||||
(Res::Def(DefKind::Fn, self.definitions.local_def_id(item.id)), ValueNS)
|
||||
}
|
||||
ForeignItemKind::Static(..) => {
|
||||
(Def::Static(self.definitions.local_def_id(item.id)), ValueNS)
|
||||
(Res::Def(DefKind::Static, self.definitions.local_def_id(item.id)), ValueNS)
|
||||
}
|
||||
ForeignItemKind::Ty => {
|
||||
(Def::ForeignTy(self.definitions.local_def_id(item.id)), TypeNS)
|
||||
(Res::Def(DefKind::ForeignTy, self.definitions.local_def_id(item.id)), TypeNS)
|
||||
}
|
||||
ForeignItemKind::Macro(_) => unreachable!(),
|
||||
};
|
||||
let parent = self.current_module;
|
||||
let vis = self.resolve_visibility(&item.vis);
|
||||
self.define(parent, item.ident, ns, (def, vis, item.span, expansion));
|
||||
self.define(parent, item.ident, ns, (res, vis, item.span, expansion));
|
||||
}
|
||||
|
||||
fn build_reduced_graph_for_block(&mut self, block: &Block, expansion: Mark) {
|
||||
@ -642,45 +649,53 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
/// Builds the reduced graph for a single item in an external crate.
|
||||
fn build_reduced_graph_for_external_crate_def(
|
||||
fn build_reduced_graph_for_external_crate_res(
|
||||
&mut self,
|
||||
parent: Module<'a>,
|
||||
child: Export<ast::NodeId>,
|
||||
) {
|
||||
let Export { ident, def, vis, span } = child;
|
||||
let Export { ident, res, vis, span } = child;
|
||||
// FIXME: We shouldn't create the gensym here, it should come from metadata,
|
||||
// but metadata cannot encode gensyms currently, so we create it here.
|
||||
// This is only a guess, two equivalent idents may incorrectly get different gensyms here.
|
||||
let ident = ident.gensym_if_underscore();
|
||||
let expansion = Mark::root(); // FIXME(jseyfried) intercrate hygiene
|
||||
match def {
|
||||
Def::Mod(def_id) | Def::Enum(def_id) => {
|
||||
match res {
|
||||
Res::Def(kind @ DefKind::Mod, def_id)
|
||||
| Res::Def(kind @ DefKind::Enum, def_id) => {
|
||||
let module = self.new_module(parent,
|
||||
ModuleKind::Def(def, ident.name),
|
||||
ModuleKind::Def(kind, def_id, ident.name),
|
||||
def_id,
|
||||
expansion,
|
||||
span);
|
||||
self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
|
||||
}
|
||||
Def::Variant(..) | Def::TyAlias(..) | Def::ForeignTy(..) | Def::Existential(..) |
|
||||
Def::TraitAlias(..) | Def::PrimTy(..) | Def::ToolMod => {
|
||||
self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
|
||||
Res::Def(DefKind::Variant, _)
|
||||
| Res::Def(DefKind::TyAlias, _)
|
||||
| Res::Def(DefKind::ForeignTy, _)
|
||||
| Res::Def(DefKind::Existential, _)
|
||||
| Res::Def(DefKind::TraitAlias, _)
|
||||
| Res::PrimTy(..)
|
||||
| Res::ToolMod => {
|
||||
self.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion));
|
||||
}
|
||||
Def::Fn(..) | Def::Static(..) | Def::Const(..) |
|
||||
Def::Ctor(_, CtorOf::Variant, ..) => {
|
||||
self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion));
|
||||
Res::Def(DefKind::Fn, _)
|
||||
| Res::Def(DefKind::Static, _)
|
||||
| Res::Def(DefKind::Const, _)
|
||||
| Res::Def(DefKind::Ctor(CtorOf::Variant, ..), _) => {
|
||||
self.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion));
|
||||
}
|
||||
Def::Ctor(def_id, CtorOf::Struct, ..) => {
|
||||
self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion));
|
||||
Res::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) => {
|
||||
self.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion));
|
||||
|
||||
if let Some(struct_def_id) =
|
||||
self.cstore.def_key(def_id).parent
|
||||
.map(|index| DefId { krate: def_id.krate, index: index }) {
|
||||
self.struct_constructors.insert(struct_def_id, (def, vis));
|
||||
self.struct_constructors.insert(struct_def_id, (res, vis));
|
||||
}
|
||||
}
|
||||
Def::Trait(def_id) => {
|
||||
let module_kind = ModuleKind::Def(def, ident.name);
|
||||
Res::Def(DefKind::Trait, def_id) => {
|
||||
let module_kind = ModuleKind::Def(DefKind::Trait, def_id, ident.name);
|
||||
let module = self.new_module(parent,
|
||||
module_kind,
|
||||
parent.normal_ancestor_id,
|
||||
@ -689,29 +704,31 @@ impl<'a> Resolver<'a> {
|
||||
self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
|
||||
|
||||
for child in self.cstore.item_children_untracked(def_id, self.session) {
|
||||
let def = child.def.map_id(|_| panic!("unexpected id"));
|
||||
let ns = if let Def::AssociatedTy(..) = def { TypeNS } else { ValueNS };
|
||||
let res = child.res.map_id(|_| panic!("unexpected id"));
|
||||
let ns = if let Res::Def(DefKind::AssociatedTy, _) = res {
|
||||
TypeNS
|
||||
} else { ValueNS };
|
||||
self.define(module, child.ident, ns,
|
||||
(def, ty::Visibility::Public, DUMMY_SP, expansion));
|
||||
(res, ty::Visibility::Public, DUMMY_SP, expansion));
|
||||
|
||||
if self.cstore.associated_item_cloned_untracked(child.def.def_id())
|
||||
if self.cstore.associated_item_cloned_untracked(child.res.def_id())
|
||||
.method_has_self_argument {
|
||||
self.has_self.insert(def.def_id());
|
||||
self.has_self.insert(res.def_id());
|
||||
}
|
||||
}
|
||||
module.populated.set(true);
|
||||
}
|
||||
Def::Struct(def_id) | Def::Union(def_id) => {
|
||||
self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
|
||||
Res::Def(DefKind::Struct, def_id) | Res::Def(DefKind::Union, def_id) => {
|
||||
self.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion));
|
||||
|
||||
// Record field names for error reporting.
|
||||
let field_names = self.cstore.struct_field_names_untracked(def_id);
|
||||
self.insert_field_names(def_id, field_names);
|
||||
}
|
||||
Def::Macro(..) | Def::NonMacroAttr(..) => {
|
||||
self.define(parent, ident, MacroNS, (def, vis, DUMMY_SP, expansion));
|
||||
Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => {
|
||||
self.define(parent, ident, MacroNS, (res, vis, DUMMY_SP, expansion));
|
||||
}
|
||||
_ => bug!("unexpected definition: {:?}", def)
|
||||
_ => bug!("unexpected resolution: {:?}", res)
|
||||
}
|
||||
}
|
||||
|
||||
@ -733,7 +750,7 @@ impl<'a> Resolver<'a> {
|
||||
Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id })))
|
||||
};
|
||||
|
||||
let kind = ModuleKind::Def(Def::Mod(def_id), name.as_symbol());
|
||||
let kind = ModuleKind::Def(DefKind::Mod, def_id, name.as_symbol());
|
||||
let module =
|
||||
self.arenas.alloc_module(ModuleData::new(parent, kind, def_id, Mark::root(), DUMMY_SP));
|
||||
self.extern_module_map.insert((def_id, macros_only), module);
|
||||
@ -752,13 +769,13 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_macro(&mut self, def: Def) -> Lrc<SyntaxExtension> {
|
||||
let def_id = match def {
|
||||
Def::Macro(def_id, ..) => def_id,
|
||||
Def::NonMacroAttr(attr_kind) => return Lrc::new(SyntaxExtension::NonMacroAttr {
|
||||
pub fn get_macro(&mut self, res: Res) -> Lrc<SyntaxExtension> {
|
||||
let def_id = match res {
|
||||
Res::Def(DefKind::Macro(..), def_id) => def_id,
|
||||
Res::NonMacroAttr(attr_kind) => return Lrc::new(SyntaxExtension::NonMacroAttr {
|
||||
mark_used: attr_kind == NonMacroAttrKind::Tool,
|
||||
}),
|
||||
_ => panic!("expected `Def::Macro` or `Def::NonMacroAttr`"),
|
||||
_ => panic!("expected `DefKind::Macro` or `Res::NonMacroAttr`"),
|
||||
};
|
||||
if let Some(ext) = self.macro_map.get(&def_id) {
|
||||
return ext.clone();
|
||||
@ -784,7 +801,7 @@ impl<'a> Resolver<'a> {
|
||||
let def_id = module.def_id().unwrap();
|
||||
for child in self.cstore.item_children_untracked(def_id, self.session) {
|
||||
let child = child.map_id(|_| panic!("unexpected id"));
|
||||
self.build_reduced_graph_for_external_crate_def(module, child);
|
||||
self.build_reduced_graph_for_external_crate_res(module, child);
|
||||
}
|
||||
module.populated.set(true)
|
||||
}
|
||||
@ -1015,20 +1032,20 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
|
||||
|
||||
// Add the item to the trait info.
|
||||
let item_def_id = self.resolver.definitions.local_def_id(item.id);
|
||||
let (def, ns) = match item.node {
|
||||
TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS),
|
||||
let (res, ns) = match item.node {
|
||||
TraitItemKind::Const(..) => (Res::Def(DefKind::AssociatedConst, item_def_id), ValueNS),
|
||||
TraitItemKind::Method(ref sig, _) => {
|
||||
if sig.decl.has_self() {
|
||||
self.resolver.has_self.insert(item_def_id);
|
||||
}
|
||||
(Def::Method(item_def_id), ValueNS)
|
||||
(Res::Def(DefKind::Method, item_def_id), ValueNS)
|
||||
}
|
||||
TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS),
|
||||
TraitItemKind::Type(..) => (Res::Def(DefKind::AssociatedTy, item_def_id), TypeNS),
|
||||
TraitItemKind::Macro(_) => bug!(), // handled above
|
||||
};
|
||||
|
||||
let vis = ty::Visibility::Public;
|
||||
self.resolver.define(parent, item.ident, ns, (def, vis, item.span, self.expansion));
|
||||
self.resolver.define(parent, item.ident, ns, (res, vis, item.span, self.expansion));
|
||||
|
||||
self.resolver.current_module = parent.parent.unwrap(); // nearest normal ancestor
|
||||
visit::walk_trait_item(self, item);
|
||||
|
@ -2,7 +2,7 @@ use std::cmp::Reverse;
|
||||
|
||||
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
|
||||
use log::debug;
|
||||
use rustc::hir::def::{self, CtorKind, Namespace::*};
|
||||
use rustc::hir::def::{self, DefKind, CtorKind, Namespace::*};
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
|
||||
use rustc::session::{Session, config::nightly_options};
|
||||
use syntax::ast::{self, Expr, ExprKind, Ident};
|
||||
@ -10,7 +10,7 @@ use syntax::ext::base::MacroKind;
|
||||
use syntax::symbol::{Symbol, keywords};
|
||||
use syntax_pos::{BytePos, Span};
|
||||
|
||||
type Def = def::Def<ast::NodeId>;
|
||||
type Res = def::Res<ast::NodeId>;
|
||||
|
||||
use crate::macros::ParentScope;
|
||||
use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver};
|
||||
@ -26,20 +26,22 @@ impl<'a> Resolver<'a> {
|
||||
path: &[Segment],
|
||||
span: Span,
|
||||
source: PathSource<'_>,
|
||||
def: Option<Def>,
|
||||
res: Option<Res>,
|
||||
) -> (DiagnosticBuilder<'a>, Vec<ImportSuggestion>) {
|
||||
let ident_span = path.last().map_or(span, |ident| ident.ident.span);
|
||||
let ns = source.namespace();
|
||||
let is_expected = &|def| source.is_expected(def);
|
||||
let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false };
|
||||
let is_expected = &|res| source.is_expected(res);
|
||||
let is_enum_variant = &|res| {
|
||||
if let Res::Def(DefKind::Variant, _) = res { true } else { false }
|
||||
};
|
||||
|
||||
// Make the base error.
|
||||
let expected = source.descr_expected();
|
||||
let path_str = Segment::names_to_string(path);
|
||||
let item_str = path.last().unwrap().ident;
|
||||
let code = source.error_code(def.is_some());
|
||||
let (base_msg, fallback_label, base_span) = if let Some(def) = def {
|
||||
(format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str),
|
||||
let code = source.error_code(res.is_some());
|
||||
let (base_msg, fallback_label, base_span) = if let Some(res) = res {
|
||||
(format!("expected {}, found {} `{}`", expected, res.kind_name(), path_str),
|
||||
format!("not a {}", expected),
|
||||
span)
|
||||
} else {
|
||||
@ -54,9 +56,9 @@ impl<'a> Resolver<'a> {
|
||||
mod_path, Some(TypeNS), false, span, CrateLint::No
|
||||
) {
|
||||
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
|
||||
module.def(),
|
||||
module.def_kind(),
|
||||
_ => None,
|
||||
}.map_or(String::new(), |def| format!("{} ", def.kind_name()));
|
||||
}.map_or(String::new(), |kind| format!("{} ", kind.descr()));
|
||||
(mod_prefix, format!("`{}`", Segment::names_to_string(mod_path)))
|
||||
};
|
||||
(format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str),
|
||||
@ -111,13 +113,14 @@ impl<'a> Resolver<'a> {
|
||||
let candidates = self.lookup_import_candidates(ident, ns, is_expected)
|
||||
.drain(..)
|
||||
.filter(|ImportSuggestion { did, .. }| {
|
||||
match (did, def.and_then(|def| def.opt_def_id())) {
|
||||
match (did, res.and_then(|res| res.opt_def_id())) {
|
||||
(Some(suggestion_did), Some(actual_did)) => *suggestion_did != actual_did,
|
||||
_ => true,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) {
|
||||
let crate_def_id = DefId::local(CRATE_DEF_INDEX);
|
||||
if candidates.is_empty() && is_expected(Res::Def(DefKind::Enum, crate_def_id)) {
|
||||
let enum_candidates =
|
||||
self.lookup_import_candidates(ident, ns, is_enum_variant);
|
||||
let mut enum_candidates = enum_candidates.iter()
|
||||
@ -129,7 +132,7 @@ impl<'a> Resolver<'a> {
|
||||
if !enum_candidates.is_empty() {
|
||||
// Contextualize for E0412 "cannot find type", but don't belabor the point
|
||||
// (that it's a variant) for E0573 "expected type, found variant".
|
||||
let preamble = if def.is_none() {
|
||||
let preamble = if res.is_none() {
|
||||
let others = match enum_candidates.len() {
|
||||
1 => String::new(),
|
||||
2 => " and 1 other".to_owned(),
|
||||
@ -221,11 +224,11 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
// Try context-dependent help if relaxed lookup didn't work.
|
||||
if let Some(def) = def {
|
||||
if let Some(res) = res {
|
||||
if self.smart_resolve_context_dependent_help(&mut err,
|
||||
span,
|
||||
source,
|
||||
def,
|
||||
res,
|
||||
&path_str,
|
||||
&fallback_label) {
|
||||
return (err, candidates);
|
||||
@ -298,12 +301,12 @@ impl<'a> Resolver<'a> {
|
||||
err: &mut DiagnosticBuilder<'a>,
|
||||
span: Span,
|
||||
source: PathSource<'_>,
|
||||
def: Def,
|
||||
res: Res,
|
||||
path_str: &str,
|
||||
fallback_label: &str,
|
||||
) -> bool {
|
||||
let ns = source.namespace();
|
||||
let is_expected = &|def| source.is_expected(def);
|
||||
let is_expected = &|res| source.is_expected(res);
|
||||
|
||||
let path_sep = |err: &mut DiagnosticBuilder<'_>, expr: &Expr| match expr.node {
|
||||
ExprKind::Field(_, ident) => {
|
||||
@ -361,8 +364,8 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
};
|
||||
|
||||
match (def, source) {
|
||||
(Def::Macro(..), _) => {
|
||||
match (res, source) {
|
||||
(Res::Def(DefKind::Macro(..), _), _) => {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"use `!` to invoke the macro",
|
||||
@ -373,18 +376,20 @@ impl<'a> Resolver<'a> {
|
||||
err.note("if you want the `try` keyword, you need to be in the 2018 edition");
|
||||
}
|
||||
}
|
||||
(Def::TyAlias(..), PathSource::Trait(_)) => {
|
||||
(Res::Def(DefKind::TyAlias, _), PathSource::Trait(_)) => {
|
||||
err.span_label(span, "type aliases cannot be used as traits");
|
||||
if nightly_options::is_nightly_build() {
|
||||
err.note("did you mean to use a trait alias?");
|
||||
}
|
||||
}
|
||||
(Def::Mod(..), PathSource::Expr(Some(parent))) => if !path_sep(err, &parent) {
|
||||
return false;
|
||||
},
|
||||
(Def::Enum(..), PathSource::TupleStruct)
|
||||
| (Def::Enum(..), PathSource::Expr(..)) => {
|
||||
if let Some(variants) = self.collect_enum_variants(def) {
|
||||
(Res::Def(DefKind::Mod, _), PathSource::Expr(Some(parent))) => {
|
||||
if !path_sep(err, &parent) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
(Res::Def(DefKind::Enum, def_id), PathSource::TupleStruct)
|
||||
| (Res::Def(DefKind::Enum, def_id), PathSource::Expr(..)) => {
|
||||
if let Some(variants) = self.collect_enum_variants(def_id) {
|
||||
if !variants.is_empty() {
|
||||
let msg = if variants.len() == 1 {
|
||||
"try using the enum's variant"
|
||||
@ -403,7 +408,7 @@ impl<'a> Resolver<'a> {
|
||||
err.note("did you mean to use one of the enum's variants?");
|
||||
}
|
||||
},
|
||||
(Def::Struct(def_id), _) if ns == ValueNS => {
|
||||
(Res::Def(DefKind::Struct, def_id), _) if ns == ValueNS => {
|
||||
if let Some((ctor_def, ctor_vis))
|
||||
= self.struct_constructors.get(&def_id).cloned() {
|
||||
let accessible_ctor = self.is_accessible(ctor_vis);
|
||||
@ -417,16 +422,17 @@ impl<'a> Resolver<'a> {
|
||||
bad_struct_syntax_suggestion();
|
||||
}
|
||||
}
|
||||
(Def::Union(..), _) |
|
||||
(Def::Variant(..), _) |
|
||||
(Def::Ctor(_, _, CtorKind::Fictive), _) if ns == ValueNS => {
|
||||
(Res::Def(DefKind::Union, _), _) |
|
||||
(Res::Def(DefKind::Variant, _), _) |
|
||||
(Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _), _) if ns == ValueNS => {
|
||||
bad_struct_syntax_suggestion();
|
||||
}
|
||||
(Def::SelfTy(..), _) if ns == ValueNS => {
|
||||
(Res::SelfTy(..), _) if ns == ValueNS => {
|
||||
err.span_label(span, fallback_label);
|
||||
err.note("can't use `Self` as a constructor, you must use the implemented struct");
|
||||
}
|
||||
(Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => {
|
||||
(Res::Def(DefKind::TyAlias, _), _)
|
||||
| (Res::Def(DefKind::AssociatedTy, _), _) if ns == ValueNS => {
|
||||
err.note("can't use a type alias as a constructor");
|
||||
}
|
||||
_ => return false,
|
||||
@ -622,7 +628,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||
let resolutions = crate_module.resolutions.borrow();
|
||||
let resolution = resolutions.get(&(ident, MacroNS))?;
|
||||
let binding = resolution.borrow().binding()?;
|
||||
if let Def::Macro(_, MacroKind::Bang) = binding.def() {
|
||||
if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() {
|
||||
let module_name = crate_module.kind.name().unwrap();
|
||||
let import = match directive.subclass {
|
||||
ImportDirectiveSubclass::SingleImport { source, target, .. } if source != target =>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@ use crate::build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport};
|
||||
use crate::resolve_imports::ImportResolver;
|
||||
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX, DefIndex,
|
||||
CrateNum, DefIndexAddressSpace};
|
||||
use rustc::hir::def::{self, NonMacroAttrKind};
|
||||
use rustc::hir::def::{self, DefKind, NonMacroAttrKind};
|
||||
use rustc::hir::map::{self, DefCollector};
|
||||
use rustc::{ty, lint};
|
||||
use rustc::{bug, span_bug};
|
||||
@ -33,7 +33,7 @@ use std::cell::Cell;
|
||||
use std::{mem, ptr};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
||||
type Def = def::Def<ast::NodeId>;
|
||||
type Res = def::Res<ast::NodeId>;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct InvocationData<'a> {
|
||||
@ -140,7 +140,7 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||
fn visit_ident(&mut self, ident: Ident) {
|
||||
if ident.name == keywords::DollarCrate.name() {
|
||||
let name = match self.resolver.resolve_crate_root(ident).kind {
|
||||
ModuleKind::Def(_, name) if name != keywords::Invalid.name() => name,
|
||||
ModuleKind::Def(.., name) if name != keywords::Invalid.name() => name,
|
||||
_ => keywords::Crate.name(),
|
||||
};
|
||||
ident.span.ctxt().set_dollar_crate_name(name);
|
||||
@ -179,7 +179,7 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||
let kind = ext.kind();
|
||||
self.macro_map.insert(def_id, ext);
|
||||
let binding = self.arenas.alloc_name_binding(NameBinding {
|
||||
kind: NameBindingKind::Def(Def::Macro(def_id, kind), false),
|
||||
kind: NameBindingKind::Res(Res::Def(DefKind::Macro(kind), def_id), false),
|
||||
ambiguity: None,
|
||||
span: DUMMY_SP,
|
||||
vis: ty::Visibility::Public,
|
||||
@ -209,8 +209,8 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||
};
|
||||
|
||||
let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope);
|
||||
let (def, ext) = match self.resolve_macro_to_def(path, kind, &parent_scope, true, force) {
|
||||
Ok((def, ext)) => (def, ext),
|
||||
let (res, ext) = match self.resolve_macro_to_res(path, kind, &parent_scope, true, force) {
|
||||
Ok((res, ext)) => (res, ext),
|
||||
Err(Determinacy::Determined) if kind == MacroKind::Attr => {
|
||||
// Replace unresolved attributes with used inert attributes for better recovery.
|
||||
return Ok(Some(Lrc::new(SyntaxExtension::NonMacroAttr { mark_used: true })));
|
||||
@ -218,7 +218,7 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||
Err(determinacy) => return Err(determinacy),
|
||||
};
|
||||
|
||||
if let Def::Macro(def_id, _) = def {
|
||||
if let Res::Def(DefKind::Macro(_), def_id) = res {
|
||||
if after_derive {
|
||||
self.session.span_err(invoc.span(),
|
||||
"macro attributes must be placed before `#[derive]`");
|
||||
@ -238,7 +238,7 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||
derives_in_scope: Vec<ast::Path>, force: bool)
|
||||
-> Result<Lrc<SyntaxExtension>, Determinacy> {
|
||||
let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope);
|
||||
Ok(self.resolve_macro_to_def(path, kind, &parent_scope, false, force)?.1)
|
||||
Ok(self.resolve_macro_to_res(path, kind, &parent_scope, false, force)?.1)
|
||||
}
|
||||
|
||||
fn check_unused_macros(&self) {
|
||||
@ -274,18 +274,18 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_macro_to_def(
|
||||
fn resolve_macro_to_res(
|
||||
&mut self,
|
||||
path: &ast::Path,
|
||||
kind: MacroKind,
|
||||
parent_scope: &ParentScope<'a>,
|
||||
trace: bool,
|
||||
force: bool,
|
||||
) -> Result<(Def, Lrc<SyntaxExtension>), Determinacy> {
|
||||
let def = self.resolve_macro_to_def_inner(path, kind, parent_scope, trace, force);
|
||||
) -> Result<(Res, Lrc<SyntaxExtension>), Determinacy> {
|
||||
let res = self.resolve_macro_to_res_inner(path, kind, parent_scope, trace, force);
|
||||
|
||||
// Report errors and enforce feature gates for the resolved macro.
|
||||
if def != Err(Determinacy::Undetermined) {
|
||||
if res != Err(Determinacy::Undetermined) {
|
||||
// Do not report duplicated errors on every undetermined resolution.
|
||||
for segment in &path.segments {
|
||||
if let Some(args) = &segment.args {
|
||||
@ -294,10 +294,10 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
let def = def?;
|
||||
let res = res?;
|
||||
|
||||
match def {
|
||||
Def::Macro(def_id, macro_kind) => {
|
||||
match res {
|
||||
Res::Def(DefKind::Macro(macro_kind), def_id) => {
|
||||
self.unused_macros.remove(&def_id);
|
||||
if macro_kind == MacroKind::ProcMacroStub {
|
||||
let msg = "can't use a procedural macro from the same crate that defines it";
|
||||
@ -305,7 +305,7 @@ impl<'a> Resolver<'a> {
|
||||
return Err(Determinacy::Determined);
|
||||
}
|
||||
}
|
||||
Def::NonMacroAttr(attr_kind) => {
|
||||
Res::NonMacroAttr(attr_kind) => {
|
||||
if kind == MacroKind::Attr {
|
||||
let features = self.session.features_untracked();
|
||||
if attr_kind == NonMacroAttrKind::Custom {
|
||||
@ -331,20 +331,20 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
} else {
|
||||
// Not only attributes, but anything in macro namespace can result in
|
||||
// `Def::NonMacroAttr` definition (e.g., `inline!()`), so we must report
|
||||
// `Res::NonMacroAttr` definition (e.g., `inline!()`), so we must report
|
||||
// an error for those cases.
|
||||
let msg = format!("expected a macro, found {}", def.kind_name());
|
||||
let msg = format!("expected a macro, found {}", res.kind_name());
|
||||
self.session.span_err(path.span, &msg);
|
||||
return Err(Determinacy::Determined);
|
||||
}
|
||||
}
|
||||
Def::Err => {
|
||||
Res::Err => {
|
||||
return Err(Determinacy::Determined);
|
||||
}
|
||||
_ => panic!("expected `Def::Macro` or `Def::NonMacroAttr`"),
|
||||
_ => panic!("expected `DefKind::Macro` or `Res::NonMacroAttr`"),
|
||||
}
|
||||
|
||||
Ok((def, self.get_macro(def)))
|
||||
Ok((res, self.get_macro(res)))
|
||||
}
|
||||
|
||||
fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: &str) {
|
||||
@ -401,14 +401,14 @@ impl<'a> Resolver<'a> {
|
||||
err.emit();
|
||||
}
|
||||
|
||||
pub fn resolve_macro_to_def_inner(
|
||||
pub fn resolve_macro_to_res_inner(
|
||||
&mut self,
|
||||
path: &ast::Path,
|
||||
kind: MacroKind,
|
||||
parent_scope: &ParentScope<'a>,
|
||||
trace: bool,
|
||||
force: bool,
|
||||
) -> Result<Def, Determinacy> {
|
||||
) -> Result<Res, Determinacy> {
|
||||
let path_span = path.span;
|
||||
let mut path = Segment::from_path(path);
|
||||
|
||||
@ -421,10 +421,10 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
if path.len() > 1 {
|
||||
let def = match self.resolve_path(&path, Some(MacroNS), parent_scope,
|
||||
let res = match self.resolve_path(&path, Some(MacroNS), parent_scope,
|
||||
false, path_span, CrateLint::No) {
|
||||
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
|
||||
Ok(path_res.base_def())
|
||||
Ok(path_res.base_res())
|
||||
}
|
||||
PathResult::Indeterminate if !force => return Err(Determinacy::Undetermined),
|
||||
PathResult::NonModule(..)
|
||||
@ -435,11 +435,11 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
if trace {
|
||||
parent_scope.module.multi_segment_macro_resolutions.borrow_mut()
|
||||
.push((path, path_span, kind, parent_scope.clone(), def.ok()));
|
||||
.push((path, path_span, kind, parent_scope.clone(), res.ok()));
|
||||
}
|
||||
|
||||
self.prohibit_imported_non_macro_attrs(None, def.ok(), path_span);
|
||||
def
|
||||
self.prohibit_imported_non_macro_attrs(None, res.ok(), path_span);
|
||||
res
|
||||
} else {
|
||||
let binding = self.early_resolve_ident_in_lexical_scope(
|
||||
path[0].ident, ScopeSet::Macro(kind), parent_scope, false, force, path_span
|
||||
@ -453,9 +453,9 @@ impl<'a> Resolver<'a> {
|
||||
.push((path[0].ident, kind, parent_scope.clone(), binding.ok()));
|
||||
}
|
||||
|
||||
let def = binding.map(|binding| binding.def());
|
||||
self.prohibit_imported_non_macro_attrs(binding.ok(), def.ok(), path_span);
|
||||
def
|
||||
let res = binding.map(|binding| binding.res());
|
||||
self.prohibit_imported_non_macro_attrs(binding.ok(), res.ok(), path_span);
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
@ -585,13 +585,13 @@ impl<'a> Resolver<'a> {
|
||||
let mut result = Err(Determinacy::Determined);
|
||||
for derive in &parent_scope.derives {
|
||||
let parent_scope = ParentScope { derives: Vec::new(), ..*parent_scope };
|
||||
match self.resolve_macro_to_def(derive, MacroKind::Derive,
|
||||
match self.resolve_macro_to_res(derive, MacroKind::Derive,
|
||||
&parent_scope, true, force) {
|
||||
Ok((_, ext)) => {
|
||||
if let SyntaxExtension::ProcMacroDerive(_, helpers, _) = &*ext {
|
||||
if helpers.contains(&ident.name) {
|
||||
let binding =
|
||||
(Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
|
||||
(Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
|
||||
ty::Visibility::Public, derive.span, Mark::root())
|
||||
.to_name_binding(self.arenas);
|
||||
result = Ok((binding, Flags::empty()));
|
||||
@ -684,7 +684,7 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
WhereToResolve::BuiltinAttrs => {
|
||||
if is_builtin_attr_name(ident.name) {
|
||||
let binding = (Def::NonMacroAttr(NonMacroAttrKind::Builtin),
|
||||
let binding = (Res::NonMacroAttr(NonMacroAttrKind::Builtin),
|
||||
ty::Visibility::Public, DUMMY_SP, Mark::root())
|
||||
.to_name_binding(self.arenas);
|
||||
Ok((binding, Flags::PRELUDE))
|
||||
@ -696,7 +696,7 @@ impl<'a> Resolver<'a> {
|
||||
if (use_prelude || rust_2015) &&
|
||||
self.session.plugin_attributes.borrow().iter()
|
||||
.any(|(name, _)| ident.name == &**name) {
|
||||
let binding = (Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper),
|
||||
let binding = (Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper),
|
||||
ty::Visibility::Public, DUMMY_SP, Mark::root())
|
||||
.to_name_binding(self.arenas);
|
||||
Ok((binding, Flags::PRELUDE))
|
||||
@ -718,7 +718,7 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
WhereToResolve::ToolPrelude => {
|
||||
if use_prelude && is_known_tool(ident.name) {
|
||||
let binding = (Def::ToolMod, ty::Visibility::Public,
|
||||
let binding = (Res::ToolMod, ty::Visibility::Public,
|
||||
DUMMY_SP, Mark::root()).to_name_binding(self.arenas);
|
||||
Ok((binding, Flags::PRELUDE))
|
||||
} else {
|
||||
@ -745,7 +745,7 @@ impl<'a> Resolver<'a> {
|
||||
WhereToResolve::BuiltinTypes => {
|
||||
match self.primitive_type_table.primitive_types.get(&ident.name).cloned() {
|
||||
Some(prim_ty) => {
|
||||
let binding = (Def::PrimTy(prim_ty), ty::Visibility::Public,
|
||||
let binding = (Res::PrimTy(prim_ty), ty::Visibility::Public,
|
||||
DUMMY_SP, Mark::root()).to_name_binding(self.arenas);
|
||||
Ok((binding, Flags::PRELUDE))
|
||||
}
|
||||
@ -762,22 +762,22 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
if let Some((innermost_binding, innermost_flags)) = innermost_result {
|
||||
// Found another solution, if the first one was "weak", report an error.
|
||||
let (def, innermost_def) = (binding.def(), innermost_binding.def());
|
||||
if def != innermost_def {
|
||||
let builtin = Def::NonMacroAttr(NonMacroAttrKind::Builtin);
|
||||
let derive_helper = Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
|
||||
let (res, innermost_res) = (binding.res(), innermost_binding.res());
|
||||
if res != innermost_res {
|
||||
let builtin = Res::NonMacroAttr(NonMacroAttrKind::Builtin);
|
||||
let derive_helper = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
|
||||
let legacy_helper =
|
||||
Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper);
|
||||
Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper);
|
||||
|
||||
let ambiguity_error_kind = if is_import {
|
||||
Some(AmbiguityKind::Import)
|
||||
} else if innermost_def == builtin || def == builtin {
|
||||
} else if innermost_res == builtin || res == builtin {
|
||||
Some(AmbiguityKind::BuiltinAttr)
|
||||
} else if innermost_def == derive_helper || def == derive_helper {
|
||||
} else if innermost_res == derive_helper || res == derive_helper {
|
||||
Some(AmbiguityKind::DeriveHelper)
|
||||
} else if innermost_def == legacy_helper &&
|
||||
} else if innermost_res == legacy_helper &&
|
||||
flags.contains(Flags::PRELUDE) ||
|
||||
def == legacy_helper &&
|
||||
res == legacy_helper &&
|
||||
innermost_flags.contains(Flags::PRELUDE) {
|
||||
Some(AmbiguityKind::LegacyHelperVsPrelude)
|
||||
} else if innermost_flags.contains(Flags::MACRO_RULES) &&
|
||||
@ -889,7 +889,7 @@ impl<'a> Resolver<'a> {
|
||||
// attribute. (Lexical resolution implies the first segment and attr kind should imply
|
||||
// the last segment, so we are certainly working with a single-segment attribute here.)
|
||||
assert!(ns == MacroNS);
|
||||
let binding = (Def::NonMacroAttr(NonMacroAttrKind::Custom),
|
||||
let binding = (Res::NonMacroAttr(NonMacroAttrKind::Custom),
|
||||
ty::Visibility::Public, ident.span, Mark::root())
|
||||
.to_name_binding(self.arenas);
|
||||
Ok(binding)
|
||||
@ -902,18 +902,18 @@ impl<'a> Resolver<'a> {
|
||||
let module = self.current_module;
|
||||
|
||||
let check_consistency = |this: &mut Self, path: &[Segment], span, kind: MacroKind,
|
||||
initial_def: Option<Def>, def: Def| {
|
||||
if let Some(initial_def) = initial_def {
|
||||
if def != initial_def && def != Def::Err && this.ambiguity_errors.is_empty() {
|
||||
initial_res: Option<Res>, res: Res| {
|
||||
if let Some(initial_res) = initial_res {
|
||||
if res != initial_res && res != Res::Err && this.ambiguity_errors.is_empty() {
|
||||
// Make sure compilation does not succeed if preferred macro resolution
|
||||
// has changed after the macro had been expanded. In theory all such
|
||||
// situations should be reported as ambiguity errors, so this is a bug.
|
||||
if initial_def == Def::NonMacroAttr(NonMacroAttrKind::Custom) {
|
||||
if initial_res == Res::NonMacroAttr(NonMacroAttrKind::Custom) {
|
||||
// Yeah, legacy custom attributes are implemented using forced resolution
|
||||
// (which is a best effort error recovery tool, basically), so we can't
|
||||
// promise their resolution won't change later.
|
||||
let msg = format!("inconsistent resolution for a macro: first {}, then {}",
|
||||
initial_def.kind_name(), def.kind_name());
|
||||
initial_res.kind_name(), res.kind_name());
|
||||
this.session.span_err(span, &msg);
|
||||
} else {
|
||||
span_bug!(span, "inconsistent resolution for a macro");
|
||||
@ -938,14 +938,14 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
let macro_resolutions =
|
||||
mem::replace(&mut *module.multi_segment_macro_resolutions.borrow_mut(), Vec::new());
|
||||
for (mut path, path_span, kind, parent_scope, initial_def) in macro_resolutions {
|
||||
for (mut path, path_span, kind, parent_scope, initial_res) in macro_resolutions {
|
||||
// FIXME: Path resolution will ICE if segment IDs present.
|
||||
for seg in &mut path { seg.id = None; }
|
||||
match self.resolve_path(&path, Some(MacroNS), &parent_scope,
|
||||
true, path_span, CrateLint::No) {
|
||||
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
|
||||
let def = path_res.base_def();
|
||||
check_consistency(self, &path, path_span, kind, initial_def, def);
|
||||
let res = path_res.base_res();
|
||||
check_consistency(self, &path, path_span, kind, initial_res, res);
|
||||
}
|
||||
path_res @ PathResult::NonModule(..) | path_res @ PathResult::Failed { .. } => {
|
||||
let (span, label) = if let PathResult::Failed { span, label, .. } = path_res {
|
||||
@ -969,13 +969,13 @@ impl<'a> Resolver<'a> {
|
||||
match self.early_resolve_ident_in_lexical_scope(ident, ScopeSet::Macro(kind),
|
||||
&parent_scope, true, true, ident.span) {
|
||||
Ok(binding) => {
|
||||
let initial_def = initial_binding.map(|initial_binding| {
|
||||
let initial_res = initial_binding.map(|initial_binding| {
|
||||
self.record_use(ident, MacroNS, initial_binding, false);
|
||||
initial_binding.def()
|
||||
initial_binding.res()
|
||||
});
|
||||
let def = binding.def();
|
||||
let res = binding.res();
|
||||
let seg = Segment::from_ident(ident);
|
||||
check_consistency(self, &[seg], ident.span, kind, initial_def, def);
|
||||
check_consistency(self, &[seg], ident.span, kind, initial_res, res);
|
||||
}
|
||||
Err(..) => {
|
||||
assert!(initial_binding.is_none());
|
||||
@ -998,8 +998,8 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
fn prohibit_imported_non_macro_attrs(&self, binding: Option<&'a NameBinding<'a>>,
|
||||
def: Option<Def>, span: Span) {
|
||||
if let Some(Def::NonMacroAttr(kind)) = def {
|
||||
res: Option<Res>, span: Span) {
|
||||
if let Some(Res::NonMacroAttr(kind)) = res {
|
||||
if kind != NonMacroAttrKind::Tool && binding.map_or(true, |b| b.is_import()) {
|
||||
let msg = format!("cannot use a {} through an import", kind.descr());
|
||||
let mut err = self.session.struct_span_err(span, &msg);
|
||||
@ -1027,8 +1027,8 @@ impl<'a> Resolver<'a> {
|
||||
find_best_match_for_name(names, name, None)
|
||||
// Then check modules.
|
||||
}).or_else(|| {
|
||||
let is_macro = |def| {
|
||||
if let Def::Macro(_, def_kind) = def {
|
||||
let is_macro = |res| {
|
||||
if let Res::Def(DefKind::Macro(def_kind), _) = res {
|
||||
def_kind == kind
|
||||
} else {
|
||||
false
|
||||
@ -1107,24 +1107,24 @@ impl<'a> Resolver<'a> {
|
||||
if def.legacy {
|
||||
let ident = ident.modern();
|
||||
self.macro_names.insert(ident);
|
||||
let def = Def::Macro(def_id, MacroKind::Bang);
|
||||
let res = Res::Def(DefKind::Macro(MacroKind::Bang), def_id);
|
||||
let is_macro_export = attr::contains_name(&item.attrs, "macro_export");
|
||||
let vis = if is_macro_export {
|
||||
ty::Visibility::Public
|
||||
} else {
|
||||
ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))
|
||||
};
|
||||
let binding = (def, vis, item.span, expansion).to_name_binding(self.arenas);
|
||||
let binding = (res, vis, item.span, expansion).to_name_binding(self.arenas);
|
||||
self.set_binding_parent_module(binding, self.current_module);
|
||||
let legacy_binding = self.arenas.alloc_legacy_binding(LegacyBinding {
|
||||
parent_legacy_scope: *current_legacy_scope, binding, ident
|
||||
});
|
||||
*current_legacy_scope = LegacyScope::Binding(legacy_binding);
|
||||
self.all_macros.insert(ident.name, def);
|
||||
self.all_macros.insert(ident.name, res);
|
||||
if is_macro_export {
|
||||
let module = self.graph_root;
|
||||
self.define(module, ident, MacroNS,
|
||||
(def, vis, item.span, expansion, IsMacroExport));
|
||||
(res, vis, item.span, expansion, IsMacroExport));
|
||||
} else {
|
||||
if !attr::contains_name(&item.attrs, "rustc_doc_only_macro") {
|
||||
self.check_reserved_macro_name(ident, MacroNS);
|
||||
@ -1133,12 +1133,12 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
} else {
|
||||
let module = self.current_module;
|
||||
let def = Def::Macro(def_id, MacroKind::Bang);
|
||||
let res = Res::Def(DefKind::Macro(MacroKind::Bang), def_id);
|
||||
let vis = self.resolve_visibility(&item.vis);
|
||||
if vis != ty::Visibility::Public {
|
||||
self.unused_macros.insert(def_id);
|
||||
}
|
||||
self.define(module, ident, MacroNS, (def, vis, item.span, expansion));
|
||||
self.define(module, ident, MacroNS, (res, vis, item.span, expansion));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use rustc::lint::builtin::{
|
||||
UNUSED_IMPORTS,
|
||||
};
|
||||
use rustc::hir::def_id::{CrateNum, DefId};
|
||||
use rustc::hir::def::{self, PathResolution, Export};
|
||||
use rustc::hir::def::{self, DefKind, PathResolution, Export};
|
||||
use rustc::session::DiagnosticMessageId;
|
||||
use rustc::util::nodemap::FxHashSet;
|
||||
use rustc::{bug, span_bug};
|
||||
@ -39,7 +39,7 @@ use log::*;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::{mem, ptr};
|
||||
|
||||
type Def = def::Def<NodeId>;
|
||||
type Res = def::Res<NodeId>;
|
||||
|
||||
/// Contains data for specific types of import directives.
|
||||
#[derive(Clone, Debug)]
|
||||
@ -247,7 +247,7 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
if let Some(binding) = resolution.binding {
|
||||
if !restricted_shadowing && binding.expansion != Mark::root() {
|
||||
if let NameBindingKind::Def(_, true) = binding.kind {
|
||||
if let NameBindingKind::Res(_, true) = binding.kind {
|
||||
self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
|
||||
}
|
||||
}
|
||||
@ -287,7 +287,7 @@ impl<'a> Resolver<'a> {
|
||||
// Forbid expanded shadowing to avoid time travel.
|
||||
if restricted_shadowing &&
|
||||
binding.expansion != Mark::root() &&
|
||||
binding.def() != shadowed_glob.def() {
|
||||
binding.res() != shadowed_glob.res() {
|
||||
self.ambiguity_errors.push(AmbiguityError {
|
||||
kind: AmbiguityKind::GlobVsExpanded,
|
||||
ident,
|
||||
@ -513,13 +513,13 @@ impl<'a> Resolver<'a> {
|
||||
self.set_binding_parent_module(binding, module);
|
||||
self.update_resolution(module, ident, ns, |this, resolution| {
|
||||
if let Some(old_binding) = resolution.binding {
|
||||
if binding.def() == Def::Err {
|
||||
// Do not override real bindings with `Def::Err`s from error recovery.
|
||||
if binding.res() == Res::Err {
|
||||
// Do not override real bindings with `Res::Err`s from error recovery.
|
||||
return Ok(());
|
||||
}
|
||||
match (old_binding.is_glob_import(), binding.is_glob_import()) {
|
||||
(true, true) => {
|
||||
if binding.def() != old_binding.def() {
|
||||
if binding.res() != old_binding.res() {
|
||||
resolution.binding = Some(this.ambiguity(AmbiguityKind::GlobVsGlob,
|
||||
old_binding, binding));
|
||||
} else if !old_binding.vis.is_at_least(binding.vis, &*this) {
|
||||
@ -533,7 +533,7 @@ impl<'a> Resolver<'a> {
|
||||
} else {
|
||||
(binding, old_binding)
|
||||
};
|
||||
if glob_binding.def() != nonglob_binding.def() &&
|
||||
if glob_binding.res() != nonglob_binding.res() &&
|
||||
ns == MacroNS && nonglob_binding.expansion != Mark::root() {
|
||||
resolution.binding = Some(this.ambiguity(AmbiguityKind::GlobVsExpanded,
|
||||
nonglob_binding, glob_binding));
|
||||
@ -543,7 +543,7 @@ impl<'a> Resolver<'a> {
|
||||
resolution.shadowed_glob = Some(glob_binding);
|
||||
}
|
||||
(false, false) => {
|
||||
if let (&NameBindingKind::Def(_, true), &NameBindingKind::Def(_, true)) =
|
||||
if let (&NameBindingKind::Res(_, true), &NameBindingKind::Res(_, true)) =
|
||||
(&old_binding.kind, &binding.kind) {
|
||||
|
||||
this.session.buffer_lint_with_diagnostic(
|
||||
@ -619,7 +619,7 @@ impl<'a> Resolver<'a> {
|
||||
t
|
||||
}
|
||||
|
||||
// Define a "dummy" resolution containing a Def::Err as a placeholder for a
|
||||
// Define a "dummy" resolution containing a Res::Err as a placeholder for a
|
||||
// failed resolution
|
||||
fn import_dummy_binding(&mut self, directive: &'a ImportDirective<'a>) {
|
||||
if let SingleImport { target, .. } = directive.subclass {
|
||||
@ -971,7 +971,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||
}
|
||||
return None;
|
||||
}
|
||||
PathResult::NonModule(path_res) if path_res.base_def() == Def::Err => {
|
||||
PathResult::NonModule(path_res) if path_res.base_res() == Res::Err => {
|
||||
if no_ambiguity {
|
||||
assert!(directive.imported_module.get().is_none());
|
||||
}
|
||||
@ -1038,7 +1038,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||
match binding {
|
||||
Ok(binding) => {
|
||||
// Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
|
||||
let initial_def = source_bindings[ns].get().map(|initial_binding| {
|
||||
let initial_res = source_bindings[ns].get().map(|initial_binding| {
|
||||
all_ns_err = false;
|
||||
if let Some(target_binding) = target_bindings[ns].get() {
|
||||
if target.name == "_" &&
|
||||
@ -1047,15 +1047,15 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||
directive.module_path.is_empty());
|
||||
}
|
||||
}
|
||||
initial_binding.def()
|
||||
initial_binding.res()
|
||||
});
|
||||
let def = binding.def();
|
||||
if let Ok(initial_def) = initial_def {
|
||||
if def != initial_def && this.ambiguity_errors.is_empty() {
|
||||
let res = binding.res();
|
||||
if let Ok(initial_res) = initial_res {
|
||||
if res != initial_res && this.ambiguity_errors.is_empty() {
|
||||
span_bug!(directive.span, "inconsistent resolution for an import");
|
||||
}
|
||||
} else {
|
||||
if def != Def::Err &&
|
||||
if res != Res::Err &&
|
||||
this.ambiguity_errors.is_empty() && this.privacy_errors.is_empty() {
|
||||
let msg = "cannot determine resolution for the import";
|
||||
let msg_note =
|
||||
@ -1101,7 +1101,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||
match binding.kind {
|
||||
// Never suggest the name that has binding error
|
||||
// i.e., the name that cannot be previously resolved
|
||||
NameBindingKind::Def(Def::Err, _) => return None,
|
||||
NameBindingKind::Res(Res::Err, _) => return None,
|
||||
_ => Some(&i.name),
|
||||
}
|
||||
},
|
||||
@ -1223,18 +1223,18 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||
// this may resolve to either a value or a type, but for documentation
|
||||
// purposes it's good enough to just favor one over the other.
|
||||
self.per_ns(|this, ns| if let Some(binding) = source_bindings[ns].get().ok() {
|
||||
let mut def = binding.def();
|
||||
if let Def::Macro(def_id, _) = def {
|
||||
let mut res = binding.res();
|
||||
if let Res::Def(DefKind::Macro(_), def_id) = res {
|
||||
// `DefId`s from the "built-in macro crate" should not leak from resolve because
|
||||
// later stages are not ready to deal with them and produce lots of ICEs. Replace
|
||||
// them with `Def::Err` until some saner scheme is implemented for built-in macros.
|
||||
// them with `Res::Err` until some saner scheme is implemented for built-in macros.
|
||||
if def_id.krate == CrateNum::BuiltinMacros {
|
||||
this.session.span_err(directive.span, "cannot import a built-in macro");
|
||||
def = Def::Err;
|
||||
res = Res::Err;
|
||||
}
|
||||
}
|
||||
let import = this.import_map.entry(directive.id).or_default();
|
||||
import[ns] = Some(PathResolution::new(def));
|
||||
import[ns] = Some(PathResolution::new(res));
|
||||
});
|
||||
|
||||
self.check_for_redundant_imports(
|
||||
@ -1264,7 +1264,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||
|
||||
// Skip if we are inside a named module (in contrast to an anonymous
|
||||
// module defined by a block).
|
||||
if let ModuleKind::Def(_, _) = directive.parent_scope.module.kind {
|
||||
if let ModuleKind::Def(..) = directive.parent_scope.module.kind {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1281,7 +1281,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||
};
|
||||
|
||||
self.per_ns(|this, ns| if let Some(binding) = source_bindings[ns].get().ok() {
|
||||
if binding.def() == Def::Err {
|
||||
if binding.res() == Res::Err {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1300,7 +1300,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||
) {
|
||||
Ok(other_binding) => {
|
||||
is_redundant[ns] = Some(
|
||||
binding.def() == other_binding.def()
|
||||
binding.res() == other_binding.res()
|
||||
&& !other_binding.is_ambiguity()
|
||||
);
|
||||
redundant_span[ns] =
|
||||
@ -1371,7 +1371,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||
}
|
||||
|
||||
// Record the destination of this import
|
||||
self.record_def(directive.id, PathResolution::new(module.def().unwrap()));
|
||||
self.record_res(directive.id, PathResolution::new(module.res().unwrap()));
|
||||
}
|
||||
|
||||
// Miscellaneous post-processing, including recording re-exports,
|
||||
@ -1395,16 +1395,16 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||
let is_good_import = binding.is_import() && !binding.is_ambiguity() &&
|
||||
!(ident.name.is_gensymed() && ident.name != "_");
|
||||
if is_good_import || binding.is_macro_def() {
|
||||
let def = binding.def();
|
||||
if def != Def::Err {
|
||||
if let Some(def_id) = def.opt_def_id() {
|
||||
let res = binding.res();
|
||||
if res != Res::Err {
|
||||
if let Some(def_id) = res.opt_def_id() {
|
||||
if !def_id.is_local() && def_id.krate != CrateNum::BuiltinMacros {
|
||||
self.cstore.export_macros_untracked(def_id.krate);
|
||||
}
|
||||
}
|
||||
reexports.push(Export {
|
||||
ident: ident.modern(),
|
||||
def: def,
|
||||
res: res,
|
||||
span: binding.span,
|
||||
vis: binding.vis,
|
||||
});
|
||||
|
@ -13,7 +13,7 @@
|
||||
//! DumpVisitor walks the AST and processes it, and JsonDumper is used for
|
||||
//! recording the output.
|
||||
|
||||
use rustc::hir::def::Def as HirDef;
|
||||
use rustc::hir::def::{Res, DefKind as HirDefKind};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::session::config::Input;
|
||||
use rustc::span_bug;
|
||||
@ -233,8 +233,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||
}
|
||||
|
||||
fn lookup_def_id(&self, ref_id: NodeId) -> Option<DefId> {
|
||||
match self.save_ctxt.get_path_def(ref_id) {
|
||||
HirDef::PrimTy(..) | HirDef::SelfTy(..) | HirDef::Err => None,
|
||||
match self.save_ctxt.get_path_res(ref_id) {
|
||||
Res::PrimTy(..) | Res::SelfTy(..) | Res::Err => None,
|
||||
def => Some(def.def_id()),
|
||||
}
|
||||
}
|
||||
@ -884,7 +884,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||
return;
|
||||
}
|
||||
};
|
||||
let variant = adt.variant_of_def(self.save_ctxt.get_path_def(p.id));
|
||||
let variant = adt.variant_of_res(self.save_ctxt.get_path_res(p.id));
|
||||
|
||||
for &Spanned { node: ref field, .. } in fields {
|
||||
if let Some(index) = self.tcx.find_field_index(field.ident, variant) {
|
||||
@ -914,8 +914,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||
|
||||
// process collected paths
|
||||
for (id, ident, immut) in collector.collected_idents {
|
||||
match self.save_ctxt.get_path_def(id) {
|
||||
HirDef::Local(hir_id) => {
|
||||
match self.save_ctxt.get_path_res(id) {
|
||||
Res::Local(hir_id) => {
|
||||
let mut value = if immut == ast::Mutability::Immutable {
|
||||
self.span.snippet(ident.span)
|
||||
} else {
|
||||
@ -957,14 +957,14 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||
);
|
||||
}
|
||||
}
|
||||
HirDef::Ctor(_, _, _) |
|
||||
HirDef::Const(..) |
|
||||
HirDef::AssociatedConst(..) |
|
||||
HirDef::Struct(..) |
|
||||
HirDef::Variant(..) |
|
||||
HirDef::TyAlias(..) |
|
||||
HirDef::AssociatedTy(..) |
|
||||
HirDef::SelfTy(..) => {
|
||||
Res::Def(HirDefKind::Ctor(..), _) |
|
||||
Res::Def(HirDefKind::Const, _) |
|
||||
Res::Def(HirDefKind::AssociatedConst, _) |
|
||||
Res::Def(HirDefKind::Struct, _) |
|
||||
Res::Def(HirDefKind::Variant, _) |
|
||||
Res::Def(HirDefKind::TyAlias, _) |
|
||||
Res::Def(HirDefKind::AssociatedTy, _) |
|
||||
Res::SelfTy(..) => {
|
||||
self.dump_path_ref(id, &ast::Path::from_ident(ident));
|
||||
}
|
||||
def => error!(
|
||||
@ -1538,8 +1538,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
|
||||
}
|
||||
};
|
||||
let node_id = self.save_ctxt.tcx.hir().hir_to_node_id(hir_expr.hir_id);
|
||||
let def = self.save_ctxt.get_path_def(node_id);
|
||||
self.process_struct_lit(ex, path, fields, adt.variant_of_def(def), base)
|
||||
let res = self.save_ctxt.get_path_res(node_id);
|
||||
self.process_struct_lit(ex, path, fields, adt.variant_of_res(res), base)
|
||||
}
|
||||
ast::ExprKind::MethodCall(ref seg, ref args) => self.process_method_call(ex, seg, args),
|
||||
ast::ExprKind::Field(ref sub_ex, _) => {
|
||||
|
@ -15,7 +15,7 @@ mod span_utils;
|
||||
mod sig;
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::hir::def::{CtorOf, Def as HirDef};
|
||||
use rustc::hir::def::{CtorOf, Res, DefKind as HirDefKind};
|
||||
use rustc::hir::Node;
|
||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc::middle::privacy::AccessLevels;
|
||||
@ -606,21 +606,21 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_path_def(&self, id: NodeId) -> HirDef {
|
||||
pub fn get_path_res(&self, id: NodeId) -> Res {
|
||||
match self.tcx.hir().get(id) {
|
||||
Node::TraitRef(tr) => tr.path.def,
|
||||
Node::TraitRef(tr) => tr.path.res,
|
||||
|
||||
Node::Item(&hir::Item {
|
||||
node: hir::ItemKind::Use(ref path, _),
|
||||
..
|
||||
}) |
|
||||
Node::Visibility(&Spanned {
|
||||
node: hir::VisibilityKind::Restricted { ref path, .. }, .. }) => path.def,
|
||||
node: hir::VisibilityKind::Restricted { ref path, .. }, .. }) => path.res,
|
||||
|
||||
Node::PathSegment(seg) => {
|
||||
match seg.def {
|
||||
Some(def) if def != HirDef::Err => def,
|
||||
_ => self.get_path_def(self.tcx.hir().get_parent_node(id)),
|
||||
match seg.res {
|
||||
Some(res) if res != Res::Err => res,
|
||||
_ => self.get_path_res(self.tcx.hir().get_parent_node(id)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -629,7 +629,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||
..
|
||||
}) => {
|
||||
let hir_id = self.tcx.hir().node_to_hir_id(id);
|
||||
self.tables.qpath_def(qpath, hir_id)
|
||||
self.tables.qpath_res(qpath, hir_id)
|
||||
}
|
||||
|
||||
Node::Expr(&hir::Expr {
|
||||
@ -653,15 +653,15 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||
..
|
||||
}) => {
|
||||
let hir_id = self.tcx.hir().node_to_hir_id(id);
|
||||
self.tables.qpath_def(qpath, hir_id)
|
||||
self.tables.qpath_res(qpath, hir_id)
|
||||
}
|
||||
|
||||
Node::Binding(&hir::Pat {
|
||||
node: hir::PatKind::Binding(_, canonical_id, ..),
|
||||
..
|
||||
}) => HirDef::Local(canonical_id),
|
||||
}) => Res::Local(canonical_id),
|
||||
|
||||
_ => HirDef::Err,
|
||||
_ => Res::Err,
|
||||
}
|
||||
}
|
||||
|
||||
@ -697,52 +697,52 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||
return None;
|
||||
}
|
||||
|
||||
let def = self.get_path_def(id);
|
||||
let res = self.get_path_res(id);
|
||||
let span = path_seg.ident.span;
|
||||
filter!(self.span_utils, span);
|
||||
let span = self.span_from_span(span);
|
||||
|
||||
match def {
|
||||
HirDef::Upvar(id, ..) | HirDef::Local(id) => {
|
||||
match res {
|
||||
Res::Upvar(id, ..) | Res::Local(id) => {
|
||||
Some(Ref {
|
||||
kind: RefKind::Variable,
|
||||
span,
|
||||
ref_id: id_from_node_id(self.tcx.hir().hir_to_node_id(id), self),
|
||||
})
|
||||
}
|
||||
HirDef::Trait(def_id) if fn_type(path_seg) => {
|
||||
Res::Def(HirDefKind::Trait, def_id) if fn_type(path_seg) => {
|
||||
Some(Ref {
|
||||
kind: RefKind::Type,
|
||||
span,
|
||||
ref_id: id_from_def_id(def_id),
|
||||
})
|
||||
}
|
||||
HirDef::Struct(def_id) |
|
||||
HirDef::Variant(def_id, ..) |
|
||||
HirDef::Union(def_id) |
|
||||
HirDef::Enum(def_id) |
|
||||
HirDef::TyAlias(def_id) |
|
||||
HirDef::ForeignTy(def_id) |
|
||||
HirDef::TraitAlias(def_id) |
|
||||
HirDef::AssociatedExistential(def_id) |
|
||||
HirDef::AssociatedTy(def_id) |
|
||||
HirDef::Trait(def_id) |
|
||||
HirDef::Existential(def_id) |
|
||||
HirDef::TyParam(def_id) => {
|
||||
Res::Def(HirDefKind::Struct, def_id) |
|
||||
Res::Def(HirDefKind::Variant, def_id) |
|
||||
Res::Def(HirDefKind::Union, def_id) |
|
||||
Res::Def(HirDefKind::Enum, def_id) |
|
||||
Res::Def(HirDefKind::TyAlias, def_id) |
|
||||
Res::Def(HirDefKind::ForeignTy, def_id) |
|
||||
Res::Def(HirDefKind::TraitAlias, def_id) |
|
||||
Res::Def(HirDefKind::AssociatedExistential, def_id) |
|
||||
Res::Def(HirDefKind::AssociatedTy, def_id) |
|
||||
Res::Def(HirDefKind::Trait, def_id) |
|
||||
Res::Def(HirDefKind::Existential, def_id) |
|
||||
Res::Def(HirDefKind::TyParam, def_id) => {
|
||||
Some(Ref {
|
||||
kind: RefKind::Type,
|
||||
span,
|
||||
ref_id: id_from_def_id(def_id),
|
||||
})
|
||||
}
|
||||
HirDef::ConstParam(def_id) => {
|
||||
Res::Def(HirDefKind::ConstParam, def_id) => {
|
||||
Some(Ref {
|
||||
kind: RefKind::Variable,
|
||||
span,
|
||||
ref_id: id_from_def_id(def_id),
|
||||
})
|
||||
}
|
||||
HirDef::Ctor(def_id, CtorOf::Struct, ..) => {
|
||||
Res::Def(HirDefKind::Ctor(CtorOf::Struct, ..), def_id) => {
|
||||
// This is a reference to a tuple struct where the def_id points
|
||||
// to an invisible constructor function. That is not a very useful
|
||||
// def, so adjust to point to the tuple struct itself.
|
||||
@ -753,17 +753,17 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||
ref_id: id_from_def_id(parent_def_id),
|
||||
})
|
||||
}
|
||||
HirDef::Static(..) |
|
||||
HirDef::Const(..) |
|
||||
HirDef::AssociatedConst(..) |
|
||||
HirDef::Ctor(..) => {
|
||||
Res::Def(HirDefKind::Static, _) |
|
||||
Res::Def(HirDefKind::Const, _) |
|
||||
Res::Def(HirDefKind::AssociatedConst, _) |
|
||||
Res::Def(HirDefKind::Ctor(..), _) => {
|
||||
Some(Ref {
|
||||
kind: RefKind::Variable,
|
||||
span,
|
||||
ref_id: id_from_def_id(def.def_id()),
|
||||
ref_id: id_from_def_id(res.def_id()),
|
||||
})
|
||||
}
|
||||
HirDef::Method(decl_id) => {
|
||||
Res::Def(HirDefKind::Method, decl_id) => {
|
||||
let def_id = if decl_id.is_local() {
|
||||
let ti = self.tcx.associated_item(decl_id);
|
||||
self.tcx
|
||||
@ -780,28 +780,28 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||
ref_id: id_from_def_id(def_id.unwrap_or(decl_id)),
|
||||
})
|
||||
}
|
||||
HirDef::Fn(def_id) => {
|
||||
Res::Def(HirDefKind::Fn, def_id) => {
|
||||
Some(Ref {
|
||||
kind: RefKind::Function,
|
||||
span,
|
||||
ref_id: id_from_def_id(def_id),
|
||||
})
|
||||
}
|
||||
HirDef::Mod(def_id) => {
|
||||
Res::Def(HirDefKind::Mod, def_id) => {
|
||||
Some(Ref {
|
||||
kind: RefKind::Mod,
|
||||
span,
|
||||
ref_id: id_from_def_id(def_id),
|
||||
})
|
||||
}
|
||||
HirDef::PrimTy(..) |
|
||||
HirDef::SelfTy(..) |
|
||||
HirDef::Label(..) |
|
||||
HirDef::Macro(..) |
|
||||
HirDef::ToolMod |
|
||||
HirDef::NonMacroAttr(..) |
|
||||
HirDef::SelfCtor(..) |
|
||||
HirDef::Err => None,
|
||||
Res::PrimTy(..) |
|
||||
Res::SelfTy(..) |
|
||||
Res::Label(..) |
|
||||
Res::Def(HirDefKind::Macro(..), _) |
|
||||
Res::ToolMod |
|
||||
Res::NonMacroAttr(..) |
|
||||
Res::SelfCtor(..) |
|
||||
Res::Err => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -870,8 +870,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||
}
|
||||
|
||||
fn lookup_ref_id(&self, ref_id: NodeId) -> Option<DefId> {
|
||||
match self.get_path_def(ref_id) {
|
||||
HirDef::PrimTy(_) | HirDef::SelfTy(..) | HirDef::Err => None,
|
||||
match self.get_path_res(ref_id) {
|
||||
Res::PrimTy(_) | Res::SelfTy(..) | Res::Err => None,
|
||||
def => Some(def.def_id()),
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ use crate::{id_from_def_id, id_from_node_id, SaveContext};
|
||||
|
||||
use rls_data::{SigElement, Signature};
|
||||
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def::{Res, DefKind};
|
||||
use syntax::ast::{self, NodeId};
|
||||
use syntax::print::pprust;
|
||||
|
||||
@ -273,8 +273,8 @@ impl Sig for ast::Ty {
|
||||
};
|
||||
|
||||
let name = pprust::path_segment_to_string(path.segments.last().ok_or("Bad path")?);
|
||||
let def = scx.get_path_def(id.ok_or("Missing id for Path")?);
|
||||
let id = id_from_def_id(def.def_id());
|
||||
let res = scx.get_path_res(id.ok_or("Missing id for Path")?);
|
||||
let id = id_from_def_id(res.def_id());
|
||||
if path.segments.len() - qself.position == 1 {
|
||||
let start = offset + prefix.len();
|
||||
let end = start + name.len();
|
||||
@ -576,17 +576,19 @@ impl Sig for ast::Item {
|
||||
|
||||
impl Sig for ast::Path {
|
||||
fn make(&self, offset: usize, id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result {
|
||||
let def = scx.get_path_def(id.ok_or("Missing id for Path")?);
|
||||
let res = scx.get_path_res(id.ok_or("Missing id for Path")?);
|
||||
|
||||
let (name, start, end) = match def {
|
||||
Def::Label(..) | Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => {
|
||||
let (name, start, end) = match res {
|
||||
Res::Label(..) | Res::PrimTy(..) | Res::SelfTy(..) | Res::Err => {
|
||||
return Ok(Signature {
|
||||
text: pprust::path_to_string(self),
|
||||
defs: vec![],
|
||||
refs: vec![],
|
||||
})
|
||||
}
|
||||
Def::AssociatedConst(..) | Def::Variant(..) | Def::Ctor(..) => {
|
||||
Res::Def(DefKind::AssociatedConst, _)
|
||||
| Res::Def(DefKind::Variant, _)
|
||||
| Res::Def(DefKind::Ctor(..), _) => {
|
||||
let len = self.segments.len();
|
||||
if len < 2 {
|
||||
return Err("Bad path");
|
||||
@ -606,7 +608,7 @@ impl Sig for ast::Path {
|
||||
}
|
||||
};
|
||||
|
||||
let id = id_from_def_id(def.def_id());
|
||||
let id = id_from_def_id(res.def_id());
|
||||
Ok(Signature {
|
||||
text: name,
|
||||
defs: vec![],
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use errors::{Applicability, DiagnosticId};
|
||||
use crate::hir::{self, GenericArg, GenericArgs, ExprKind};
|
||||
use crate::hir::def::{CtorOf, Def};
|
||||
use crate::hir::def::{CtorOf, Res, DefKind};
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::hir::HirVec;
|
||||
use crate::lint;
|
||||
@ -1311,10 +1311,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
hir_ref_id: hir::HirId,
|
||||
span: Span,
|
||||
qself_ty: Ty<'tcx>,
|
||||
qself_def: Def,
|
||||
qself_res: Res,
|
||||
assoc_segment: &hir::PathSegment,
|
||||
permit_variants: bool,
|
||||
) -> (Ty<'tcx>, Def) {
|
||||
) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorReported> {
|
||||
let tcx = self.tcx();
|
||||
let assoc_ident = assoc_segment.ident;
|
||||
|
||||
@ -1330,13 +1330,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
tcx.hygienic_eq(assoc_ident, vd.ident, adt_def.did)
|
||||
});
|
||||
if let Some(variant_def) = variant_def {
|
||||
let def = Def::Variant(variant_def.def_id);
|
||||
if permit_variants {
|
||||
check_type_alias_enum_variants_enabled(tcx, span);
|
||||
tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span);
|
||||
return (qself_ty, def);
|
||||
return Ok((qself_ty, DefKind::Variant, variant_def.def_id));
|
||||
} else {
|
||||
variant_resolution = Some(def);
|
||||
variant_resolution = Some(variant_def.def_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1344,32 +1343,26 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
|
||||
// Find the type of the associated item, and the trait where the associated
|
||||
// item is declared.
|
||||
let bound = match (&qself_ty.sty, qself_def) {
|
||||
(_, Def::SelfTy(Some(_), Some(impl_def_id))) => {
|
||||
let bound = match (&qself_ty.sty, qself_res) {
|
||||
(_, Res::SelfTy(Some(_), Some(impl_def_id))) => {
|
||||
// `Self` in an impl of a trait -- we have a concrete self type and a
|
||||
// trait reference.
|
||||
let trait_ref = match tcx.impl_trait_ref(impl_def_id) {
|
||||
Some(trait_ref) => trait_ref,
|
||||
None => {
|
||||
// A cycle error occurred, most likely.
|
||||
return (tcx.types.err, Def::Err);
|
||||
return Err(ErrorReported);
|
||||
}
|
||||
};
|
||||
|
||||
let candidates = traits::supertraits(tcx, ty::Binder::bind(trait_ref))
|
||||
.filter(|r| self.trait_defines_associated_type_named(r.def_id(), assoc_ident));
|
||||
|
||||
match self.one_bound_for_assoc_type(candidates, "Self", assoc_ident, span) {
|
||||
Ok(bound) => bound,
|
||||
Err(ErrorReported) => return (tcx.types.err, Def::Err),
|
||||
}
|
||||
self.one_bound_for_assoc_type(candidates, "Self", assoc_ident, span)?
|
||||
}
|
||||
(&ty::Param(_), Def::SelfTy(Some(param_did), None)) |
|
||||
(&ty::Param(_), Def::TyParam(param_did)) => {
|
||||
match self.find_bound_for_assoc_item(param_did, assoc_ident, span) {
|
||||
Ok(bound) => bound,
|
||||
Err(ErrorReported) => return (tcx.types.err, Def::Err),
|
||||
}
|
||||
(&ty::Param(_), Res::SelfTy(Some(param_did), None)) |
|
||||
(&ty::Param(_), Res::Def(DefKind::TyParam, param_did)) => {
|
||||
self.find_bound_for_assoc_item(param_did, assoc_ident, span)?
|
||||
}
|
||||
_ => {
|
||||
if variant_resolution.is_some() {
|
||||
@ -1413,7 +1406,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
&assoc_ident.as_str(),
|
||||
);
|
||||
}
|
||||
return (tcx.types.err, Def::Err);
|
||||
return Err(ErrorReported);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1427,14 +1420,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, bound);
|
||||
let ty = self.normalize_ty(span, ty);
|
||||
|
||||
let def = Def::AssociatedTy(item.def_id);
|
||||
let kind = DefKind::AssociatedTy;
|
||||
if !item.vis.is_accessible_from(def_scope, tcx) {
|
||||
let msg = format!("{} `{}` is private", def.kind_name(), assoc_ident);
|
||||
let msg = format!("{} `{}` is private", kind.descr(), assoc_ident);
|
||||
tcx.sess.span_err(span, &msg);
|
||||
}
|
||||
tcx.check_stability(item.def_id, Some(hir_ref_id), span);
|
||||
|
||||
if let Some(variant_def) = variant_resolution {
|
||||
if let Some(variant_def_id) = variant_resolution {
|
||||
let mut err = tcx.struct_span_lint_hir(
|
||||
AMBIGUOUS_ASSOCIATED_ITEMS,
|
||||
hir_ref_id,
|
||||
@ -1442,13 +1435,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
"ambiguous associated item",
|
||||
);
|
||||
|
||||
let mut could_refer_to = |def: Def, also| {
|
||||
let mut could_refer_to = |kind: DefKind, def_id, also| {
|
||||
let note_msg = format!("`{}` could{} refer to {} defined here",
|
||||
assoc_ident, also, def.kind_name());
|
||||
err.span_note(tcx.def_span(def.def_id()), ¬e_msg);
|
||||
assoc_ident, also, kind.descr());
|
||||
err.span_note(tcx.def_span(def_id), ¬e_msg);
|
||||
};
|
||||
could_refer_to(variant_def, "");
|
||||
could_refer_to(def, " also");
|
||||
could_refer_to(DefKind::Variant, variant_def_id, "");
|
||||
could_refer_to(kind, item.def_id, " also");
|
||||
|
||||
err.span_suggestion(
|
||||
span,
|
||||
@ -1458,7 +1451,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
).emit();
|
||||
}
|
||||
|
||||
(ty, def)
|
||||
Ok((ty, kind, item.def_id))
|
||||
}
|
||||
|
||||
fn qpath_to_ty(&self,
|
||||
@ -1554,11 +1547,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
err.span_label(span, "associated type not allowed here").emit();
|
||||
}
|
||||
|
||||
pub fn def_ids_for_path_segments(&self,
|
||||
segments: &[hir::PathSegment],
|
||||
self_ty: Option<Ty<'tcx>>,
|
||||
def: Def)
|
||||
-> Vec<PathSeg> {
|
||||
// FIXME(eddyb, varkor) handle type paths here too, not just value ones.
|
||||
pub fn def_ids_for_value_path_segments(
|
||||
&self,
|
||||
segments: &[hir::PathSegment],
|
||||
self_ty: Option<Ty<'tcx>>,
|
||||
kind: DefKind,
|
||||
def_id: DefId,
|
||||
) -> Vec<PathSeg> {
|
||||
// We need to extract the type parameters supplied by the user in
|
||||
// the path `path`. Due to the current setup, this is a bit of a
|
||||
// tricky-process; the problem is that resolve only tells us the
|
||||
@ -1602,10 +1598,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
// `SomeStruct::<A>`, contains parameters in TypeSpace, and the
|
||||
// final segment, `foo::<B>` contains parameters in fn space.
|
||||
//
|
||||
// 5. Reference to a local variable
|
||||
//
|
||||
// Local variables can't have any type parameters.
|
||||
//
|
||||
// The first step then is to categorize the segments appropriately.
|
||||
|
||||
let tcx = self.tcx();
|
||||
@ -1615,10 +1607,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
|
||||
let mut path_segs = vec![];
|
||||
|
||||
match def {
|
||||
match kind {
|
||||
// Case 1. Reference to a struct constructor.
|
||||
Def::Ctor(def_id, CtorOf::Struct, ..) |
|
||||
Def::SelfCtor(.., def_id) => {
|
||||
DefKind::Ctor(CtorOf::Struct, ..) => {
|
||||
// Everything but the final segment should have no
|
||||
// parameters at all.
|
||||
let generics = tcx.generics_of(def_id);
|
||||
@ -1629,7 +1620,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
}
|
||||
|
||||
// Case 2. Reference to a variant constructor.
|
||||
Def::Ctor(def_id, CtorOf::Variant, ..) | Def::Variant(def_id, ..) => {
|
||||
DefKind::Ctor(CtorOf::Variant, ..)
|
||||
| DefKind::Variant => {
|
||||
let adt_def = self_ty.map(|t| t.ty_adt_def().unwrap());
|
||||
let (generics_def_id, index) = if let Some(adt_def) = adt_def {
|
||||
debug_assert!(adt_def.is_enum());
|
||||
@ -1639,12 +1631,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
// parameters at all.
|
||||
let mut def_id = def_id;
|
||||
|
||||
// `Def::Ctor` -> `Def::Variant`
|
||||
if let Def::Ctor(..) = def {
|
||||
// `DefKind::Ctor` -> `DefKind::Variant`
|
||||
if let DefKind::Ctor(..) = kind {
|
||||
def_id = tcx.parent(def_id).unwrap()
|
||||
}
|
||||
|
||||
// `Def::Variant` -> `Def::Item` (enum)
|
||||
// `DefKind::Variant` -> `DefKind::Enum`
|
||||
let enum_def_id = tcx.parent(def_id).unwrap();
|
||||
(enum_def_id, last - 1)
|
||||
} else {
|
||||
@ -1662,16 +1654,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
}
|
||||
|
||||
// Case 3. Reference to a top-level value.
|
||||
Def::Fn(def_id) |
|
||||
Def::Const(def_id) |
|
||||
Def::ConstParam(def_id) |
|
||||
Def::Static(def_id) => {
|
||||
DefKind::Fn
|
||||
| DefKind::Const
|
||||
| DefKind::ConstParam
|
||||
| DefKind::Static => {
|
||||
path_segs.push(PathSeg(def_id, last));
|
||||
}
|
||||
|
||||
// Case 4. Reference to a method or associated const.
|
||||
Def::Method(def_id) |
|
||||
Def::AssociatedConst(def_id) => {
|
||||
DefKind::Method
|
||||
| DefKind::AssociatedConst => {
|
||||
if segments.len() >= 2 {
|
||||
let generics = tcx.generics_of(def_id);
|
||||
path_segs.push(PathSeg(generics.parent.unwrap(), last - 1));
|
||||
@ -1679,10 +1671,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
path_segs.push(PathSeg(def_id, last));
|
||||
}
|
||||
|
||||
// Case 5. Local variable, no generics.
|
||||
Def::Local(..) | Def::Upvar(..) => {}
|
||||
|
||||
_ => bug!("unexpected definition: {:?}", def),
|
||||
kind => bug!("unexpected definition kind {:?} for {:?}", kind, def_id),
|
||||
}
|
||||
|
||||
debug!("path_segs = {:?}", path_segs);
|
||||
@ -1691,19 +1680,19 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
}
|
||||
|
||||
// Check a type `Path` and convert it to a `Ty`.
|
||||
pub fn def_to_ty(&self,
|
||||
pub fn res_to_ty(&self,
|
||||
opt_self_ty: Option<Ty<'tcx>>,
|
||||
path: &hir::Path,
|
||||
permit_variants: bool)
|
||||
-> Ty<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
debug!("def_to_ty(def={:?}, opt_self_ty={:?}, path_segments={:?})",
|
||||
path.def, opt_self_ty, path.segments);
|
||||
debug!("res_to_ty(res={:?}, opt_self_ty={:?}, path_segments={:?})",
|
||||
path.res, opt_self_ty, path.segments);
|
||||
|
||||
let span = path.span;
|
||||
match path.def {
|
||||
Def::Existential(did) => {
|
||||
match path.res {
|
||||
Res::Def(DefKind::Existential, did) => {
|
||||
// Check for desugared impl trait.
|
||||
assert!(ty::is_impl_trait_defn(tcx, did).is_none());
|
||||
let item_segment = path.segments.split_last().unwrap();
|
||||
@ -1714,18 +1703,22 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
tcx.mk_opaque(did, substs),
|
||||
)
|
||||
}
|
||||
Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) |
|
||||
Def::Union(did) | Def::ForeignTy(did) => {
|
||||
Res::Def(DefKind::Enum, did)
|
||||
| Res::Def(DefKind::TyAlias, did)
|
||||
| Res::Def(DefKind::Struct, did)
|
||||
| Res::Def(DefKind::Union, did)
|
||||
| Res::Def(DefKind::ForeignTy, did) => {
|
||||
assert_eq!(opt_self_ty, None);
|
||||
self.prohibit_generics(path.segments.split_last().unwrap().1);
|
||||
self.ast_path_to_ty(span, did, path.segments.last().unwrap())
|
||||
}
|
||||
Def::Variant(_) if permit_variants => {
|
||||
Res::Def(kind @ DefKind::Variant, def_id) if permit_variants => {
|
||||
// Convert "variant type" as if it were a real type.
|
||||
// The resulting `Ty` is type of the variant's enum for now.
|
||||
assert_eq!(opt_self_ty, None);
|
||||
|
||||
let path_segs = self.def_ids_for_path_segments(&path.segments, None, path.def);
|
||||
let path_segs =
|
||||
self.def_ids_for_value_path_segments(&path.segments, None, kind, def_id);
|
||||
let generic_segs: FxHashSet<_> =
|
||||
path_segs.iter().map(|PathSeg(_, index)| index).collect();
|
||||
self.prohibit_generics(path.segments.iter().enumerate().filter_map(|(index, seg)| {
|
||||
@ -1739,7 +1732,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
let PathSeg(def_id, index) = path_segs.last().unwrap();
|
||||
self.ast_path_to_ty(span, *def_id, &path.segments[*index])
|
||||
}
|
||||
Def::TyParam(did) => {
|
||||
Res::Def(DefKind::TyParam, did) => {
|
||||
assert_eq!(opt_self_ty, None);
|
||||
self.prohibit_generics(&path.segments);
|
||||
|
||||
@ -1751,20 +1744,20 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
&tcx.hir().local_def_id_from_hir_id(hir_id)];
|
||||
tcx.mk_ty_param(index, tcx.hir().name_by_hir_id(hir_id).as_interned_str())
|
||||
}
|
||||
Def::SelfTy(_, Some(def_id)) => {
|
||||
Res::SelfTy(_, Some(def_id)) => {
|
||||
// `Self` in impl (we know the concrete type).
|
||||
assert_eq!(opt_self_ty, None);
|
||||
self.prohibit_generics(&path.segments);
|
||||
// Try to evaluate any array length constants
|
||||
self.normalize_ty(span, tcx.at(span).type_of(def_id))
|
||||
}
|
||||
Def::SelfTy(Some(_), None) => {
|
||||
Res::SelfTy(Some(_), None) => {
|
||||
// `Self` in trait.
|
||||
assert_eq!(opt_self_ty, None);
|
||||
self.prohibit_generics(&path.segments);
|
||||
tcx.mk_self_type()
|
||||
}
|
||||
Def::AssociatedTy(def_id) => {
|
||||
Res::Def(DefKind::AssociatedTy, def_id) => {
|
||||
debug_assert!(path.segments.len() >= 2);
|
||||
self.prohibit_generics(&path.segments[..path.segments.len() - 2]);
|
||||
self.qpath_to_ty(span,
|
||||
@ -1773,7 +1766,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
&path.segments[path.segments.len() - 2],
|
||||
path.segments.last().unwrap())
|
||||
}
|
||||
Def::PrimTy(prim_ty) => {
|
||||
Res::PrimTy(prim_ty) => {
|
||||
assert_eq!(opt_self_ty, None);
|
||||
self.prohibit_generics(&path.segments);
|
||||
match prim_ty {
|
||||
@ -1785,11 +1778,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
hir::Str => tcx.mk_str()
|
||||
}
|
||||
}
|
||||
Def::Err => {
|
||||
Res::Err => {
|
||||
self.set_tainted_by_errors();
|
||||
return self.tcx().types.err;
|
||||
}
|
||||
_ => span_bug!(span, "unexpected definition: {:?}", path.def)
|
||||
_ => span_bug!(span, "unexpected resolution: {:?}", path.res)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1835,7 +1828,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
let opt_self_ty = maybe_qself.as_ref().map(|qself| {
|
||||
self.ast_ty_to_ty(qself)
|
||||
});
|
||||
self.def_to_ty(opt_self_ty, path, false)
|
||||
self.res_to_ty(opt_self_ty, path, false)
|
||||
}
|
||||
hir::TyKind::Def(item_id, ref lifetimes) => {
|
||||
let did = tcx.hir().local_def_id_from_hir_id(item_id.id);
|
||||
@ -1845,12 +1838,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment);
|
||||
let ty = self.ast_ty_to_ty(qself);
|
||||
|
||||
let def = if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = qself.node {
|
||||
path.def
|
||||
let res = if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = qself.node {
|
||||
path.res
|
||||
} else {
|
||||
Def::Err
|
||||
Res::Err
|
||||
};
|
||||
self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, def, segment, false).0
|
||||
self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, res, segment, false)
|
||||
.map(|(ty, _, _)| ty).unwrap_or(tcx.types.err)
|
||||
}
|
||||
hir::TyKind::Array(ref ty, ref length) => {
|
||||
let length = self.ast_const_to_const(length, tcx.types.usize);
|
||||
@ -1911,7 +1905,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
let expr = &tcx.hir().body(ast_const.body).value;
|
||||
if let ExprKind::Path(ref qpath) = expr.node {
|
||||
if let hir::QPath::Resolved(_, ref path) = qpath {
|
||||
if let Def::ConstParam(def_id) = path.def {
|
||||
if let Res::Def(DefKind::ConstParam, def_id) = path.res {
|
||||
let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
|
||||
let item_id = tcx.hir().get_parent_node(node_id);
|
||||
let item_def_id = tcx.hir().local_def_id(item_id);
|
||||
@ -2097,8 +2091,8 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
{
|
||||
let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.iter().partition(|bound| {
|
||||
// Checks whether `trait_did` is an auto trait and adds it to `auto_traits` if so.
|
||||
match bound.trait_ref.path.def {
|
||||
Def::Trait(trait_did) if tcx.trait_is_auto(trait_did) => {
|
||||
match bound.trait_ref.path.res {
|
||||
Res::Def(DefKind::Trait, trait_did) if tcx.trait_is_auto(trait_did) => {
|
||||
true
|
||||
}
|
||||
_ => false
|
||||
@ -2106,7 +2100,7 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
});
|
||||
|
||||
let auto_traits = auto_traits.into_iter().map(|tr| {
|
||||
if let Def::Trait(trait_did) = tr.trait_ref.path.def {
|
||||
if let Res::Def(DefKind::Trait, trait_did) = tr.trait_ref.path.res {
|
||||
trait_did
|
||||
} else {
|
||||
unreachable!()
|
||||
|
@ -3,7 +3,7 @@ use crate::check::coercion::CoerceMany;
|
||||
use crate::util::nodemap::FxHashMap;
|
||||
use errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc::hir::{self, PatKind, Pat};
|
||||
use rustc::hir::def::{Def, CtorKind};
|
||||
use rustc::hir::def::{Res, DefKind, CtorKind};
|
||||
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
|
||||
use rustc::infer;
|
||||
use rustc::infer::type_variable::TypeVariableOrigin;
|
||||
@ -19,7 +19,7 @@ use syntax_pos::Span;
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use std::cmp;
|
||||
|
||||
use super::report_unexpected_variant_def;
|
||||
use super::report_unexpected_variant_res;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
/// `match_discrim_span` argument having a `Span` indicates that this pattern is part of
|
||||
@ -65,9 +65,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
PatKind::Path(ref qpath) => {
|
||||
let (def, _, _) = self.resolve_ty_and_def_ufcs(qpath, pat.hir_id, pat.span);
|
||||
let (def, _, _) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
|
||||
match def {
|
||||
Def::Const(..) | Def::AssociatedConst(..) => false,
|
||||
Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssociatedConst, _) => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
@ -840,28 +840,28 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
|
||||
let tcx = self.tcx;
|
||||
|
||||
// Resolve the path and check the definition for errors.
|
||||
let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath, pat.hir_id, pat.span);
|
||||
match def {
|
||||
Def::Err => {
|
||||
let (res, opt_ty, segments) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
|
||||
match res {
|
||||
Res::Err => {
|
||||
self.set_tainted_by_errors();
|
||||
return tcx.types.err;
|
||||
}
|
||||
Def::Method(..) => {
|
||||
report_unexpected_variant_def(tcx, &def, pat.span, qpath);
|
||||
Res::Def(DefKind::Method, _) => {
|
||||
report_unexpected_variant_res(tcx, res, pat.span, qpath);
|
||||
return tcx.types.err;
|
||||
}
|
||||
Def::Ctor(_, _, CtorKind::Fictive) |
|
||||
Def::Ctor(_, _, CtorKind::Fn) => {
|
||||
report_unexpected_variant_def(tcx, &def, pat.span, qpath);
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) |
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
|
||||
report_unexpected_variant_res(tcx, res, pat.span, qpath);
|
||||
return tcx.types.err;
|
||||
}
|
||||
Def::Ctor(_, _, CtorKind::Const) | Def::SelfCtor(..) |
|
||||
Def::Const(..) | Def::AssociatedConst(..) => {} // OK
|
||||
_ => bug!("unexpected pattern definition: {:?}", def)
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::SelfCtor(..) |
|
||||
Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssociatedConst, _) => {} // OK
|
||||
_ => bug!("unexpected pattern resolution: {:?}", res)
|
||||
}
|
||||
|
||||
// Type-check the path.
|
||||
let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.hir_id).0;
|
||||
let pat_ty = self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id).0;
|
||||
self.demand_suptype(pat.span, expected, pat_ty);
|
||||
pat_ty
|
||||
}
|
||||
@ -882,9 +882,9 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
|
||||
self.check_pat_walk(&pat, tcx.types.err, def_bm, match_arm_pat_span);
|
||||
}
|
||||
};
|
||||
let report_unexpected_def = |def: Def| {
|
||||
let report_unexpected_res = |res: Res| {
|
||||
let msg = format!("expected tuple struct/variant, found {} `{}`",
|
||||
def.kind_name(),
|
||||
res.kind_name(),
|
||||
hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
|
||||
struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg)
|
||||
.span_label(pat.span, "not a tuple variant or struct").emit();
|
||||
@ -892,35 +892,35 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
|
||||
};
|
||||
|
||||
// Resolve the path and check the definition for errors.
|
||||
let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath, pat.hir_id, pat.span);
|
||||
if def == Def::Err {
|
||||
let (res, opt_ty, segments) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
|
||||
if res == Res::Err {
|
||||
self.set_tainted_by_errors();
|
||||
on_error();
|
||||
return self.tcx.types.err;
|
||||
}
|
||||
|
||||
// Type-check the path.
|
||||
let (pat_ty, def) = self.instantiate_value_path(segments, opt_ty, def, pat.span,
|
||||
let (pat_ty, res) = self.instantiate_value_path(segments, opt_ty, res, pat.span,
|
||||
pat.hir_id);
|
||||
if !pat_ty.is_fn() {
|
||||
report_unexpected_def(def);
|
||||
report_unexpected_res(res);
|
||||
return self.tcx.types.err;
|
||||
}
|
||||
|
||||
let variant = match def {
|
||||
Def::Err => {
|
||||
let variant = match res {
|
||||
Res::Err => {
|
||||
self.set_tainted_by_errors();
|
||||
on_error();
|
||||
return tcx.types.err;
|
||||
}
|
||||
Def::AssociatedConst(..) | Def::Method(..) => {
|
||||
report_unexpected_def(def);
|
||||
Res::Def(DefKind::AssociatedConst, _) | Res::Def(DefKind::Method, _) => {
|
||||
report_unexpected_res(res);
|
||||
return tcx.types.err;
|
||||
}
|
||||
Def::Ctor(_, _, CtorKind::Fn) => {
|
||||
tcx.expect_variant_def(def)
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
|
||||
tcx.expect_variant_res(res)
|
||||
}
|
||||
_ => bug!("unexpected pattern definition: {:?}", def)
|
||||
_ => bug!("unexpected pattern resolution: {:?}", res)
|
||||
};
|
||||
|
||||
// Replace constructor type with constructed type for tuple struct patterns.
|
||||
@ -947,7 +947,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
|
||||
let fields_ending = if variant.fields.len() == 1 { "" } else { "s" };
|
||||
struct_span_err!(tcx.sess, pat.span, E0023,
|
||||
"this pattern has {} field{}, but the corresponding {} has {} field{}",
|
||||
subpats.len(), subpats_ending, def.kind_name(),
|
||||
subpats.len(), subpats_ending, res.kind_name(),
|
||||
variant.fields.len(), fields_ending)
|
||||
.span_label(pat.span, format!("expected {} field{}, found {}",
|
||||
variant.fields.len(), fields_ending, subpats.len()))
|
||||
|
@ -3,7 +3,7 @@ use super::method::MethodCallee;
|
||||
use super::{Expectation, FnCtxt, Needs, TupleArgumentsFlag};
|
||||
|
||||
use errors::{Applicability, DiagnosticBuilder};
|
||||
use hir::def::Def;
|
||||
use hir::def::Res;
|
||||
use hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
@ -317,7 +317,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let mut inner_callee_path = None;
|
||||
let def = match callee.node {
|
||||
hir::ExprKind::Path(ref qpath) => {
|
||||
self.tables.borrow().qpath_def(qpath, callee.hir_id)
|
||||
self.tables.borrow().qpath_res(qpath, callee.hir_id)
|
||||
}
|
||||
hir::ExprKind::Call(ref inner_callee, _) => {
|
||||
// If the call spans more than one line and the callee kind is
|
||||
@ -338,19 +338,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
inner_callee_path = Some(inner_qpath);
|
||||
self.tables
|
||||
.borrow()
|
||||
.qpath_def(inner_qpath, inner_callee.hir_id)
|
||||
.qpath_res(inner_qpath, inner_callee.hir_id)
|
||||
} else {
|
||||
Def::Err
|
||||
Res::Err
|
||||
}
|
||||
}
|
||||
_ => Def::Err,
|
||||
_ => Res::Err,
|
||||
};
|
||||
|
||||
err.span_label(call_expr.span, "call expression requires function");
|
||||
|
||||
let def_span = match def {
|
||||
Def::Err => None,
|
||||
Def::Local(id) | Def::Upvar(id, ..) => {
|
||||
Res::Err => None,
|
||||
Res::Local(id) | Res::Upvar(id, ..) => {
|
||||
Some(self.tcx.hir().span_by_hir_id(id))
|
||||
},
|
||||
_ => def
|
||||
|
@ -1,4 +1,5 @@
|
||||
use rustc::hir::{self, GenericParamKind, ImplItemKind, TraitItemKind};
|
||||
use rustc::hir::def::{Res, DefKind};
|
||||
use rustc::infer::{self, InferOk};
|
||||
use rustc::ty::{self, TyCtxt, GenericParamDefKind};
|
||||
use rustc::ty::util::ExplicitSelf;
|
||||
@ -844,7 +845,7 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
if let hir::TyKind::Path(
|
||||
hir::QPath::Resolved(None, ref path)) = ty.node
|
||||
{
|
||||
if let hir::def::Def::TyParam(def_id) = path.def {
|
||||
if let Res::Def(DefKind::TyParam, def_id) = path.res {
|
||||
if def_id == self.1 {
|
||||
self.0 = Some(ty.span);
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ use rustc::traits::{self, ObligationCause, ObligationCauseCode};
|
||||
use syntax::util::parser::PREC_POSTFIX;
|
||||
use syntax_pos::Span;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::Node;
|
||||
use rustc::hir::{print, lowering::is_range_literal};
|
||||
use rustc::ty::{self, Ty, AssociatedItem};
|
||||
@ -206,9 +205,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
// This function checks if the method isn't static and takes other arguments than `self`.
|
||||
fn has_no_input_arg(&self, method: &AssociatedItem) -> bool {
|
||||
match method.def() {
|
||||
Def::Method(def_id) => {
|
||||
self.tcx.fn_sig(def_id).inputs().skip_binder().len() == 1
|
||||
match method.kind {
|
||||
ty::AssociatedKind::Method => {
|
||||
self.tcx.fn_sig(method.def_id).inputs().skip_binder().len() == 1
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
@ -235,7 +234,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
expr: &hir::Expr,
|
||||
) -> Option<(Span, &'static str, String)> {
|
||||
if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = expr.node {
|
||||
if let hir::def::Def::Local(id) = path.def {
|
||||
if let hir::def::Res::Local(id) = path.res {
|
||||
let parent = self.tcx.hir().get_parent_node_by_hir_id(id);
|
||||
if let Some(Node::Expr(hir::Expr {
|
||||
hir_id,
|
||||
|
@ -15,7 +15,7 @@ use crate::namespace::Namespace;
|
||||
use errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def::{CtorOf, Def};
|
||||
use rustc::hir::def::{CtorOf, DefKind};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::traits;
|
||||
use rustc::ty::subst::{InternalSubsts, SubstsRef};
|
||||
@ -53,9 +53,9 @@ pub enum MethodError<'tcx> {
|
||||
// Multiple methods might apply.
|
||||
Ambiguity(Vec<CandidateSource>),
|
||||
|
||||
// Found an applicable method, but it is not visible. The second argument contains a list of
|
||||
// Found an applicable method, but it is not visible. The third argument contains a list of
|
||||
// not-in-scope traits which may work.
|
||||
PrivateMatch(Def, Vec<DefId>),
|
||||
PrivateMatch(DefKind, DefId, Vec<DefId>),
|
||||
|
||||
// Found a `Self: Sized` bound where `Self` is a trait object, also the caller may have
|
||||
// forgotten to import a trait.
|
||||
@ -400,7 +400,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
method_name: ast::Ident,
|
||||
self_ty: Ty<'tcx>,
|
||||
expr_id: hir::HirId
|
||||
) -> Result<Def, MethodError<'tcx>> {
|
||||
) -> Result<(DefKind, DefId), MethodError<'tcx>> {
|
||||
debug!(
|
||||
"resolve_ufcs: method_name={:?} self_ty={:?} expr_id={:?}",
|
||||
method_name, self_ty, expr_id,
|
||||
@ -422,9 +422,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// them as well. It's ok to use the variant's id as a ctor id since an
|
||||
// error will be reported on any use of such resolution anyway.
|
||||
let ctor_def_id = variant_def.ctor_def_id.unwrap_or(variant_def.def_id);
|
||||
let def = Def::Ctor(ctor_def_id, CtorOf::Variant, variant_def.ctor_kind);
|
||||
tcx.check_stability(def.def_id(), Some(expr_id), span);
|
||||
return Ok(def);
|
||||
tcx.check_stability(ctor_def_id, Some(expr_id), span);
|
||||
return Ok((
|
||||
DefKind::Ctor(CtorOf::Variant, variant_def.ctor_kind),
|
||||
ctor_def_id,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -439,10 +441,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
.unwrap().insert(import_def_id);
|
||||
}
|
||||
|
||||
let def = pick.item.def();
|
||||
debug!("resolve_ufcs: def={:?}", def);
|
||||
tcx.check_stability(def.def_id(), Some(expr_id), span);
|
||||
Ok(def)
|
||||
let def_kind = pick.item.def_kind();
|
||||
debug!("resolve_ufcs: def_kind={:?}, def_id={:?}", def_kind, pick.item.def_id);
|
||||
tcx.check_stability(pick.item.def_id, Some(expr_id), span);
|
||||
Ok((def_kind, pick.item.def_id))
|
||||
}
|
||||
|
||||
/// Finds item with name `item_name` defined in impl/trait `def_id`
|
||||
|
@ -6,7 +6,7 @@ use super::suggest;
|
||||
use crate::check::autoderef::{self, Autoderef};
|
||||
use crate::check::FnCtxt;
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::hir::def::Def;
|
||||
use crate::hir::def::DefKind;
|
||||
use crate::namespace::Namespace;
|
||||
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
@ -68,7 +68,7 @@ struct ProbeContext<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
||||
allow_similar_names: bool,
|
||||
|
||||
/// Some(candidate) if there is a private candidate
|
||||
private_candidate: Option<Def>,
|
||||
private_candidate: Option<(DefKind, DefId)>,
|
||||
|
||||
/// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
|
||||
/// for error reporting
|
||||
@ -520,7 +520,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
self.extension_candidates.push(candidate);
|
||||
}
|
||||
} else if self.private_candidate.is_none() {
|
||||
self.private_candidate = Some(candidate.item.def());
|
||||
self.private_candidate =
|
||||
Some((candidate.item.def_kind(), candidate.item.def_id));
|
||||
}
|
||||
}
|
||||
|
||||
@ -861,9 +862,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
method: &ty::AssociatedItem,
|
||||
self_ty: Option<Ty<'tcx>>,
|
||||
expected: Ty<'tcx>) -> bool {
|
||||
match method.def() {
|
||||
Def::Method(def_id) => {
|
||||
let fty = self.tcx.fn_sig(def_id);
|
||||
match method.kind {
|
||||
ty::AssociatedKind::Method => {
|
||||
let fty = self.tcx.fn_sig(method.def_id);
|
||||
self.probe(|_| {
|
||||
let substs = self.fresh_substs_for_item(self.span, method.def_id);
|
||||
let fty = fty.subst(self.tcx, substs);
|
||||
@ -1004,8 +1005,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
_ => vec![],
|
||||
};
|
||||
|
||||
if let Some(def) = private_candidate {
|
||||
return Err(MethodError::PrivateMatch(def, out_of_scope_traits));
|
||||
if let Some((kind, def_id)) = private_candidate {
|
||||
return Err(MethodError::PrivateMatch(kind, def_id, out_of_scope_traits));
|
||||
}
|
||||
let lev_candidate = self.probe_for_lev_candidate()?;
|
||||
|
||||
|
@ -8,7 +8,7 @@ use crate::util::nodemap::FxHashSet;
|
||||
use errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc::hir::{self, ExprKind, Node, QPath};
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def::{Res, DefKind};
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::hir::print;
|
||||
@ -249,7 +249,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
ExprKind::Path(ref qpath) => {
|
||||
// local binding
|
||||
if let &QPath::Resolved(_, ref path) = &qpath {
|
||||
if let hir::def::Def::Local(hir_id) = path.def {
|
||||
if let hir::def::Res::Local(hir_id) = path.res {
|
||||
let span = tcx.hir().span_by_hir_id(hir_id);
|
||||
let snippet = tcx.sess.source_map().span_to_snippet(span)
|
||||
.unwrap();
|
||||
@ -483,13 +483,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
if let Some(lev_candidate) = lev_candidate {
|
||||
let def = lev_candidate.def();
|
||||
let def_kind = lev_candidate.def_kind();
|
||||
err.span_suggestion(
|
||||
span,
|
||||
&format!(
|
||||
"there is {} {} with a similar name",
|
||||
def.article(),
|
||||
def.kind_name(),
|
||||
def_kind.article(),
|
||||
def_kind.descr(),
|
||||
),
|
||||
lev_candidate.ident.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
@ -510,9 +510,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
err.emit();
|
||||
}
|
||||
|
||||
MethodError::PrivateMatch(def, out_of_scope_traits) => {
|
||||
MethodError::PrivateMatch(kind, _, out_of_scope_traits) => {
|
||||
let mut err = struct_span_err!(self.tcx.sess, span, E0624,
|
||||
"{} `{}` is private", def.kind_name(), item_name);
|
||||
"{} `{}` is private", kind.descr(), item_name);
|
||||
self.suggest_valid_traits(&mut err, out_of_scope_traits);
|
||||
err.emit();
|
||||
}
|
||||
@ -799,21 +799,21 @@ fn compute_all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Vec<DefId>
|
||||
// Cross-crate:
|
||||
|
||||
let mut external_mods = FxHashSet::default();
|
||||
fn handle_external_def(tcx: TyCtxt<'_, '_, '_>,
|
||||
fn handle_external_res(tcx: TyCtxt<'_, '_, '_>,
|
||||
traits: &mut Vec<DefId>,
|
||||
external_mods: &mut FxHashSet<DefId>,
|
||||
def: Def) {
|
||||
match def {
|
||||
Def::Trait(def_id) |
|
||||
Def::TraitAlias(def_id) => {
|
||||
res: Res) {
|
||||
match res {
|
||||
Res::Def(DefKind::Trait, def_id) |
|
||||
Res::Def(DefKind::TraitAlias, def_id) => {
|
||||
traits.push(def_id);
|
||||
}
|
||||
Def::Mod(def_id) => {
|
||||
Res::Def(DefKind::Mod, def_id) => {
|
||||
if !external_mods.insert(def_id) {
|
||||
return;
|
||||
}
|
||||
for child in tcx.item_children(def_id).iter() {
|
||||
handle_external_def(tcx, traits, external_mods, child.def)
|
||||
handle_external_res(tcx, traits, external_mods, child.res)
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@ -824,7 +824,7 @@ fn compute_all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Vec<DefId>
|
||||
krate: cnum,
|
||||
index: CRATE_DEF_INDEX,
|
||||
};
|
||||
handle_external_def(tcx, &mut traits, &mut external_mods, Def::Mod(def_id));
|
||||
handle_external_res(tcx, &mut traits, &mut external_mods, Res::Def(DefKind::Mod, def_id));
|
||||
}
|
||||
|
||||
traits
|
||||
|
@ -88,7 +88,7 @@ mod op;
|
||||
use crate::astconv::{AstConv, PathSeg};
|
||||
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
|
||||
use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath};
|
||||
use rustc::hir::def::{CtorOf, CtorKind, Def};
|
||||
use rustc::hir::def::{CtorOf, CtorKind, Res, DefKind};
|
||||
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
|
||||
use rustc::hir::itemlikevisit::ItemLikeVisitor;
|
||||
@ -1896,13 +1896,13 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
check_representable(tcx, sp, def_id);
|
||||
}
|
||||
|
||||
fn report_unexpected_variant_def<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
def: &Def,
|
||||
fn report_unexpected_variant_res<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
res: Res,
|
||||
span: Span,
|
||||
qpath: &QPath) {
|
||||
span_err!(tcx.sess, span, E0533,
|
||||
"expected unit struct/variant or constant, found {} `{}`",
|
||||
def.kind_name(),
|
||||
res.kind_name(),
|
||||
hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
|
||||
}
|
||||
|
||||
@ -2149,7 +2149,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
self.tables
|
||||
.borrow_mut()
|
||||
.type_dependent_defs_mut()
|
||||
.insert(hir_id, Def::Method(method.def_id));
|
||||
.insert(hir_id, Ok((DefKind::Method, method.def_id)));
|
||||
|
||||
self.write_substs(hir_id, method.substs);
|
||||
|
||||
@ -3922,20 +3922,23 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
};
|
||||
let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
|
||||
let variant = match def {
|
||||
Def::Err => {
|
||||
Res::Err => {
|
||||
self.set_tainted_by_errors();
|
||||
return None;
|
||||
}
|
||||
Def::Variant(..) => {
|
||||
Res::Def(DefKind::Variant, _) => {
|
||||
match ty.sty {
|
||||
ty::Adt(adt, substs) => {
|
||||
Some((adt.variant_of_def(def), adt.did, substs))
|
||||
Some((adt.variant_of_res(def), adt.did, substs))
|
||||
}
|
||||
_ => bug!("unexpected type: {:?}", ty)
|
||||
}
|
||||
}
|
||||
Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
|
||||
Def::AssociatedTy(..) | Def::SelfTy(..) => {
|
||||
Res::Def(DefKind::Struct, _)
|
||||
| Res::Def(DefKind::Union, _)
|
||||
| Res::Def(DefKind::TyAlias, _)
|
||||
| Res::Def(DefKind::AssociatedTy, _)
|
||||
| Res::SelfTy(..) => {
|
||||
match ty.sty {
|
||||
ty::Adt(adt, substs) if !adt.is_enum() => {
|
||||
Some((adt.non_enum_variant(), adt.did, substs))
|
||||
@ -4230,18 +4233,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
ExprKind::Path(ref qpath) => {
|
||||
let (def, opt_ty, segs) = self.resolve_ty_and_def_ufcs(qpath, expr.hir_id,
|
||||
let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id,
|
||||
expr.span);
|
||||
let ty = match def {
|
||||
Def::Err => {
|
||||
let ty = match res {
|
||||
Res::Err => {
|
||||
self.set_tainted_by_errors();
|
||||
tcx.types.err
|
||||
}
|
||||
Def::Ctor(_, _, CtorKind::Fictive) => {
|
||||
report_unexpected_variant_def(tcx, &def, expr.span, qpath);
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
|
||||
report_unexpected_variant_res(tcx, res, expr.span, qpath);
|
||||
tcx.types.err
|
||||
}
|
||||
_ => self.instantiate_value_path(segs, opt_ty, def, expr.span, id).0,
|
||||
_ => self.instantiate_value_path(segs, opt_ty, res, expr.span, id).0,
|
||||
};
|
||||
|
||||
if let ty::FnDef(..) = ty.sty {
|
||||
@ -4778,45 +4781,54 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
qpath: &QPath,
|
||||
path_span: Span,
|
||||
hir_id: hir::HirId)
|
||||
-> (Def, Ty<'tcx>)
|
||||
-> (Res, Ty<'tcx>)
|
||||
{
|
||||
match *qpath {
|
||||
QPath::Resolved(ref maybe_qself, ref path) => {
|
||||
let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
|
||||
let ty = AstConv::def_to_ty(self, self_ty, path, true);
|
||||
(path.def, ty)
|
||||
let ty = AstConv::res_to_ty(self, self_ty, path, true);
|
||||
(path.res, ty)
|
||||
}
|
||||
QPath::TypeRelative(ref qself, ref segment) => {
|
||||
let ty = self.to_ty(qself);
|
||||
|
||||
let def = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.node {
|
||||
path.def
|
||||
let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.node {
|
||||
path.res
|
||||
} else {
|
||||
Def::Err
|
||||
Res::Err
|
||||
};
|
||||
let (ty, def) = AstConv::associated_path_to_ty(self, hir_id, path_span,
|
||||
ty, def, segment, true);
|
||||
let result = AstConv::associated_path_to_ty(
|
||||
self,
|
||||
hir_id,
|
||||
path_span,
|
||||
ty,
|
||||
res,
|
||||
segment,
|
||||
true,
|
||||
);
|
||||
let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err);
|
||||
let result = result.map(|(_, kind, def_id)| (kind, def_id));
|
||||
|
||||
// Write back the new resolution.
|
||||
self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
|
||||
self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, result);
|
||||
|
||||
(def, ty)
|
||||
(result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves associated value path into a base type and associated constant or method
|
||||
/// definition. The newly resolved definition is written into `type_dependent_defs`.
|
||||
pub fn resolve_ty_and_def_ufcs<'b>(&self,
|
||||
/// resolution. The newly resolved definition is written into `type_dependent_defs`.
|
||||
pub fn resolve_ty_and_res_ufcs<'b>(&self,
|
||||
qpath: &'b QPath,
|
||||
hir_id: hir::HirId,
|
||||
span: Span)
|
||||
-> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
|
||||
-> (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment])
|
||||
{
|
||||
debug!("resolve_ty_and_def_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
|
||||
debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
|
||||
let (ty, qself, item_segment) = match *qpath {
|
||||
QPath::Resolved(ref opt_qself, ref path) => {
|
||||
return (path.def,
|
||||
return (path.res,
|
||||
opt_qself.as_ref().map(|qself| self.to_ty(qself)),
|
||||
&path.segments[..]);
|
||||
}
|
||||
@ -4824,34 +4836,39 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
(self.to_ty(qself), qself, segment)
|
||||
}
|
||||
};
|
||||
if let Some(cached_def) = self.tables.borrow().type_dependent_def(hir_id) {
|
||||
if let Some(&cached_result) = self.tables.borrow().type_dependent_defs().get(hir_id) {
|
||||
// Return directly on cache hit. This is useful to avoid doubly reporting
|
||||
// errors with default match binding modes. See #44614.
|
||||
return (cached_def, Some(ty), slice::from_ref(&**item_segment))
|
||||
let def = cached_result.map(|(kind, def_id)| Res::Def(kind, def_id))
|
||||
.unwrap_or(Res::Err);
|
||||
return (def, Some(ty), slice::from_ref(&**item_segment));
|
||||
}
|
||||
let item_name = item_segment.ident;
|
||||
let def = match self.resolve_ufcs(span, item_name, ty, hir_id) {
|
||||
Ok(def) => def,
|
||||
Err(error) => {
|
||||
let def = match error {
|
||||
method::MethodError::PrivateMatch(def, _) => def,
|
||||
_ => Def::Err,
|
||||
};
|
||||
if item_name.name != keywords::Invalid.name() {
|
||||
self.report_method_error(span,
|
||||
ty,
|
||||
item_name,
|
||||
SelfSource::QPath(qself),
|
||||
error,
|
||||
None);
|
||||
}
|
||||
def
|
||||
let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
|
||||
let result = match error {
|
||||
method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
|
||||
_ => Err(ErrorReported),
|
||||
};
|
||||
if item_name.name != keywords::Invalid.name() {
|
||||
self.report_method_error(
|
||||
span,
|
||||
ty,
|
||||
item_name,
|
||||
SelfSource::QPath(qself),
|
||||
error,
|
||||
None,
|
||||
);
|
||||
}
|
||||
};
|
||||
result
|
||||
});
|
||||
|
||||
// Write back the new resolution.
|
||||
self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
|
||||
(def, Some(ty), slice::from_ref(&**item_segment))
|
||||
self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, result);
|
||||
(
|
||||
result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
|
||||
Some(ty),
|
||||
slice::from_ref(&**item_segment),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn check_decl_initializer(&self,
|
||||
@ -5352,9 +5369,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
// Rewrite `SelfCtor` to `Ctor`
|
||||
pub fn rewrite_self_ctor(&self, def: Def, span: Span) -> (Def, DefId, Ty<'tcx>) {
|
||||
pub fn rewrite_self_ctor(
|
||||
&self,
|
||||
res: Res,
|
||||
span: Span,
|
||||
) -> Result<(DefKind, DefId, Ty<'tcx>), ErrorReported> {
|
||||
let tcx = self.tcx;
|
||||
if let Def::SelfCtor(impl_def_id) = def {
|
||||
if let Res::SelfCtor(impl_def_id) = res {
|
||||
let ty = self.impl_self_ty(span, impl_def_id).ty;
|
||||
let adt_def = ty.ty_adt_def();
|
||||
|
||||
@ -5362,8 +5383,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
Some(adt_def) if adt_def.has_ctor() => {
|
||||
let variant = adt_def.non_enum_variant();
|
||||
let ctor_def_id = variant.ctor_def_id.unwrap();
|
||||
let def = Def::Ctor(ctor_def_id, CtorOf::Struct, variant.ctor_kind);
|
||||
(def, ctor_def_id, tcx.type_of(ctor_def_id))
|
||||
Ok((
|
||||
DefKind::Ctor(CtorOf::Struct, variant.ctor_kind),
|
||||
ctor_def_id,
|
||||
tcx.type_of(ctor_def_id),
|
||||
))
|
||||
}
|
||||
_ => {
|
||||
let mut err = tcx.sess.struct_span_err(span,
|
||||
@ -5386,16 +5410,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
err.emit();
|
||||
|
||||
(def, impl_def_id, tcx.types.err)
|
||||
Err(ErrorReported)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let def_id = def.def_id();
|
||||
|
||||
// The things we are substituting into the type should not contain
|
||||
// escaping late-bound regions, and nor should the base type scheme.
|
||||
let ty = tcx.type_of(def_id);
|
||||
(def, def_id, ty)
|
||||
match res {
|
||||
Res::Def(kind, def_id) => {
|
||||
// The things we are substituting into the type should not contain
|
||||
// escaping late-bound regions, and nor should the base type scheme.
|
||||
let ty = tcx.type_of(def_id);
|
||||
Ok((kind, def_id, ty))
|
||||
}
|
||||
_ => span_bug!(span, "unexpected res in rewrite_self_ctor: {:?}", res),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5404,37 +5431,41 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn instantiate_value_path(&self,
|
||||
segments: &[hir::PathSegment],
|
||||
self_ty: Option<Ty<'tcx>>,
|
||||
def: Def,
|
||||
res: Res,
|
||||
span: Span,
|
||||
hir_id: hir::HirId)
|
||||
-> (Ty<'tcx>, Def) {
|
||||
-> (Ty<'tcx>, Res) {
|
||||
debug!(
|
||||
"instantiate_value_path(segments={:?}, self_ty={:?}, def={:?}, hir_id={})",
|
||||
"instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
|
||||
segments,
|
||||
self_ty,
|
||||
def,
|
||||
res,
|
||||
hir_id,
|
||||
);
|
||||
|
||||
let tcx = self.tcx;
|
||||
|
||||
match def {
|
||||
Def::Local(hid) | Def::Upvar(hid, ..) => {
|
||||
match res {
|
||||
Res::Local(hid) | Res::Upvar(hid, ..) => {
|
||||
let ty = self.local_ty(span, hid).decl_ty;
|
||||
let ty = self.normalize_associated_types_in(span, &ty);
|
||||
self.write_ty(hir_id, ty);
|
||||
return (ty, def);
|
||||
return (ty, res);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let (def, def_id, ty) = self.rewrite_self_ctor(def, span);
|
||||
let path_segs = AstConv::def_ids_for_path_segments(self, segments, self_ty, def);
|
||||
let (kind, def_id, ty) = match self.rewrite_self_ctor(res, span) {
|
||||
Ok(result) => result,
|
||||
Err(ErrorReported) => return (tcx.types.err, res),
|
||||
};
|
||||
let path_segs =
|
||||
AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id);
|
||||
|
||||
let mut user_self_ty = None;
|
||||
let mut is_alias_variant_ctor = false;
|
||||
match def {
|
||||
Def::Ctor(_, CtorOf::Variant, _) => {
|
||||
match kind {
|
||||
DefKind::Ctor(CtorOf::Variant, _) => {
|
||||
if let Some(self_ty) = self_ty {
|
||||
let adt_def = self_ty.ty_adt_def().unwrap();
|
||||
user_self_ty = Some(UserSelfTy {
|
||||
@ -5444,10 +5475,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
is_alias_variant_ctor = true;
|
||||
}
|
||||
}
|
||||
Def::Method(def_id) |
|
||||
Def::AssociatedConst(def_id) => {
|
||||
DefKind::Method
|
||||
| DefKind::AssociatedConst => {
|
||||
let container = tcx.associated_item(def_id).container;
|
||||
debug!("instantiate_value_path: def={:?} container={:?}", def, container);
|
||||
debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
|
||||
match container {
|
||||
ty::TraitContainer(trait_did) => {
|
||||
callee::check_legal_trait_for_method_call(tcx, span, trait_did)
|
||||
@ -5637,7 +5668,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
ty_substituted);
|
||||
self.write_substs(hir_id, substs);
|
||||
|
||||
(ty_substituted, def)
|
||||
(ty_substituted, Res::Def(kind, def_id))
|
||||
}
|
||||
|
||||
fn check_rustc_args_require_const(&self,
|
||||
|
@ -42,7 +42,7 @@ use syntax::feature_gate;
|
||||
use syntax::symbol::{keywords, Symbol};
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
use rustc::hir::def::{CtorKind, Def};
|
||||
use rustc::hir::def::{CtorKind, Res, DefKind};
|
||||
use rustc::hir::Node;
|
||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
@ -380,8 +380,8 @@ fn is_param<'a, 'tcx>(
|
||||
param_id: hir::HirId,
|
||||
) -> bool {
|
||||
if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = ast_ty.node {
|
||||
match path.def {
|
||||
Def::SelfTy(Some(def_id), None) | Def::TyParam(def_id) => {
|
||||
match path.res {
|
||||
Res::SelfTy(Some(def_id), None) | Res::Def(DefKind::TyParam, def_id) => {
|
||||
def_id == tcx.hir().local_def_id_from_hir_id(param_id)
|
||||
}
|
||||
_ => false,
|
||||
@ -1377,14 +1377,14 @@ pub fn checked_type_of<'a, 'tcx>(
|
||||
}
|
||||
bug!("no arg matching AnonConst in path")
|
||||
}
|
||||
match path.def {
|
||||
match path.res {
|
||||
// We've encountered an `AnonConst` in some path, so we need to
|
||||
// figure out which generic parameter it corresponds to and return
|
||||
// the relevant type.
|
||||
Def::Struct(def_id)
|
||||
| Def::Union(def_id)
|
||||
| Def::Enum(def_id)
|
||||
| Def::Fn(def_id) => {
|
||||
Res::Def(DefKind::Struct, def_id)
|
||||
| Res::Def(DefKind::Union, def_id)
|
||||
| Res::Def(DefKind::Enum, def_id)
|
||||
| Res::Def(DefKind::Fn, def_id) => {
|
||||
let generics = tcx.generics_of(def_id);
|
||||
let mut param_index = 0;
|
||||
for param in &generics.params {
|
||||
@ -1399,7 +1399,7 @@ pub fn checked_type_of<'a, 'tcx>(
|
||||
// probably from an extra arg where one is not needed.
|
||||
return Some(tcx.types.err);
|
||||
}
|
||||
Def::Err => tcx.types.err,
|
||||
Res::Err => tcx.types.err,
|
||||
x => {
|
||||
if !fail {
|
||||
return None;
|
||||
@ -1778,7 +1778,7 @@ fn is_unsized<'gcx: 'tcx, 'tcx>(
|
||||
Some(ref tpb) => {
|
||||
// FIXME(#8559) currently requires the unbound to be built-in.
|
||||
if let Ok(kind_id) = kind_id {
|
||||
if tpb.path.def != Def::Trait(kind_id) {
|
||||
if tpb.path.res != Res::Def(DefKind::Trait, kind_id) {
|
||||
tcx.sess.span_warn(
|
||||
span,
|
||||
"default bound relaxed for a type parameter, but \
|
||||
|
@ -7,7 +7,7 @@ use syntax::ext::base::{MacroKind, SyntaxExtension};
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::hir::def::{Def, CtorKind};
|
||||
use rustc::hir::def::{Res, DefKind, CtorKind};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc_metadata::cstore::LoadedMacro;
|
||||
use rustc::ty;
|
||||
@ -37,72 +37,71 @@ use super::Clean;
|
||||
/// and `Some` of a vector of items if it was successfully expanded.
|
||||
pub fn try_inline(
|
||||
cx: &DocContext<'_>,
|
||||
def: Def,
|
||||
res: Res,
|
||||
name: ast::Name,
|
||||
visited: &mut FxHashSet<DefId>
|
||||
)
|
||||
-> Option<Vec<clean::Item>> {
|
||||
let did = if let Some(did) = def.opt_def_id() {
|
||||
) -> Option<Vec<clean::Item>> {
|
||||
let did = if let Some(did) = res.opt_def_id() {
|
||||
did
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
if did.is_local() { return None }
|
||||
let mut ret = Vec::new();
|
||||
let inner = match def {
|
||||
Def::Trait(did) => {
|
||||
let inner = match res {
|
||||
Res::Def(DefKind::Trait, did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeKind::Trait);
|
||||
ret.extend(build_impls(cx, did));
|
||||
clean::TraitItem(build_external_trait(cx, did))
|
||||
}
|
||||
Def::Fn(did) => {
|
||||
Res::Def(DefKind::Fn, did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeKind::Function);
|
||||
clean::FunctionItem(build_external_function(cx, did))
|
||||
}
|
||||
Def::Struct(did) => {
|
||||
Res::Def(DefKind::Struct, did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeKind::Struct);
|
||||
ret.extend(build_impls(cx, did));
|
||||
clean::StructItem(build_struct(cx, did))
|
||||
}
|
||||
Def::Union(did) => {
|
||||
Res::Def(DefKind::Union, did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeKind::Union);
|
||||
ret.extend(build_impls(cx, did));
|
||||
clean::UnionItem(build_union(cx, did))
|
||||
}
|
||||
Def::TyAlias(did) => {
|
||||
Res::Def(DefKind::TyAlias, did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeKind::Typedef);
|
||||
ret.extend(build_impls(cx, did));
|
||||
clean::TypedefItem(build_type_alias(cx, did), false)
|
||||
}
|
||||
Def::Enum(did) => {
|
||||
Res::Def(DefKind::Enum, did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeKind::Enum);
|
||||
ret.extend(build_impls(cx, did));
|
||||
clean::EnumItem(build_enum(cx, did))
|
||||
}
|
||||
Def::ForeignTy(did) => {
|
||||
Res::Def(DefKind::ForeignTy, did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeKind::Foreign);
|
||||
ret.extend(build_impls(cx, did));
|
||||
clean::ForeignTypeItem
|
||||
}
|
||||
// Never inline enum variants but leave them shown as re-exports.
|
||||
Def::Variant(..) => return None,
|
||||
Res::Def(DefKind::Variant, _) => return None,
|
||||
// Assume that enum variants and struct types are re-exported next to
|
||||
// their constructors.
|
||||
Def::Ctor(..) | Def::SelfCtor(..) => return Some(Vec::new()),
|
||||
Def::Mod(did) => {
|
||||
Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) => return Some(Vec::new()),
|
||||
Res::Def(DefKind::Mod, did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeKind::Module);
|
||||
clean::ModuleItem(build_module(cx, did, visited))
|
||||
}
|
||||
Def::Static(did) => {
|
||||
Res::Def(DefKind::Static, did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeKind::Static);
|
||||
clean::StaticItem(build_static(cx, did, cx.tcx.is_mutable_static(did)))
|
||||
}
|
||||
Def::Const(did) => {
|
||||
Res::Def(DefKind::Const, did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeKind::Const);
|
||||
clean::ConstantItem(build_const(cx, did))
|
||||
}
|
||||
// FIXME: proc-macros don't propagate attributes or spans across crates, so they look empty
|
||||
Def::Macro(did, MacroKind::Bang) => {
|
||||
Res::Def(DefKind::Macro(MacroKind::Bang), did) => {
|
||||
let mac = build_macro(cx, did, name);
|
||||
if let clean::MacroItem(..) = mac {
|
||||
record_extern_fqn(cx, did, clean::TypeKind::Macro);
|
||||
@ -127,15 +126,15 @@ pub fn try_inline(
|
||||
Some(ret)
|
||||
}
|
||||
|
||||
pub fn try_inline_glob(cx: &DocContext<'_>, def: Def, visited: &mut FxHashSet<DefId>)
|
||||
pub fn try_inline_glob(cx: &DocContext<'_>, res: Res, visited: &mut FxHashSet<DefId>)
|
||||
-> Option<Vec<clean::Item>>
|
||||
{
|
||||
if def == Def::Err { return None }
|
||||
let did = def.def_id();
|
||||
if res == Res::Err { return None }
|
||||
let did = res.def_id();
|
||||
if did.is_local() { return None }
|
||||
|
||||
match def {
|
||||
Def::Mod(did) => {
|
||||
match res {
|
||||
Res::Def(DefKind::Mod, did) => {
|
||||
let m = build_module(cx, did, visited);
|
||||
Some(m.items)
|
||||
}
|
||||
@ -413,10 +412,10 @@ fn build_module(
|
||||
// two namespaces, so the target may be listed twice. Make sure we only
|
||||
// visit each node at most once.
|
||||
for &item in cx.tcx.item_children(did).iter() {
|
||||
let def_id = item.def.def_id();
|
||||
let def_id = item.res.def_id();
|
||||
if item.vis == ty::Visibility::Public {
|
||||
if did == def_id || !visited.insert(def_id) { continue }
|
||||
if let Some(i) = try_inline(cx, item.def, item.ident.name, visited) {
|
||||
if let Some(i) = try_inline(cx, item.res, item.ident.name, visited) {
|
||||
items.extend(i)
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ use rustc::middle::lang_items;
|
||||
use rustc::middle::stability;
|
||||
use rustc::mir::interpret::{GlobalId, ConstValue};
|
||||
use rustc::hir::{self, HirVec};
|
||||
use rustc::hir::def::{self, Def, CtorKind};
|
||||
use rustc::hir::def::{self, Res, DefKind, CtorKind};
|
||||
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
use rustc::ty::subst::{InternalSubsts, SubstsRef, UnpackedKind};
|
||||
use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
|
||||
@ -257,8 +257,8 @@ impl Clean<ExternalCrate> for CrateNum {
|
||||
// Also note that this does not attempt to deal with modules tagged
|
||||
// duplicately for the same primitive. This is handled later on when
|
||||
// rendering by delegating everything to a hash map.
|
||||
let as_primitive = |def: Def| {
|
||||
if let Def::Mod(def_id) = def {
|
||||
let as_primitive = |res: Res| {
|
||||
if let Res::Def(DefKind::Mod, def_id) = res {
|
||||
let attrs = cx.tcx.get_attrs(def_id).clean(cx);
|
||||
let mut prim = None;
|
||||
for attr in attrs.lists("doc") {
|
||||
@ -281,11 +281,14 @@ impl Clean<ExternalCrate> for CrateNum {
|
||||
let item = cx.tcx.hir().expect_item_by_hir_id(id.id);
|
||||
match item.node {
|
||||
hir::ItemKind::Mod(_) => {
|
||||
as_primitive(Def::Mod(cx.tcx.hir().local_def_id_from_hir_id(id.id)))
|
||||
as_primitive(Res::Def(
|
||||
DefKind::Mod,
|
||||
cx.tcx.hir().local_def_id_from_hir_id(id.id),
|
||||
))
|
||||
}
|
||||
hir::ItemKind::Use(ref path, hir::UseKind::Single)
|
||||
if item.vis.node.is_pub() => {
|
||||
as_primitive(path.def).map(|(_, prim, attrs)| {
|
||||
as_primitive(path.res).map(|(_, prim, attrs)| {
|
||||
// Pretend the primitive is local.
|
||||
(cx.tcx.hir().local_def_id_from_hir_id(id.id), prim, attrs)
|
||||
})
|
||||
@ -294,12 +297,12 @@ impl Clean<ExternalCrate> for CrateNum {
|
||||
}
|
||||
}).collect()
|
||||
} else {
|
||||
cx.tcx.item_children(root).iter().map(|item| item.def)
|
||||
cx.tcx.item_children(root).iter().map(|item| item.res)
|
||||
.filter_map(as_primitive).collect()
|
||||
};
|
||||
|
||||
let as_keyword = |def: Def| {
|
||||
if let Def::Mod(def_id) = def {
|
||||
let as_keyword = |res: Res| {
|
||||
if let Res::Def(DefKind::Mod, def_id) = res {
|
||||
let attrs = cx.tcx.get_attrs(def_id).clean(cx);
|
||||
let mut keyword = None;
|
||||
for attr in attrs.lists("doc") {
|
||||
@ -323,11 +326,14 @@ impl Clean<ExternalCrate> for CrateNum {
|
||||
let item = cx.tcx.hir().expect_item_by_hir_id(id.id);
|
||||
match item.node {
|
||||
hir::ItemKind::Mod(_) => {
|
||||
as_keyword(Def::Mod(cx.tcx.hir().local_def_id_from_hir_id(id.id)))
|
||||
as_keyword(Res::Def(
|
||||
DefKind::Mod,
|
||||
cx.tcx.hir().local_def_id_from_hir_id(id.id),
|
||||
))
|
||||
}
|
||||
hir::ItemKind::Use(ref path, hir::UseKind::Single)
|
||||
if item.vis.node.is_pub() => {
|
||||
as_keyword(path.def).map(|(_, prim, attrs)| {
|
||||
as_keyword(path.res).map(|(_, prim, attrs)| {
|
||||
(cx.tcx.hir().local_def_id_from_hir_id(id.id), prim, attrs)
|
||||
})
|
||||
}
|
||||
@ -335,7 +341,7 @@ impl Clean<ExternalCrate> for CrateNum {
|
||||
}
|
||||
}).collect()
|
||||
} else {
|
||||
cx.tcx.item_children(root).iter().map(|item| item.def)
|
||||
cx.tcx.item_children(root).iter().map(|item| item.res)
|
||||
.filter_map(as_keyword).collect()
|
||||
};
|
||||
|
||||
@ -1157,7 +1163,7 @@ fn external_path(cx: &DocContext<'_>, name: &str, trait_did: Option<DefId>, has_
|
||||
bindings: Vec<TypeBinding>, substs: SubstsRef<'_>) -> Path {
|
||||
Path {
|
||||
global: false,
|
||||
def: Def::Err,
|
||||
res: Res::Err,
|
||||
segments: vec![PathSegment {
|
||||
name: name.to_string(),
|
||||
args: external_generic_args(cx, trait_did, has_self, bindings, substs)
|
||||
@ -2781,18 +2787,17 @@ impl Clean<Type> for hir::Ty {
|
||||
}
|
||||
}
|
||||
TyKind::Path(hir::QPath::Resolved(None, ref path)) => {
|
||||
if let Some(new_ty) = cx.ty_substs.borrow().get(&path.def).cloned() {
|
||||
return new_ty;
|
||||
}
|
||||
|
||||
if let Def::TyParam(did) = path.def {
|
||||
if let Res::Def(DefKind::TyParam, did) = path.res {
|
||||
if let Some(new_ty) = cx.ty_substs.borrow().get(&did).cloned() {
|
||||
return new_ty;
|
||||
}
|
||||
if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&did) {
|
||||
return ImplTrait(bounds);
|
||||
}
|
||||
}
|
||||
|
||||
let mut alias = None;
|
||||
if let Def::TyAlias(def_id) = path.def {
|
||||
if let Res::Def(DefKind::TyAlias, def_id) = path.res {
|
||||
// Substitute private type aliases
|
||||
if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(def_id) {
|
||||
if !cx.renderinfo.borrow().access_levels.is_exported(def_id) {
|
||||
@ -2805,7 +2810,7 @@ impl Clean<Type> for hir::Ty {
|
||||
let provided_params = &path.segments.last().expect("segments were empty");
|
||||
let mut ty_substs = FxHashMap::default();
|
||||
let mut lt_substs = FxHashMap::default();
|
||||
let mut const_substs = FxHashMap::default();
|
||||
let mut ct_substs = FxHashMap::default();
|
||||
provided_params.with_generic_args(|generic_args| {
|
||||
let mut indices: GenericParamCount = Default::default();
|
||||
for param in generics.params.iter() {
|
||||
@ -2834,9 +2839,8 @@ impl Clean<Type> for hir::Ty {
|
||||
indices.lifetimes += 1;
|
||||
}
|
||||
hir::GenericParamKind::Type { ref default, .. } => {
|
||||
let ty_param_def =
|
||||
Def::TyParam(
|
||||
cx.tcx.hir().local_def_id_from_hir_id(param.hir_id));
|
||||
let ty_param_def_id =
|
||||
cx.tcx.hir().local_def_id_from_hir_id(param.hir_id);
|
||||
let mut j = 0;
|
||||
let type_ = generic_args.args.iter().find_map(|arg| {
|
||||
match arg {
|
||||
@ -2851,17 +2855,16 @@ impl Clean<Type> for hir::Ty {
|
||||
}
|
||||
});
|
||||
if let Some(ty) = type_.cloned() {
|
||||
ty_substs.insert(ty_param_def, ty.clean(cx));
|
||||
ty_substs.insert(ty_param_def_id, ty.clean(cx));
|
||||
} else if let Some(default) = default.clone() {
|
||||
ty_substs.insert(ty_param_def,
|
||||
ty_substs.insert(ty_param_def_id,
|
||||
default.into_inner().clean(cx));
|
||||
}
|
||||
indices.types += 1;
|
||||
}
|
||||
hir::GenericParamKind::Const { .. } => {
|
||||
let const_param_def =
|
||||
Def::ConstParam(
|
||||
cx.tcx.hir().local_def_id_from_hir_id(param.hir_id));
|
||||
let const_param_def_id =
|
||||
cx.tcx.hir().local_def_id_from_hir_id(param.hir_id);
|
||||
let mut j = 0;
|
||||
let const_ = generic_args.args.iter().find_map(|arg| {
|
||||
match arg {
|
||||
@ -2876,7 +2879,7 @@ impl Clean<Type> for hir::Ty {
|
||||
}
|
||||
});
|
||||
if let Some(ct) = const_.cloned() {
|
||||
const_substs.insert(const_param_def, ct.clean(cx));
|
||||
ct_substs.insert(const_param_def_id, ct.clean(cx));
|
||||
}
|
||||
// FIXME(const_generics:defaults)
|
||||
indices.consts += 1;
|
||||
@ -2884,7 +2887,7 @@ impl Clean<Type> for hir::Ty {
|
||||
}
|
||||
}
|
||||
});
|
||||
return cx.enter_alias(ty_substs, lt_substs, const_substs, || ty.clean(cx));
|
||||
return cx.enter_alias(ty_substs, lt_substs, ct_substs, || ty.clean(cx));
|
||||
}
|
||||
resolve_type(cx, path.clean(cx), self.hir_id)
|
||||
}
|
||||
@ -2893,7 +2896,10 @@ impl Clean<Type> for hir::Ty {
|
||||
segments.pop();
|
||||
let trait_path = hir::Path {
|
||||
span: p.span,
|
||||
def: Def::Trait(cx.tcx.associated_item(p.def.def_id()).container.id()),
|
||||
res: Res::Def(
|
||||
DefKind::Trait,
|
||||
cx.tcx.associated_item(p.res.def_id()).container.id(),
|
||||
),
|
||||
segments: segments.into(),
|
||||
};
|
||||
Type::QPath {
|
||||
@ -2903,14 +2909,14 @@ impl Clean<Type> for hir::Ty {
|
||||
}
|
||||
}
|
||||
TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
|
||||
let mut def = Def::Err;
|
||||
let mut res = Res::Err;
|
||||
let ty = hir_ty_to_ty(cx.tcx, self);
|
||||
if let ty::Projection(proj) = ty.sty {
|
||||
def = Def::Trait(proj.trait_ref(cx.tcx).def_id);
|
||||
res = Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id);
|
||||
}
|
||||
let trait_path = hir::Path {
|
||||
span: self.span,
|
||||
def,
|
||||
res,
|
||||
segments: vec![].into(),
|
||||
};
|
||||
Type::QPath {
|
||||
@ -3196,7 +3202,7 @@ impl Clean<Option<Visibility>> for hir::Visibility {
|
||||
hir::VisibilityKind::Crate(_) => Visibility::Crate,
|
||||
hir::VisibilityKind::Restricted { ref path, .. } => {
|
||||
let path = path.clean(cx);
|
||||
let did = register_def(cx, path.def);
|
||||
let did = register_res(cx, path.res);
|
||||
Visibility::Restricted(did, path)
|
||||
}
|
||||
})
|
||||
@ -3434,7 +3440,7 @@ impl Clean<Span> for syntax_pos::Span {
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct Path {
|
||||
pub global: bool,
|
||||
pub def: Def,
|
||||
pub res: Res,
|
||||
pub segments: Vec<PathSegment>,
|
||||
}
|
||||
|
||||
@ -3448,7 +3454,7 @@ impl Clean<Path> for hir::Path {
|
||||
fn clean(&self, cx: &DocContext<'_>) -> Path {
|
||||
Path {
|
||||
global: self.is_global(),
|
||||
def: self.def,
|
||||
res: self.res,
|
||||
segments: if self.is_global() { &self.segments[1..] } else { &self.segments }.clean(cx),
|
||||
}
|
||||
}
|
||||
@ -3564,7 +3570,7 @@ fn strip_path(path: &Path) -> Path {
|
||||
|
||||
Path {
|
||||
global: path.global,
|
||||
def: path.def.clone(),
|
||||
res: path.res.clone(),
|
||||
segments,
|
||||
}
|
||||
}
|
||||
@ -3898,12 +3904,15 @@ impl Clean<Vec<Item>> for doctree::ExternCrate {
|
||||
if please_inline {
|
||||
let mut visited = FxHashSet::default();
|
||||
|
||||
let def = Def::Mod(DefId {
|
||||
krate: self.cnum,
|
||||
index: CRATE_DEF_INDEX,
|
||||
});
|
||||
let res = Res::Def(
|
||||
DefKind::Mod,
|
||||
DefId {
|
||||
krate: self.cnum,
|
||||
index: CRATE_DEF_INDEX,
|
||||
},
|
||||
);
|
||||
|
||||
if let Some(items) = inline::try_inline(cx, def, self.name, &mut visited) {
|
||||
if let Some(items) = inline::try_inline(cx, res, self.name, &mut visited) {
|
||||
return items;
|
||||
}
|
||||
}
|
||||
@ -3941,7 +3950,7 @@ impl Clean<Vec<Item>> for doctree::Import {
|
||||
let inner = if self.glob {
|
||||
if !denied {
|
||||
let mut visited = FxHashSet::default();
|
||||
if let Some(items) = inline::try_inline_glob(cx, path.def, &mut visited) {
|
||||
if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited) {
|
||||
return items;
|
||||
}
|
||||
}
|
||||
@ -3950,18 +3959,20 @@ impl Clean<Vec<Item>> for doctree::Import {
|
||||
} else {
|
||||
let name = self.name;
|
||||
if !please_inline {
|
||||
match path.def {
|
||||
Def::Mod(did) => if !did.is_local() && did.index == CRATE_DEF_INDEX {
|
||||
// if we're `pub use`ing an extern crate root, don't inline it unless we
|
||||
// were specifically asked for it
|
||||
denied = true;
|
||||
match path.res {
|
||||
Res::Def(DefKind::Mod, did) => {
|
||||
if !did.is_local() && did.index == CRATE_DEF_INDEX {
|
||||
// if we're `pub use`ing an extern crate root, don't inline it unless we
|
||||
// were specifically asked for it
|
||||
denied = true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if !denied {
|
||||
let mut visited = FxHashSet::default();
|
||||
if let Some(items) = inline::try_inline(cx, path.def, name, &mut visited) {
|
||||
if let Some(items) = inline::try_inline(cx, path.res, name, &mut visited) {
|
||||
return items;
|
||||
}
|
||||
}
|
||||
@ -4145,8 +4156,8 @@ fn resolve_type(cx: &DocContext<'_>,
|
||||
debug!("resolve_type({:?},{:?})", path, id);
|
||||
}
|
||||
|
||||
let is_generic = match path.def {
|
||||
Def::PrimTy(p) => match p {
|
||||
let is_generic = match path.res {
|
||||
Res::PrimTy(p) => match p {
|
||||
hir::Str => return Primitive(PrimitiveType::Str),
|
||||
hir::Bool => return Primitive(PrimitiveType::Bool),
|
||||
hir::Char => return Primitive(PrimitiveType::Char),
|
||||
@ -4154,45 +4165,47 @@ fn resolve_type(cx: &DocContext<'_>,
|
||||
hir::Uint(uint_ty) => return Primitive(uint_ty.into()),
|
||||
hir::Float(float_ty) => return Primitive(float_ty.into()),
|
||||
},
|
||||
Def::SelfTy(..) if path.segments.len() == 1 => {
|
||||
Res::SelfTy(..) if path.segments.len() == 1 => {
|
||||
return Generic(keywords::SelfUpper.name().to_string());
|
||||
}
|
||||
Def::TyParam(..) if path.segments.len() == 1 => {
|
||||
Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => {
|
||||
return Generic(format!("{:#}", path));
|
||||
}
|
||||
Def::SelfTy(..) | Def::TyParam(..) | Def::AssociatedTy(..) => true,
|
||||
Res::SelfTy(..)
|
||||
| Res::Def(DefKind::TyParam, _)
|
||||
| Res::Def(DefKind::AssociatedTy, _) => true,
|
||||
_ => false,
|
||||
};
|
||||
let did = register_def(&*cx, path.def);
|
||||
let did = register_res(&*cx, path.res);
|
||||
ResolvedPath { path: path, param_names: None, did: did, is_generic: is_generic }
|
||||
}
|
||||
|
||||
pub fn register_def(cx: &DocContext<'_>, def: Def) -> DefId {
|
||||
debug!("register_def({:?})", def);
|
||||
pub fn register_res(cx: &DocContext<'_>, res: Res) -> DefId {
|
||||
debug!("register_res({:?})", res);
|
||||
|
||||
let (did, kind) = match def {
|
||||
Def::Fn(i) => (i, TypeKind::Function),
|
||||
Def::TyAlias(i) => (i, TypeKind::Typedef),
|
||||
Def::Enum(i) => (i, TypeKind::Enum),
|
||||
Def::Trait(i) => (i, TypeKind::Trait),
|
||||
Def::Struct(i) => (i, TypeKind::Struct),
|
||||
Def::Union(i) => (i, TypeKind::Union),
|
||||
Def::Mod(i) => (i, TypeKind::Module),
|
||||
Def::ForeignTy(i) => (i, TypeKind::Foreign),
|
||||
Def::Const(i) => (i, TypeKind::Const),
|
||||
Def::Static(i) => (i, TypeKind::Static),
|
||||
Def::Variant(i) => (cx.tcx.parent(i).expect("cannot get parent def id"),
|
||||
let (did, kind) = match res {
|
||||
Res::Def(DefKind::Fn, i) => (i, TypeKind::Function),
|
||||
Res::Def(DefKind::TyAlias, i) => (i, TypeKind::Typedef),
|
||||
Res::Def(DefKind::Enum, i) => (i, TypeKind::Enum),
|
||||
Res::Def(DefKind::Trait, i) => (i, TypeKind::Trait),
|
||||
Res::Def(DefKind::Struct, i) => (i, TypeKind::Struct),
|
||||
Res::Def(DefKind::Union, i) => (i, TypeKind::Union),
|
||||
Res::Def(DefKind::Mod, i) => (i, TypeKind::Module),
|
||||
Res::Def(DefKind::ForeignTy, i) => (i, TypeKind::Foreign),
|
||||
Res::Def(DefKind::Const, i) => (i, TypeKind::Const),
|
||||
Res::Def(DefKind::Static, i) => (i, TypeKind::Static),
|
||||
Res::Def(DefKind::Variant, i) => (cx.tcx.parent(i).expect("cannot get parent def id"),
|
||||
TypeKind::Enum),
|
||||
Def::Macro(i, mac_kind) => match mac_kind {
|
||||
Res::Def(DefKind::Macro(mac_kind), i) => match mac_kind {
|
||||
MacroKind::Bang => (i, TypeKind::Macro),
|
||||
MacroKind::Attr => (i, TypeKind::Attr),
|
||||
MacroKind::Derive => (i, TypeKind::Derive),
|
||||
MacroKind::ProcMacroStub => unreachable!(),
|
||||
},
|
||||
Def::TraitAlias(i) => (i, TypeKind::TraitAlias),
|
||||
Def::SelfTy(Some(def_id), _) => (def_id, TypeKind::Trait),
|
||||
Def::SelfTy(_, Some(impl_def_id)) => return impl_def_id,
|
||||
_ => return def.def_id()
|
||||
Res::Def(DefKind::TraitAlias, i) => (i, TypeKind::TraitAlias),
|
||||
Res::SelfTy(Some(def_id), _) => (def_id, TypeKind::Trait),
|
||||
Res::SelfTy(_, Some(impl_def_id)) => return impl_def_id,
|
||||
_ => return res.def_id()
|
||||
};
|
||||
if did.is_local() { return did }
|
||||
inline::record_extern_fqn(cx, did, kind);
|
||||
@ -4204,10 +4217,10 @@ pub fn register_def(cx: &DocContext<'_>, def: Def) -> DefId {
|
||||
|
||||
fn resolve_use_source(cx: &DocContext<'_>, path: Path) -> ImportSource {
|
||||
ImportSource {
|
||||
did: if path.def.opt_def_id().is_none() {
|
||||
did: if path.res.opt_def_id().is_none() {
|
||||
None
|
||||
} else {
|
||||
Some(register_def(cx, path.def))
|
||||
Some(register_res(cx, path.res))
|
||||
},
|
||||
path,
|
||||
}
|
||||
@ -4417,13 +4430,13 @@ pub fn path_to_def(tcx: TyCtxt<'_, '_, '_>, path: &[&str]) -> Option<DefId> {
|
||||
for item in mem::replace(&mut items, Lrc::new(vec![])).iter() {
|
||||
if item.ident.name == *segment {
|
||||
if path_it.peek().is_none() {
|
||||
return match item.def {
|
||||
def::Def::Trait(did) => Some(did),
|
||||
return match item.res {
|
||||
def::Res::Def(DefKind::Trait, did) => Some(did),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
items = tcx.item_children(item.def.def_id());
|
||||
items = tcx.item_children(item.res.def_id());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
use rustc_lint;
|
||||
use rustc::session::{self, config};
|
||||
use rustc::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CrateNum, LOCAL_CRATE};
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::HirId;
|
||||
use rustc::middle::cstore::CrateStore;
|
||||
use rustc::middle::privacy::AccessLevels;
|
||||
@ -59,12 +58,12 @@ pub struct DocContext<'tcx> {
|
||||
// The current set of type and lifetime substitutions,
|
||||
// for expanding type aliases at the HIR level:
|
||||
|
||||
/// Table type parameter definition -> substituted type
|
||||
pub ty_substs: RefCell<FxHashMap<Def, clean::Type>>,
|
||||
/// Table `NodeId` of lifetime parameter definition -> substituted lifetime
|
||||
/// Table `DefId` of type parameter -> substituted type
|
||||
pub ty_substs: RefCell<FxHashMap<DefId, clean::Type>>,
|
||||
/// Table `DefId` of lifetime parameter -> substituted lifetime
|
||||
pub lt_substs: RefCell<FxHashMap<DefId, clean::Lifetime>>,
|
||||
/// Table node id of const parameter definition -> substituted const
|
||||
pub ct_substs: RefCell<FxHashMap<Def, clean::Constant>>,
|
||||
/// Table `DefId` of const parameter -> substituted const
|
||||
pub ct_substs: RefCell<FxHashMap<DefId, clean::Constant>>,
|
||||
/// Table DefId of `impl Trait` in argument position -> bounds
|
||||
pub impl_trait_bounds: RefCell<FxHashMap<DefId, Vec<clean::GenericBound>>>,
|
||||
pub send_trait: Option<DefId>,
|
||||
@ -91,9 +90,9 @@ impl<'tcx> DocContext<'tcx> {
|
||||
/// Call the closure with the given parameters set as
|
||||
/// the substitutions for a type alias' RHS.
|
||||
pub fn enter_alias<F, R>(&self,
|
||||
ty_substs: FxHashMap<Def, clean::Type>,
|
||||
ty_substs: FxHashMap<DefId, clean::Type>,
|
||||
lt_substs: FxHashMap<DefId, clean::Lifetime>,
|
||||
ct_substs: FxHashMap<Def, clean::Constant>,
|
||||
ct_substs: FxHashMap<DefId, clean::Constant>,
|
||||
f: F) -> R
|
||||
where F: FnOnce() -> R {
|
||||
let (old_tys, old_lts, old_cts) = (
|
||||
|
@ -1,5 +1,5 @@
|
||||
use errors::Applicability;
|
||||
use rustc::hir::def::{Def, Namespace::{self, *}, PerNS};
|
||||
use rustc::hir::def::{Res, DefKind, Namespace::{self, *}, PerNS};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir;
|
||||
use rustc::lint as lint;
|
||||
@ -56,7 +56,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||
ns: Namespace,
|
||||
current_item: &Option<String>,
|
||||
parent_id: Option<hir::HirId>)
|
||||
-> Result<(Def, Option<String>), ()>
|
||||
-> Result<(Res, Option<String>), ()>
|
||||
{
|
||||
let cx = self.cx;
|
||||
|
||||
@ -74,12 +74,12 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||
if let Ok(result) = result {
|
||||
// In case this is a trait item, skip the
|
||||
// early return and try looking for the trait.
|
||||
let value = match result.def {
|
||||
Def::Method(_) | Def::AssociatedConst(_) => true,
|
||||
Def::AssociatedTy(_) => false,
|
||||
Def::Variant(_) => return handle_variant(cx, result.def),
|
||||
let value = match result.res {
|
||||
Res::Def(DefKind::Method, _) | Res::Def(DefKind::AssociatedConst, _) => true,
|
||||
Res::Def(DefKind::AssociatedTy, _) => false,
|
||||
Res::Def(DefKind::Variant, _) => return handle_variant(cx, result.res),
|
||||
// Not a trait item; just return what we found.
|
||||
_ => return Ok((result.def, None))
|
||||
_ => return Ok((result.res, None))
|
||||
};
|
||||
|
||||
if value != (ns == ValueNS) {
|
||||
@ -132,8 +132,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||
let ty = cx.enter_resolver(|resolver| resolver.with_scope(node_id, |resolver| {
|
||||
resolver.resolve_str_path_error(DUMMY_SP, &path, false)
|
||||
}))?;
|
||||
match ty.def {
|
||||
Def::Struct(did) | Def::Union(did) | Def::Enum(did) | Def::TyAlias(did) => {
|
||||
match ty.res {
|
||||
Res::Def(DefKind::Struct, did)
|
||||
| Res::Def(DefKind::Union, did)
|
||||
| Res::Def(DefKind::Enum, did)
|
||||
| Res::Def(DefKind::TyAlias, did) => {
|
||||
let item = cx.tcx.inherent_impls(did)
|
||||
.iter()
|
||||
.flat_map(|imp| cx.tcx.associated_items(*imp))
|
||||
@ -144,7 +147,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||
ty::AssociatedKind::Const if ns == ValueNS => "associatedconstant",
|
||||
_ => return Err(())
|
||||
};
|
||||
Ok((ty.def, Some(format!("{}.{}", out, item_name))))
|
||||
Ok((ty.res, Some(format!("{}.{}", out, item_name))))
|
||||
} else {
|
||||
match cx.tcx.type_of(did).sty {
|
||||
ty::Adt(def, _) => {
|
||||
@ -156,7 +159,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||
.iter()
|
||||
.find(|item| item.ident.name == item_name)
|
||||
} {
|
||||
Ok((ty.def,
|
||||
Ok((ty.res,
|
||||
Some(format!("{}.{}",
|
||||
if def.is_enum() {
|
||||
"variant"
|
||||
@ -172,7 +175,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
Def::Trait(did) => {
|
||||
Res::Def(DefKind::Trait, did) => {
|
||||
let item = cx.tcx.associated_item_def_ids(did).iter()
|
||||
.map(|item| cx.tcx.associated_item(*item))
|
||||
.find(|item| item.ident.name == item_name);
|
||||
@ -190,7 +193,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||
_ => return Err(())
|
||||
};
|
||||
|
||||
Ok((ty.def, Some(format!("{}.{}", kind, item_name))))
|
||||
Ok((ty.res, Some(format!("{}.{}", kind, item_name))))
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
@ -280,7 +283,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||
}
|
||||
|
||||
let link = ori_link.replace("`", "");
|
||||
let (def, fragment) = {
|
||||
let (res, fragment) = {
|
||||
let mut kind = None;
|
||||
let path_str = if let Some(prefix) =
|
||||
["struct@", "enum@", "type@",
|
||||
@ -315,8 +318,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||
|
||||
match kind {
|
||||
Some(ns @ ValueNS) => {
|
||||
if let Ok(def) = self.resolve(path_str, ns, ¤t_item, parent_node) {
|
||||
def
|
||||
if let Ok(res) = self.resolve(path_str, ns, ¤t_item, parent_node) {
|
||||
res
|
||||
} else {
|
||||
resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
|
||||
// This could just be a normal link or a broken link
|
||||
@ -326,8 +329,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
Some(ns @ TypeNS) => {
|
||||
if let Ok(def) = self.resolve(path_str, ns, ¤t_item, parent_node) {
|
||||
def
|
||||
if let Ok(res) = self.resolve(path_str, ns, ¤t_item, parent_node) {
|
||||
res
|
||||
} else {
|
||||
resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
|
||||
// This could just be a normal link.
|
||||
@ -337,18 +340,18 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||
None => {
|
||||
// Try everything!
|
||||
let candidates = PerNS {
|
||||
macro_ns: macro_resolve(cx, path_str).map(|def| (def, None)),
|
||||
macro_ns: macro_resolve(cx, path_str).map(|res| (res, None)),
|
||||
type_ns: self
|
||||
.resolve(path_str, TypeNS, ¤t_item, parent_node)
|
||||
.ok(),
|
||||
value_ns: self
|
||||
.resolve(path_str, ValueNS, ¤t_item, parent_node)
|
||||
.ok()
|
||||
.and_then(|(def, fragment)| {
|
||||
.and_then(|(res, fragment)| {
|
||||
// Constructors are picked up in the type namespace.
|
||||
match def {
|
||||
Def::Ctor(..) | Def::SelfCtor(..) => None,
|
||||
_ => Some((def, fragment))
|
||||
match res {
|
||||
Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) => None,
|
||||
_ => Some((res, fragment))
|
||||
}
|
||||
}),
|
||||
};
|
||||
@ -369,14 +372,14 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||
path_str,
|
||||
&dox,
|
||||
link_range,
|
||||
candidates.map(|candidate| candidate.map(|(def, _)| def)),
|
||||
candidates.map(|candidate| candidate.map(|(res, _)| res)),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Some(MacroNS) => {
|
||||
if let Some(def) = macro_resolve(cx, path_str) {
|
||||
(def, None)
|
||||
if let Some(res) = macro_resolve(cx, path_str) {
|
||||
(res, None)
|
||||
} else {
|
||||
resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
|
||||
continue
|
||||
@ -385,10 +388,10 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
if let Def::PrimTy(_) = def {
|
||||
if let Res::PrimTy(_) = res {
|
||||
item.attrs.links.push((ori_link, None, fragment));
|
||||
} else {
|
||||
let id = register_def(cx, def);
|
||||
let id = register_res(cx, res);
|
||||
item.attrs.links.push((ori_link, Some(id), fragment));
|
||||
}
|
||||
}
|
||||
@ -419,24 +422,24 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||
}
|
||||
|
||||
/// Resolves a string as a macro.
|
||||
fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Def> {
|
||||
fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
|
||||
use syntax::ext::base::{MacroKind, SyntaxExtension};
|
||||
let segment = ast::PathSegment::from_ident(Ident::from_str(path_str));
|
||||
let path = ast::Path { segments: vec![segment], span: DUMMY_SP };
|
||||
cx.enter_resolver(|resolver| {
|
||||
let parent_scope = resolver.dummy_parent_scope();
|
||||
if let Ok(def) = resolver.resolve_macro_to_def_inner(&path, MacroKind::Bang,
|
||||
if let Ok(res) = resolver.resolve_macro_to_res_inner(&path, MacroKind::Bang,
|
||||
&parent_scope, false, false) {
|
||||
if let Def::Macro(_, MacroKind::ProcMacroStub) = def {
|
||||
if let Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) = res {
|
||||
// skip proc-macro stubs, they'll cause `get_macro` to crash
|
||||
} else {
|
||||
if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(def) {
|
||||
return Some(def.map_id(|_| panic!("unexpected id")));
|
||||
if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(res) {
|
||||
return Some(res.map_id(|_| panic!("unexpected id")));
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(def) = resolver.all_macros.get(&Symbol::intern(path_str)) {
|
||||
return Some(def.map_id(|_| panic!("unexpected id")));
|
||||
if let Some(res) = resolver.all_macros.get(&Symbol::intern(path_str)) {
|
||||
return Some(res.map_id(|_| panic!("unexpected id")));
|
||||
}
|
||||
None
|
||||
})
|
||||
@ -496,14 +499,14 @@ fn ambiguity_error(
|
||||
path_str: &str,
|
||||
dox: &str,
|
||||
link_range: Option<Range<usize>>,
|
||||
candidates: PerNS<Option<Def>>,
|
||||
candidates: PerNS<Option<Res>>,
|
||||
) {
|
||||
let sp = span_of_attrs(attrs);
|
||||
|
||||
let mut msg = format!("`{}` is ", path_str);
|
||||
|
||||
let candidates = [TypeNS, ValueNS, MacroNS].iter().filter_map(|&ns| {
|
||||
candidates[ns].map(|def| (def, ns))
|
||||
candidates[ns].map(|res| (res, ns))
|
||||
}).collect::<Vec<_>>();
|
||||
match candidates.as_slice() {
|
||||
[(first_def, _), (second_def, _)] => {
|
||||
@ -517,11 +520,11 @@ fn ambiguity_error(
|
||||
}
|
||||
_ => {
|
||||
let mut candidates = candidates.iter().peekable();
|
||||
while let Some((def, _)) = candidates.next() {
|
||||
while let Some((res, _)) = candidates.next() {
|
||||
if candidates.peek().is_some() {
|
||||
msg += &format!("{} {}, ", def.article(), def.kind_name());
|
||||
msg += &format!("{} {}, ", res.article(), res.kind_name());
|
||||
} else {
|
||||
msg += &format!("and {} {}", def.article(), def.kind_name());
|
||||
msg += &format!("and {} {}", res.article(), res.kind_name());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -539,23 +542,23 @@ fn ambiguity_error(
|
||||
diag.set_span(sp);
|
||||
diag.span_label(sp, "ambiguous link");
|
||||
|
||||
for (def, ns) in candidates {
|
||||
let (action, mut suggestion) = match def {
|
||||
Def::Method(..) | Def::Fn(..) => {
|
||||
for (res, ns) in candidates {
|
||||
let (action, mut suggestion) = match res {
|
||||
Res::Def(DefKind::Method, _) | Res::Def(DefKind::Fn, _) => {
|
||||
("add parentheses", format!("{}()", path_str))
|
||||
}
|
||||
Def::Macro(..) => {
|
||||
Res::Def(DefKind::Macro(..), _) => {
|
||||
("add an exclamation mark", format!("{}!", path_str))
|
||||
}
|
||||
_ => {
|
||||
let type_ = match (def, ns) {
|
||||
(Def::Const(..), _) => "const",
|
||||
(Def::Static(..), _) => "static",
|
||||
(Def::Struct(..), _) => "struct",
|
||||
(Def::Enum(..), _) => "enum",
|
||||
(Def::Union(..), _) => "union",
|
||||
(Def::Trait(..), _) => "trait",
|
||||
(Def::Mod(..), _) => "module",
|
||||
let type_ = match (res, ns) {
|
||||
(Res::Def(DefKind::Const, _), _) => "const",
|
||||
(Res::Def(DefKind::Static, _), _) => "static",
|
||||
(Res::Def(DefKind::Struct, _), _) => "struct",
|
||||
(Res::Def(DefKind::Enum, _), _) => "enum",
|
||||
(Res::Def(DefKind::Union, _), _) => "union",
|
||||
(Res::Def(DefKind::Trait, _), _) => "trait",
|
||||
(Res::Def(DefKind::Mod, _), _) => "module",
|
||||
(_, TypeNS) => "type",
|
||||
(_, ValueNS) => "value",
|
||||
(_, MacroNS) => "macro",
|
||||
@ -572,7 +575,7 @@ fn ambiguity_error(
|
||||
|
||||
diag.span_suggestion(
|
||||
sp,
|
||||
&format!("to link to the {}, {}", def.kind_name(), action),
|
||||
&format!("to link to the {}, {}", res.kind_name(), action),
|
||||
suggestion,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
@ -600,41 +603,41 @@ fn ambiguity_error(
|
||||
diag.emit();
|
||||
}
|
||||
|
||||
/// Given an enum variant's def, return the def of its enum and the associated fragment.
|
||||
fn handle_variant(cx: &DocContext<'_>, def: Def) -> Result<(Def, Option<String>), ()> {
|
||||
/// Given an enum variant's res, return the res of its enum and the associated fragment.
|
||||
fn handle_variant(cx: &DocContext<'_>, res: Res) -> Result<(Res, Option<String>), ()> {
|
||||
use rustc::ty::DefIdTree;
|
||||
|
||||
let parent = if let Some(parent) = cx.tcx.parent(def.def_id()) {
|
||||
let parent = if let Some(parent) = cx.tcx.parent(res.def_id()) {
|
||||
parent
|
||||
} else {
|
||||
return Err(())
|
||||
};
|
||||
let parent_def = Def::Enum(parent);
|
||||
let variant = cx.tcx.expect_variant_def(def);
|
||||
let parent_def = Res::Def(DefKind::Enum, parent);
|
||||
let variant = cx.tcx.expect_variant_res(res);
|
||||
Ok((parent_def, Some(format!("{}.v", variant.ident.name))))
|
||||
}
|
||||
|
||||
const PRIMITIVES: &[(&str, Def)] = &[
|
||||
("u8", Def::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U8))),
|
||||
("u16", Def::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U16))),
|
||||
("u32", Def::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U32))),
|
||||
("u64", Def::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U64))),
|
||||
("u128", Def::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U128))),
|
||||
("usize", Def::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::Usize))),
|
||||
("i8", Def::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I8))),
|
||||
("i16", Def::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I16))),
|
||||
("i32", Def::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I32))),
|
||||
("i64", Def::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I64))),
|
||||
("i128", Def::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I128))),
|
||||
("isize", Def::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::Isize))),
|
||||
("f32", Def::PrimTy(hir::PrimTy::Float(syntax::ast::FloatTy::F32))),
|
||||
("f64", Def::PrimTy(hir::PrimTy::Float(syntax::ast::FloatTy::F64))),
|
||||
("str", Def::PrimTy(hir::PrimTy::Str)),
|
||||
("bool", Def::PrimTy(hir::PrimTy::Bool)),
|
||||
("char", Def::PrimTy(hir::PrimTy::Char)),
|
||||
const PRIMITIVES: &[(&str, Res)] = &[
|
||||
("u8", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U8))),
|
||||
("u16", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U16))),
|
||||
("u32", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U32))),
|
||||
("u64", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U64))),
|
||||
("u128", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::U128))),
|
||||
("usize", Res::PrimTy(hir::PrimTy::Uint(syntax::ast::UintTy::Usize))),
|
||||
("i8", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I8))),
|
||||
("i16", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I16))),
|
||||
("i32", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I32))),
|
||||
("i64", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I64))),
|
||||
("i128", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::I128))),
|
||||
("isize", Res::PrimTy(hir::PrimTy::Int(syntax::ast::IntTy::Isize))),
|
||||
("f32", Res::PrimTy(hir::PrimTy::Float(syntax::ast::FloatTy::F32))),
|
||||
("f64", Res::PrimTy(hir::PrimTy::Float(syntax::ast::FloatTy::F64))),
|
||||
("str", Res::PrimTy(hir::PrimTy::Str)),
|
||||
("bool", Res::PrimTy(hir::PrimTy::Bool)),
|
||||
("char", Res::PrimTy(hir::PrimTy::Char)),
|
||||
];
|
||||
|
||||
fn is_primitive(path_str: &str, ns: Namespace) -> Option<Def> {
|
||||
fn is_primitive(path_str: &str, ns: Namespace) -> Option<Res> {
|
||||
if ns == TypeNS {
|
||||
PRIMITIVES.iter().find(|x| x.0 == path_str).map(|x| x.1)
|
||||
} else {
|
||||
|
@ -2,7 +2,7 @@
|
||||
//! usable for `clean`.
|
||||
|
||||
use rustc::hir::{self, Node};
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def::{Res, DefKind};
|
||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc::middle::privacy::AccessLevel;
|
||||
use rustc::util::nodemap::{FxHashSet, FxHashMap};
|
||||
@ -265,7 +265,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
/// Returns `true` if the target has been inlined.
|
||||
fn maybe_inline_local(&mut self,
|
||||
id: hir::HirId,
|
||||
def: Def,
|
||||
res: Res,
|
||||
renamed: Option<ast::Ident>,
|
||||
glob: bool,
|
||||
om: &mut Module,
|
||||
@ -284,10 +284,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
false
|
||||
}
|
||||
|
||||
debug!("maybe_inline_local def: {:?}", def);
|
||||
debug!("maybe_inline_local res: {:?}", res);
|
||||
|
||||
let tcx = self.cx.tcx;
|
||||
let def_did = if let Some(did) = def.opt_def_id() {
|
||||
let res_did = if let Some(did) = res.opt_def_id() {
|
||||
did
|
||||
} else {
|
||||
return false;
|
||||
@ -302,22 +302,22 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
// reachable in documentation -- a previously nonreachable item can be
|
||||
// made reachable by cross-crate inlining which we're checking here.
|
||||
// (this is done here because we need to know this upfront).
|
||||
if !def_did.is_local() && !is_no_inline {
|
||||
let attrs = clean::inline::load_attrs(self.cx, def_did);
|
||||
if !res_did.is_local() && !is_no_inline {
|
||||
let attrs = clean::inline::load_attrs(self.cx, res_did);
|
||||
let self_is_hidden = attrs.lists("doc").has_word("hidden");
|
||||
match def {
|
||||
Def::Trait(did) |
|
||||
Def::Struct(did) |
|
||||
Def::Union(did) |
|
||||
Def::Enum(did) |
|
||||
Def::ForeignTy(did) |
|
||||
Def::TyAlias(did) if !self_is_hidden => {
|
||||
match res {
|
||||
Res::Def(DefKind::Trait, did) |
|
||||
Res::Def(DefKind::Struct, did) |
|
||||
Res::Def(DefKind::Union, did) |
|
||||
Res::Def(DefKind::Enum, did) |
|
||||
Res::Def(DefKind::ForeignTy, did) |
|
||||
Res::Def(DefKind::TyAlias, did) if !self_is_hidden => {
|
||||
self.cx.renderinfo
|
||||
.borrow_mut()
|
||||
.access_levels.map
|
||||
.insert(did, AccessLevel::Public);
|
||||
},
|
||||
Def::Mod(did) => if !self_is_hidden {
|
||||
Res::Def(DefKind::Mod, did) => if !self_is_hidden {
|
||||
crate::visit_lib::LibEmbargoVisitor::new(self.cx).visit_mod(did);
|
||||
},
|
||||
_ => {},
|
||||
@ -326,21 +326,21 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
return false
|
||||
}
|
||||
|
||||
let def_hir_id = match tcx.hir().as_local_hir_id(def_did) {
|
||||
let res_hir_id = match tcx.hir().as_local_hir_id(res_did) {
|
||||
Some(n) => n, None => return false
|
||||
};
|
||||
|
||||
let is_private = !self.cx.renderinfo.borrow().access_levels.is_public(def_did);
|
||||
let is_hidden = inherits_doc_hidden(self.cx, def_hir_id);
|
||||
let is_private = !self.cx.renderinfo.borrow().access_levels.is_public(res_did);
|
||||
let is_hidden = inherits_doc_hidden(self.cx, res_hir_id);
|
||||
|
||||
// Only inline if requested or if the item would otherwise be stripped.
|
||||
if (!please_inline && !is_private && !is_hidden) || is_no_inline {
|
||||
return false
|
||||
}
|
||||
|
||||
if !self.view_item_stack.insert(def_hir_id) { return false }
|
||||
if !self.view_item_stack.insert(res_hir_id) { return false }
|
||||
|
||||
let ret = match tcx.hir().get_by_hir_id(def_hir_id) {
|
||||
let ret = match tcx.hir().get_by_hir_id(res_hir_id) {
|
||||
Node::Item(&hir::Item { node: hir::ItemKind::Mod(ref m), .. }) if glob => {
|
||||
let prev = mem::replace(&mut self.inlining, true);
|
||||
for i in &m.item_ids {
|
||||
@ -373,7 +373,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
self.view_item_stack.remove(&def_hir_id);
|
||||
self.view_item_stack.remove(&res_hir_id);
|
||||
ret
|
||||
}
|
||||
|
||||
@ -420,9 +420,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
|
||||
// Struct and variant constructors and proc macro stubs always show up alongside
|
||||
// their definitions, we've already processed them so just discard these.
|
||||
match path.def {
|
||||
Def::Ctor(..) | Def::SelfCtor(..) | Def::Macro(_, MacroKind::ProcMacroStub) =>
|
||||
return,
|
||||
match path.res {
|
||||
Res::Def(DefKind::Ctor(..), _)
|
||||
| Res::SelfCtor(..)
|
||||
| Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) => return,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@ -439,7 +440,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
});
|
||||
let ident = if is_glob { None } else { Some(ident) };
|
||||
if self.maybe_inline_local(item.hir_id,
|
||||
path.def,
|
||||
path.res,
|
||||
ident,
|
||||
is_glob,
|
||||
om,
|
||||
|
@ -1,5 +1,5 @@
|
||||
use rustc::middle::privacy::{AccessLevels, AccessLevel};
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def::{Res, DefKind};
|
||||
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
|
||||
use rustc::ty::Visibility;
|
||||
use rustc::util::nodemap::FxHashSet;
|
||||
@ -60,17 +60,17 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
for item in self.cx.tcx.item_children(def_id).iter() {
|
||||
if let Some(def_id) = item.def.opt_def_id() {
|
||||
if let Some(def_id) = item.res.opt_def_id() {
|
||||
if self.cx.tcx.def_key(def_id).parent.map_or(false, |d| d == def_id.index) ||
|
||||
item.vis == Visibility::Public {
|
||||
self.visit_item(item.def);
|
||||
self.visit_item(item.res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, def: Def) {
|
||||
let def_id = def.def_id();
|
||||
fn visit_item(&mut self, res: Res) {
|
||||
let def_id = res.def_id();
|
||||
let vis = self.cx.tcx.visibility(def_id);
|
||||
let inherited_item_level = if vis == Visibility::Public {
|
||||
self.prev_level
|
||||
@ -80,7 +80,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
|
||||
|
||||
let item_level = self.update(def_id, inherited_item_level);
|
||||
|
||||
if let Def::Mod(..) = def {
|
||||
if let Res::Def(DefKind::Mod, _) = res {
|
||||
let orig_level = self.prev_level;
|
||||
|
||||
self.prev_level = item_level;
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Ambiguity between a `macro_rules` macro and a non-existent import recovered as `Def::Err`
|
||||
// Ambiguity between a `macro_rules` macro and a non-existent import recovered as `Res::Err`
|
||||
|
||||
macro_rules! mac { () => () }
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Macro from prelude is shadowed by non-existent import recovered as `Def::Err`.
|
||||
// Macro from prelude is shadowed by non-existent import recovered as `Res::Err`.
|
||||
|
||||
use std::assert; //~ ERROR unresolved import `std::assert`
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user