From a3fcab36d25317ff2bad24d67f7e932c37f35d19 Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Sat, 20 Apr 2019 18:26:26 +0300
Subject: [PATCH 1/3] rustc: factor most DefId-containing variants out of Def
 and into DefKind.

---
 src/librustc/hir/def.rs                       | 166 ++++++++----------
 src/librustc/hir/lowering.rs                  |  41 +++--
 src/librustc/hir/map/mod.rs                   |  93 +++++-----
 src/librustc/hir/mod.rs                       |  11 +-
 src/librustc/hir/pat_util.rs                  |   8 +-
 src/librustc/middle/dead.rs                   |  10 +-
 src/librustc/middle/expr_use_visitor.rs       |  14 +-
 src/librustc/middle/intrinsicck.rs            |   4 +-
 src/librustc/middle/mem_categorization.rs     |  22 ++-
 src/librustc/middle/reachable.rs              |   6 +-
 src/librustc/middle/resolve_lifetime.rs       |  25 +--
 src/librustc/middle/stability.rs              |  10 +-
 src/librustc/ty/context.rs                    |   4 +-
 src/librustc/ty/mod.rs                        |  32 ++--
 src/librustc_lint/builtin.rs                  |   6 +-
 src/librustc_lint/nonstandard_style.rs        |   4 +-
 src/librustc_lint/unused.rs                   |   4 +-
 src/librustc_metadata/decoder.rs              |  64 ++++---
 .../error_reporting/region_name.rs            |   3 +-
 src/librustc_mir/const_eval.rs                |   4 +-
 src/librustc_mir/hair/cx/expr.rs              |  40 +++--
 src/librustc_mir/hair/pattern/mod.rs          |  21 ++-
 src/librustc_mir/interpret/eval_context.rs    |   6 +-
 src/librustc_mir/transform/const_prop.rs      |   4 +-
 src/librustc_mir/util/pretty.rs               |  13 +-
 src/librustc_passes/rvalue_promotion.rs       |  19 +-
 src/librustc_privacy/lib.rs                   |  12 +-
 src/librustc_resolve/build_reduced_graph.rs   |  87 +++++----
 src/librustc_resolve/diagnostics.rs           |  38 ++--
 src/librustc_resolve/lib.rs                   | 161 ++++++++++-------
 src/librustc_resolve/macros.rs                |  16 +-
 src/librustc_resolve/resolve_imports.rs       |   4 +-
 src/librustc_save_analysis/dump_visitor.rs    |  16 +-
 src/librustc_save_analysis/lib.rs             |  48 ++---
 src/librustc_save_analysis/sig.rs             |   6 +-
 src/librustc_typeck/astconv.rs                |  52 +++---
 src/librustc_typeck/check/_match.rs           |  18 +-
 src/librustc_typeck/check/compare_method.rs   |   3 +-
 src/librustc_typeck/check/demand.rs           |   4 +-
 src/librustc_typeck/check/method/mod.rs       |   7 +-
 src/librustc_typeck/check/method/probe.rs     |   4 +-
 src/librustc_typeck/check/method/suggest.rs   |  10 +-
 src/librustc_typeck/check/mod.rs              |  26 +--
 src/librustc_typeck/collect.rs                |  14 +-
 src/librustdoc/clean/inline.rs                |  30 ++--
 src/librustdoc/clean/mod.rs                   |  94 ++++++----
 .../passes/collect_intra_doc_links.rs         |  39 ++--
 src/librustdoc/visit_ast.rs                   |  21 +--
 src/librustdoc/visit_lib.rs                   |   4 +-
 49 files changed, 737 insertions(+), 611 deletions(-)

diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index 4af79764a60..d4ad4225b99 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -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,52 @@ 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),
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
+pub enum Def<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,10 +98,9 @@ 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,
 }
 
@@ -291,15 +301,7 @@ impl<Id> Def<Id> {
     /// Return `Some(..)` with the `DefId` of this `Def` 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)
-            }
+            Def::Def(_, id) => Some(id),
 
             Def::Local(..) |
             Def::Upvar(..) |
@@ -318,7 +320,7 @@ impl<Id> Def<Id> {
     /// Return the `DefId` of this `Def` if it represents a module.
     pub fn mod_def_id(&self) -> Option<DefId> {
         match *self {
-            Def::Mod(id) => Some(id),
+            Def::Def(DefKind::Mod, id) => Some(id),
             _ => None,
         }
     }
@@ -326,39 +328,39 @@ impl<Id> Def<Id> {
     /// A human readable name for the def 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) =>
+            Def::Def(DefKind::Fn, _) => "function",
+            Def::Def(DefKind::Mod, _) => "module",
+            Def::Def(DefKind::Static, _) => "static",
+            Def::Def(DefKind::Enum, _) => "enum",
+            Def::Def(DefKind::Variant, _) => "variant",
+            Def::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), _) => "tuple variant",
+            Def::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), _) => "unit variant",
+            Def::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fictive), _) => "struct variant",
+            Def::Def(DefKind::Struct, _) => "struct",
+            Def::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), _) => "tuple struct",
+            Def::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Const), _) => "unit struct",
+            Def::Def(DefKind::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::Def(DefKind::Existential, _) => "existential type",
+            Def::Def(DefKind::TyAlias, _) => "type alias",
+            Def::Def(DefKind::TraitAlias, _) => "trait alias",
+            Def::Def(DefKind::AssociatedTy, _) => "associated type",
+            Def::Def(DefKind::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::Def(DefKind::Union, _) => "union",
+            Def::Def(DefKind::Trait, _) => "trait",
+            Def::Def(DefKind::ForeignTy, _) => "foreign type",
+            Def::Def(DefKind::Method, _) => "method",
+            Def::Def(DefKind::Const, _) => "constant",
+            Def::Def(DefKind::AssociatedConst, _) => "associated constant",
+            Def::Def(DefKind::TyParam, _) => "type parameter",
+            Def::Def(DefKind::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::Def(DefKind::Macro(macro_kind), _) => macro_kind.descr(),
             Def::ToolMod => "tool module",
             Def::NonMacroAttr(attr_kind) => attr_kind.descr(),
             Def::Err => "unresolved item",
@@ -368,36 +370,21 @@ impl<Id> Def<Id> {
     /// An English article for the def.
     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(),
+            Def::Def(DefKind::AssociatedTy, _)
+            | Def::Def(DefKind::AssociatedConst, _)
+            | Def::Def(DefKind::AssociatedExistential, _)
+            | Def::Def(DefKind::Enum, _)
+            | Def::Def(DefKind::Existential, _)
+            | Def::Err => "an",
+            Def::Def(DefKind::Macro(macro_kind), _) => macro_kind.article(),
             _ => "a",
         }
     }
 
     pub fn map_id<R>(self, mut map: impl FnMut(Id) -> R) -> Def<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::Def(kind, id) => Def::Def(kind, 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(
@@ -407,7 +394,6 @@ impl<Id> Def<Id> {
             ),
             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,
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index ad26e05bf80..583508bfb7e 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -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::{Def, DefKind, PathResolution, PerNS};
 use crate::hir::{GenericArg, ConstArg};
 use crate::lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
                     ELIDED_LIFETIMES_IN_PATHS};
@@ -1500,7 +1500,7 @@ impl<'a> LoweringContext<'a> {
                             None,
                             P(hir::Path {
                                 span,
-                                def: Def::TyParam(DefId::local(def_index)),
+                                def: Def::Def(DefKind::TyParam, DefId::local(def_index)),
                                 segments: hir_vec![hir::PathSegment::from_ident(ident)],
                             }),
                         ))
@@ -1870,17 +1870,17 @@ impl<'a> LoweringContext<'a> {
                         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 => {
+                        Def::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 => {
+                        Def::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 =>
+                        Def::Def(DefKind::Struct, def_id)
+                        | Def::Def(DefKind::Union, def_id)
+                        | Def::Def(DefKind::Enum, def_id)
+                        | Def::Def(DefKind::TyAlias, def_id)
+                        | Def::Def(DefKind::Trait, def_id) if i + 1 == proj_start =>
                         {
                             Some(def_id)
                         }
@@ -1888,9 +1888,12 @@ impl<'a> LoweringContext<'a> {
                     };
                     let parenthesized_generic_args = match resolution.base_def() {
                         // `a::b::Trait(Args)`
-                        Def::Trait(..) if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
+                        Def::Def(DefKind::Trait, _)
+                            if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
                         // `a::b::Trait(Args)::TraitItem`
-                        Def::Method(..) | Def::AssociatedConst(..) | Def::AssociatedTy(..)
+                        Def::Def(DefKind::Method, _)
+                        | Def::Def(DefKind::AssociatedConst, _)
+                        | Def::Def(DefKind::AssociatedTy, _)
                             if i + 2 == proj_start =>
                         {
                             ParenthesizedGenericArgs::Ok
@@ -1898,11 +1901,11 @@ impl<'a> LoweringContext<'a> {
                         // Avoid duplicated errors.
                         Def::Err => ParenthesizedGenericArgs::Ok,
                         // An error
-                        Def::Struct(..)
-                        | Def::Enum(..)
-                        | Def::Union(..)
-                        | Def::TyAlias(..)
-                        | Def::Variant(..) if i + 1 == proj_start =>
+                        Def::Def(DefKind::Struct, _)
+                        | Def::Def(DefKind::Enum, _)
+                        | Def::Def(DefKind::Union, _)
+                        | Def::Def(DefKind::TyAlias, _)
+                        | Def::Def(DefKind::Variant, _) if i + 1 == proj_start =>
                         {
                             ParenthesizedGenericArgs::Err
                         }
@@ -2788,7 +2791,7 @@ 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(Def::Def(DefKind::TyParam, def_id)) = self.resolver
                                     .get_resolution(bound_pred.bounded_ty.id)
                                     .map(|d| d.base_def())
                                 {
@@ -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 Def::Def(DefKind::Trait, def_id) = trait_ref.path.def {
                                 this.trait_impls.entry(def_id).or_default().push(
                                     lowered_trait_impl_id);
                             }
@@ -5277,7 +5280,7 @@ impl<'a> LoweringContext<'a> {
             hir::QPath::Resolved(None, path) => {
                 // Turn trait object paths into `TyKind::TraitObject` instead.
                 match path.def {
-                    Def::Trait(_) | Def::TraitAlias(_) => {
+                    Def::Def(DefKind::Trait, _) | Def::Def(DefKind::TraitAlias, _) => {
                         let principal = hir::PolyTraitRef {
                             bound_generic_params: hir::HirVec::new(),
                             trait_ref: hir::TraitRef {
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 826ae836a90..9251f8e797b 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -17,6 +17,7 @@ use syntax::ext::base::MacroKind;
 use syntax_pos::{Span, DUMMY_SP};
 
 use crate::hir::*;
+use crate::hir::{Def, DefKind};
 use crate::hir::itemlikevisit::ItemLikeVisitor;
 use crate::hir::print::Nested;
 use crate::util::nodemap::FxHashMap;
@@ -316,67 +317,61 @@ impl<'hir> Map<'hir> {
             return None
         };
 
-        match node {
+        let kind = 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(_) |
@@ -390,26 +385,22 @@ impl<'hir> Map<'hir> {
             Node::Lifetime(_) |
             Node::Visibility(_) |
             Node::Block(_) |
-            Node::Crate => None,
+            Node::Crate => return None,
+            // FIXME(eddyb) this is the only non-`DefKind` case here,
+            // investigate whether it's actually used, and ideally remove it.
             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))
+                return Some(Def::Local(local.hir_id));
             }
+            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,
+                }
             }
-        }
+        };
+        Some(Def::Def(kind, self.local_def_id(node_id)))
     }
 
     // FIXME(@ljedrz): replace the NodeId variant
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 4293019aed5..f474ab1a1a5 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -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::{Def, DefKind};
 use crate::hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
 use crate::util::nodemap::{NodeMap, FxHashSet};
 use crate::mir::mono::Linkage;
@@ -1394,7 +1394,10 @@ impl Expr {
          match self.node {
             ExprKind::Path(QPath::Resolved(_, ref path)) => {
                 match path.def {
-                    Def::Local(..) | Def::Upvar(..) | Def::Static(..) | Def::Err => true,
+                    Def::Local(..)
+                    | Def::Upvar(..)
+                    | Def::Def(DefKind::Static, _)
+                    | Def::Err => true,
                     _ => false,
                 }
             }
@@ -2152,8 +2155,8 @@ 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::Def(DefKind::Trait, did) => did,
+            Def::Def(DefKind::TraitAlias, did) => did,
             Def::Err => {
                 FatalError.raise();
             }
diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs
index e7eda5aab13..a1ff3dcda2d 100644
--- a/src/librustc/hir/pat_util.rs
+++ b/src/librustc/hir/pat_util.rs
@@ -1,4 +1,4 @@
-use crate::hir::def::{CtorOf, Def};
+use crate::hir::def::{CtorOf, Def, DefKind};
 use crate::hir::def_id::DefId;
 use crate::hir::{self, HirId, PatKind};
 use syntax::ast;
@@ -55,7 +55,7 @@ impl hir::Pat {
             PatKind::TupleStruct(hir::QPath::Resolved(_, ref path), ..) |
             PatKind::Struct(hir::QPath::Resolved(_, ref path), ..) => {
                 match path.def {
-                    Def::Variant(..) => true,
+                    Def::Def(DefKind::Variant, _) => true,
                     _ => false
                 }
             }
@@ -125,8 +125,8 @@ impl hir::Pat {
                 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),
+                        Def::Def(DefKind::Variant, id) => variants.push(id),
+                        Def::Def(DefKind::Ctor(CtorOf::Variant, ..), id) => variants.push(id),
                         _ => ()
                     }
                 }
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 28fc3047af6..a58fb1a933e 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -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, Def, DefKind};
 use crate::hir::CodegenFnAttrFlags;
 use crate::hir::def_id::{DefId, LOCAL_CRATE};
 use crate::lint;
@@ -70,13 +70,15 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
 
     fn handle_definition(&mut self, def: Def) {
         match def {
-            Def::Const(_) | Def::AssociatedConst(..) | Def::TyAlias(_) => {
+            Def::Def(DefKind::Const, _)
+            | Def::Def(DefKind::AssociatedConst, _)
+            | Def::Def(DefKind::TyAlias, _) => {
                 self.check_def_id(def.def_id());
             }
             _ if self.in_pat => {},
             Def::PrimTy(..) | Def::SelfTy(..) | Def::SelfCtor(..) |
             Def::Local(..) | Def::Upvar(..) => {}
-            Def::Ctor(ctor_def_id, CtorOf::Variant, ..) => {
+            Def::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,7 +86,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                     self.check_def_id(variant_id);
                 }
             }
-            Def::Variant(variant_id) => {
+            Def::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) {
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 3b9af75bd0a..149f9fe96f6 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -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, Def, DefKind};
 use crate::hir::def_id::DefId;
 use crate::infer::InferCtxt;
 use crate::middle::mem_categorization as mc;
@@ -900,21 +900,25 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
             };
             let def = mc.tables.qpath_def(qpath, pat.hir_id);
             match def {
-                Def::Ctor(variant_ctor_did, CtorOf::Variant, ..) => {
+                Def::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) => {
+                Def::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(..) => {
+                Def::Def(DefKind::Struct, _)
+                | Def::Def(DefKind::Ctor(..), _)
+                | Def::Def(DefKind::Union, _)
+                | Def::Def(DefKind::TyAlias, _)
+                | Def::Def(DefKind::AssociatedTy, _)
+                | Def::SelfTy(..) => {
                     debug!("struct cmt_pat={:?} pat={:?}", cmt_pat, pat);
                     delegate.matched_pat(pat, &cmt_pat, match_mode);
                 }
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index c4071e9f354..507aff69005 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -1,4 +1,4 @@
-use crate::hir::def::Def;
+use crate::hir::def::{Def, DefKind};
 use crate::hir::def_id::DefId;
 use crate::ty::{self, Ty, TyCtxt};
 use crate::ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx};
@@ -157,7 +157,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, 'tcx> {
         } else {
             Def::Err
         };
-        if let Def::Fn(did) = def {
+        if let Def::Def(DefKind::Fn, did) = def {
             if self.def_id_is_transmute(did) {
                 let typ = self.tables.node_type(expr.hir_id);
                 let sig = typ.fn_sig(self.tcx);
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 34b44234279..21c7152ed7d 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -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, Def, DefKind, CtorKind};
 use crate::ty::adjustment;
 use crate::ty::{self, DefIdTree, Ty, TyCtxt};
 use crate::ty::fold::TypeFoldable;
@@ -699,12 +699,17 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                hir_id, expr_ty, def);
 
         match def {
-            Def::Ctor(..) | Def::Const(..) | Def::ConstParam(..) |
-            Def::AssociatedConst(..) | Def::Fn(..) | Def::Method(..) | Def::SelfCtor(..) => {
+            Def::Def(DefKind::Ctor(..), _)
+            | Def::Def(DefKind::Const, _)
+            | Def::Def(DefKind::ConstParam, _)
+            | Def::Def(DefKind::AssociatedConst, _)
+            | Def::Def(DefKind::Fn, _)
+            | Def::Def(DefKind::Method, _)
+            | Def::SelfCtor(..) => {
                 Ok(self.cat_rvalue_node(hir_id, span, expr_ty))
             }
 
-            Def::Static(def_id) => {
+            Def::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)[..]
@@ -1274,14 +1279,15 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                         debug!("access to unresolvable pattern {:?}", pat);
                         return Err(())
                     }
-                    Def::Ctor(variant_ctor_did, CtorOf::Variant, CtorKind::Fn) => {
+                    Def::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(..) => {
+                    Def::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), _)
+                    | Def::SelfCtor(..) => {
                         let ty = self.pat_ty_unadjusted(&pat)?;
                         match ty.sty {
                             ty::Adt(adt_def, _) => {
@@ -1316,11 +1322,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                         debug!("access to unresolvable pattern {:?}", pat);
                         return Err(())
                     }
-                    Def::Ctor(variant_ctor_did, CtorOf::Variant, _) => {
+                    Def::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) => {
+                    Def::Def(DefKind::Variant, variant_did) => {
                         self.cat_downcast_if_needed(pat, cmt, variant_did)
                     }
                     _ => cmt,
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 92266838dd8..8647820d574 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -7,7 +7,7 @@
 
 use crate::hir::{CodegenFnAttrs, CodegenFnAttrFlags};
 use crate::hir::Node;
-use crate::hir::def::Def;
+use crate::hir::def::{Def, DefKind};
 use crate::hir::def_id::{DefId, CrateNum};
 use rustc_data_structures::sync::Lrc;
 use crate::ty::{self, TyCtxt};
@@ -117,7 +117,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
                             // 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(..) => {
+                            Def::Def(DefKind::Const, _) | Def::Def(DefKind::AssociatedConst, _) => {
                                 self.worklist.push(hir_id);
                             }
 
@@ -357,7 +357,7 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a,
                 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,
+                    Def::Def(DefKind::Trait, def_id) => def_id,
                     _ => unreachable!()
                 };
 
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 814776c21bd..1e886c08d41 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -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::{Def, 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};
@@ -1365,7 +1365,7 @@ fn object_lifetime_defaults_for_item(
                         _ => continue,
                     };
 
-                    if def == Def::TyParam(param_def_id) {
+                    if def == Def::Def(DefKind::TyParam, param_def_id) {
                         add_bounds(&mut set, &data.bounds);
                     }
                 }
@@ -1929,13 +1929,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
         };
         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 =>
+            Def::Def(DefKind::AssociatedTy, def_id)
+                if depth == 1 => Some(parent_def_id(self, def_id)),
+            Def::Def(DefKind::Variant, def_id)
+                if depth == 0 => Some(parent_def_id(self, def_id)),
+            Def::Def(DefKind::Struct, def_id)
+            | Def::Def(DefKind::Union, def_id)
+            | Def::Def(DefKind::Enum, def_id)
+            | Def::Def(DefKind::TyAlias, def_id)
+            | Def::Def(DefKind::Trait, def_id) if depth == 0 =>
             {
                 Some(def_id)
             }
@@ -2139,7 +2141,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                         // 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(_) => {
+                        Def::Def(DefKind::Struct, _)
+                        | Def::Def(DefKind::Union, _)
+                        | Def::Def(DefKind::Enum, _)
+                        | Def::PrimTy(_) => {
                             return def == path.def
                         }
                         _ => {}
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 8ce86f70a55..e651e82d304 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -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::{Def, 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;
@@ -526,9 +526,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     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(_)) => {
+            Some(Def::Def(DefKind::Method, _)) |
+            Some(Def::Def(DefKind::AssociatedTy, _)) |
+            Some(Def::Def(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 Def::Def(DefKind::Trait, trait_did) = t.path.def {
                     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)
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index c07175d9451..48c3400c597 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -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::{Def, DefKind, Export};
 use crate::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
 use crate::hir::map as hir_map;
 use crate::hir::map::DefPathHash;
@@ -658,7 +658,7 @@ impl<'tcx> TypeckTables<'tcx> {
         }
 
         match self.type_dependent_defs().get(expr.hir_id) {
-            Some(&Def::Method(_)) => true,
+            Some(&Def::Def(DefKind::Method, _)) => true,
             _ => false
         }
     }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 36da21b71f5..3871b465cab 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -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::{Def, 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;
@@ -193,10 +193,10 @@ pub enum AssociatedKind {
 impl AssociatedItem {
     pub fn def(&self) -> Def {
         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 => Def::Def(DefKind::AssociatedConst, self.def_id),
+            AssociatedKind::Method => Def::Def(DefKind::Method, self.def_id),
+            AssociatedKind::Type => Def::Def(DefKind::AssociatedTy, self.def_id),
+            AssociatedKind::Existential => Def::Def(DefKind::AssociatedExistential, self.def_id),
         }
     }
 
@@ -2339,10 +2339,10 @@ impl<'a, 'gcx, 'tcx> AdtDef {
 
     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::Def(DefKind::Variant, vid) => self.variant_with_id(vid),
+            Def::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid),
+            Def::Def(DefKind::Struct, _) | Def::Def(DefKind::Union, _) |
+            Def::Def(DefKind::TyAlias, _) | Def::Def(DefKind::AssociatedTy, _) | Def::SelfTy(..) |
             Def::SelfCtor(..) => self.non_enum_variant(),
             _ => bug!("unexpected def {:?} in variant_of_def", def)
         }
@@ -2806,7 +2806,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             }
         } else {
             match self.describe_def(def_id).expect("no def for def-id") {
-                Def::AssociatedConst(_) | Def::Method(_) | Def::AssociatedTy(_) => true,
+                Def::Def(DefKind::AssociatedConst, _)
+                | Def::Def(DefKind::Method, _)
+                | Def::Def(DefKind::AssociatedTy, _) => true,
                 _ => false,
             }
         };
@@ -2952,19 +2954,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     /// or variant or their constructors, panics otherwise.
     pub fn expect_variant_def(self, def: Def) -> &'tcx VariantDef {
         match def {
-            Def::Variant(did) => {
+            Def::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) => {
+            Def::Def(DefKind::Struct, did) | Def::Def(DefKind::Union, did) => {
                 self.adt_def(did).non_enum_variant()
             }
-            Def::Ctor(variant_ctor_did, CtorOf::Variant, ..) => {
+            Def::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, ..) => {
+            Def::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()
             }
@@ -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(Def::Def(DefKind::Method, _)) = self.describe_def(def_id) {
                 Some(self.associated_item(def_id))
             } else {
                 None
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 47c1c16f1f8..8f583f3546b 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -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::{Def, DefKind};
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::ty::{self, Ty};
 use rustc::{lint, util};
@@ -916,7 +916,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
             } else {
                 return None;
             };
-            if let Def::Fn(did) = def {
+            if let Def::Def(DefKind::Fn, did) = def {
                 if !def_id_is_transmute(cx, did) {
                     return None;
                 }
@@ -1072,7 +1072,7 @@ impl TypeAliasBounds {
                 match ty.node {
                     hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => {
                         match path.def {
-                            Def::TyParam(_) => true,
+                            Def::Def(DefKind::TyParam, _) => true,
                             _ => false
                         }
                     }
diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs
index 1d8979f7d1c..7e6af43c500 100644
--- a/src/librustc_lint/nonstandard_style.rs
+++ b/src/librustc_lint/nonstandard_style.rs
@@ -1,5 +1,5 @@
 use rustc::hir::{self, GenericParamKind, PatKind};
-use rustc::hir::def::Def;
+use rustc::hir::def::{Def, 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 Def::Def(DefKind::Const, _) = path.def {
                 if path.segments.len() == 1 {
                     NonUpperCaseGlobals::check_upper_case(
                         cx,
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 043bc62ddce..9962caf0731 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -1,4 +1,4 @@
-use rustc::hir::def::Def;
+use rustc::hir::def::{Def, DefKind};
 use rustc::hir::def_id::DefId;
 use rustc::lint;
 use rustc::ty;
@@ -93,7 +93,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                     hir::ExprKind::Path(ref qpath) => {
                         let def = cx.tables.qpath_def(qpath, callee.hir_id);
                         match def {
-                            Def::Fn(_) | Def::Method(_) => Some(def),
+                            Def::Def(DefKind::Fn, _) | Def::Def(DefKind::Method, _) => Some(def),
                             // `Def::Local` if it was a closure, for which we
                             // do not currently support must-use linting
                             _ => None
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 0e3d05d29a3..cc7a72c7593 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -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, Def, DefKind, CtorOf, CtorKind};
 use rustc::hir::def_id::{CrateNum, DefId, DefIndex, DefIndexAddressSpace,
                          CRATE_DEF_INDEX, LOCAL_CRATE, LocalDefId};
 use rustc::hir::map::definitions::DefPathTable;
@@ -401,30 +401,30 @@ impl<'a, 'tcx> MetadataBlob {
 impl<'tcx> EntryKind<'tcx> {
     fn to_def(&self, did: DefId) -> Option<Def> {
         Some(match *self {
-            EntryKind::Const(..) => Def::Const(did),
-            EntryKind::AssociatedConst(..) => Def::AssociatedConst(did),
+            EntryKind::Const(..) => Def::Def(DefKind::Const, did),
+            EntryKind::AssociatedConst(..) => Def::Def(DefKind::AssociatedConst, did),
             EntryKind::ImmStatic |
             EntryKind::MutStatic |
             EntryKind::ForeignImmStatic |
-            EntryKind::ForeignMutStatic => Def::Static(did),
-            EntryKind::Struct(_, _) => Def::Struct(did),
-            EntryKind::Union(_, _) => Def::Union(did),
+            EntryKind::ForeignMutStatic => Def::Def(DefKind::Static, did),
+            EntryKind::Struct(_, _) => Def::Def(DefKind::Struct, did),
+            EntryKind::Union(_, _) => Def::Def(DefKind::Union, did),
             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(_) => Def::Def(DefKind::Fn, did),
+            EntryKind::Method(_) => Def::Def(DefKind::Method, did),
+            EntryKind::Type => Def::Def(DefKind::TyAlias, did),
+            EntryKind::TypeParam => Def::Def(DefKind::TyParam, did),
+            EntryKind::ConstParam => Def::Def(DefKind::ConstParam, did),
+            EntryKind::Existential => Def::Def(DefKind::Existential, did),
+            EntryKind::AssociatedType(_) => Def::Def(DefKind::AssociatedTy, did),
+            EntryKind::AssociatedExistential(_) => Def::Def(DefKind::AssociatedExistential, did),
+            EntryKind::Mod(_) => Def::Def(DefKind::Mod, did),
+            EntryKind::Variant(_) => Def::Def(DefKind::Variant, did),
+            EntryKind::Trait(_) => Def::Def(DefKind::Trait, did),
+            EntryKind::TraitAlias(_) => Def::Def(DefKind::TraitAlias, did),
+            EntryKind::Enum(..) => Def::Def(DefKind::Enum, did),
+            EntryKind::MacroDef(_) => Def::Def(DefKind::Macro(MacroKind::Bang), did),
+            EntryKind::ForeignType => Def::Def(DefKind::ForeignTy, did),
 
             EntryKind::ForeignMod |
             EntryKind::GlobalAsm |
@@ -512,7 +512,7 @@ impl<'a, 'tcx> CrateMetadata {
             self.entry(index).kind.to_def(self.local_def_id(index))
         } 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(Def::Def(DefKind::Macro(kind), self.local_def_id(index)))
         }
     }
 
@@ -743,12 +743,12 @@ impl<'a, 'tcx> CrateMetadata {
              */
             if id == CRATE_DEF_INDEX {
                 for (id, &(name, ref ext)) in proc_macros.iter().enumerate() {
-                    let def = Def::Macro(
+                    let def = Def::Def(
+                        DefKind::Macro(ext.kind()),
                         DefId {
                             krate: self.cnum,
                             index: DefIndex::from_proc_macro_index(id),
                         },
-                        ext.kind()
                     );
                     let ident = Ident::with_empty_ctxt(name);
                     callback(def::Export {
@@ -815,22 +815,28 @@ impl<'a, 'tcx> CrateMetadata {
                     // For non-re-export structs and variants add their constructors to children.
                     // Re-export lists automatically contain constructors when necessary.
                     match def {
-                        Def::Struct(..) => {
+                        Def::Def(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_def = Def::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 });
                             }
                         }
-                        Def::Variant(def_id) => {
+                        Def::Def(DefKind::Variant, def_id) => {
                             // 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_def = Def::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
@@ -854,7 +860,7 @@ 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(..) => {}
+                    Def::Def(DefKind::Macro(..), _) => {}
                     _ if macros_only => continue,
                     _ => {}
                 }
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
index f9b571a7d60..4a636fa87c6 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
@@ -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::{Def, DefKind};
 use rustc::hir::def_id::DefId;
 use rustc::infer::InferCtxt;
 use rustc::mir::Mir;
@@ -496,7 +497,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                         // 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(_) => (),
+                        Def::Def(DefKind::TyAlias, _) => (),
                         _ => if let Some(last_segment) = path.segments.last() {
                             if let Some(name) = self.match_adt_and_segment(
                                 substs,
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 681a204d76e..f4c7b40647c 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -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::{Def, DefKind};
 use rustc::hir::def_id::DefId;
 use rustc::mir::interpret::{ConstEvalErr, ErrorHandled};
 use rustc::mir;
@@ -641,7 +641,7 @@ pub fn const_eval_raw_provider<'a, 'tcx>(
                 // 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(Def::Def(DefKind::Const, _)) | Some(Def::Def(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)),
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 6e11f1dae9b..b1c3cdc9dc8 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -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, Def, DefKind, CtorKind};
 use rustc::mir::interpret::{GlobalId, ErrorHandled, ConstValue};
 use rustc::ty::{self, AdtKind, Ty};
 use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability, PointerCast};
@@ -250,7 +250,7 @@ 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) =>
+                            Def::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))),
                             _ => None,
@@ -470,7 +470,7 @@ 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) => {
+                                Def::Def(DefKind::Variant, variant_id) => {
                                     assert!(base.is_none());
 
                                     let index = adt.variant_index_with_id(variant_id);
@@ -664,7 +664,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                         .ty_adt_def()
                         .and_then(|adt_def| {
                         match def {
-                            Def::Ctor(variant_ctor_id, CtorOf::Variant, CtorKind::Const) => {
+                            Def::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;
@@ -792,17 +795,18 @@ fn user_substs_applied_to_def(
         // 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),
+        Def::Def(DefKind::Fn, _) |
+        Def::Def(DefKind::Method, _) |
+        Def::Def(DefKind::Ctor(_, CtorKind::Fn), _) |
+        Def::Def(DefKind::Const, _) |
+        Def::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) =>
+        Def::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
@@ -895,9 +899,9 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
     let substs = cx.tables().node_substs(expr.hir_id);
     match def {
         // A regular function, constructor function or a constant.
-        Def::Fn(_) |
-        Def::Method(_) |
-        Def::Ctor(_, _, CtorKind::Fn) |
+        Def::Def(DefKind::Fn, _) |
+        Def::Def(DefKind::Method, _) |
+        Def::Def(DefKind::Ctor(_, CtorKind::Fn), _) |
         Def::SelfCtor(..) => {
             let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def);
             debug!("convert_path_expr: user_ty={:?}", user_ty);
@@ -909,7 +913,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             }
         }
 
-        Def::ConstParam(def_id) => {
+        Def::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,8 +932,8 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             }
         }
 
-        Def::Const(def_id) |
-        Def::AssociatedConst(def_id) => {
+        Def::Def(DefKind::Const, def_id) |
+        Def::Def(DefKind::AssociatedConst, def_id) => {
             let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def);
             debug!("convert_path_expr: (const) user_ty={:?}", user_ty);
             ExprKind::Literal {
@@ -941,7 +945,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             }
         },
 
-        Def::Ctor(def_id, _, CtorKind::Const) => {
+        Def::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,7 +967,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             }
         }
 
-        Def::Static(id) => ExprKind::StaticRef { id },
+        Def::Def(DefKind::Static, id) => ExprKind::StaticRef { id },
 
         Def::Local(..) | Def::Upvar(..) => convert_var(cx, expr, def),
 
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index e354ec3e0ba..90551d8d167 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -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, Def, DefKind, CtorKind};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
 
 use rustc_data_structures::indexed_vec::Idx;
@@ -733,15 +733,15 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
         subpatterns: Vec<FieldPattern<'tcx>>,
     ) -> PatternKind<'tcx> {
         let def = match def {
-            Def::Ctor(variant_ctor_id, CtorOf::Variant, ..) => {
+            Def::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => {
                 let variant_id = self.tcx.parent(variant_ctor_id).unwrap();
-                Def::Variant(variant_id)
+                Def::Def(DefKind::Variant, variant_id)
             },
             def => def,
         };
 
         let mut kind = match def {
-            Def::Variant(variant_id) => {
+            Def::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(..) => {
+            Def::Def(DefKind::Struct, _)
+            | Def::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
+            | Def::Def(DefKind::Union, _)
+            | Def::Def(DefKind::TyAlias, _)
+            | Def::Def(DefKind::AssociatedTy, _)
+            | Def::SelfTy(..)
+            | Def::SelfCtor(..) => {
                 PatternKind::Leaf { subpatterns }
             }
 
@@ -805,11 +810,11 @@ impl<'a, 'tcx> PatternContext<'a, '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,
+            Def::Def(DefKind::AssociatedConst, _) => true,
             _ => false,
         };
         let kind = match def {
-            Def::Const(def_id) | Def::AssociatedConst(def_id) => {
+            Def::Def(DefKind::Const, def_id) | Def::Def(DefKind::AssociatedConst, def_id) => {
                 let substs = self.tables.node_substs(id);
                 match ty::Instance::resolve(
                     self.tcx,
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 4ae8bfe854d..7a8530b31ce 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -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::{Def, DefKind};
 use rustc::mir;
 use rustc::ty::layout::{
     self, Size, Align, HasDataLayout, LayoutOf, TyLayout
@@ -503,7 +503,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
             // Now mark those locals as dead that we do not want to initialize
             match self.tcx.describe_def(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(Def::Def(DefKind::Static, _))
+                | Some(Def::Def(DefKind::Const, _))
+                | Some(Def::Def(DefKind::AssociatedConst, _)) => {},
                 _ => {
                     trace!("push_stack_frame: {:?}: num_bbs: {}", span, mir.basic_blocks().len());
                     for block in mir.basic_blocks() {
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 2d89f73a95f..a114c18ace8 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -1,7 +1,7 @@
 //! Propagates constants for early reporting of statically known
 //! assertion failures
 
-use rustc::hir::def::Def;
+use rustc::hir::def::{Def, DefKind};
 use rustc::mir::{
     Constant, Location, Place, PlaceBase, Mir, Operand, Rvalue, Local,
     NullOp, UnOp, StatementKind, Statement, LocalKind, Static, StaticKind,
@@ -43,7 +43,7 @@ impl MirPass for ConstProp {
 
         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,
+            Some(Def::Def(DefKind::AssociatedConst, _)) => true,
             _ => false,
         };
 
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index 6c377684bee..790d3c6624a 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -575,19 +575,22 @@ fn write_mir_sig(
     mir: &Mir<'_>,
     w: &mut dyn Write,
 ) -> io::Result<()> {
-    use rustc::hir::def::Def;
+    use rustc::hir::def::{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,
+        Some(Def::Def(DefKind::Fn, _))
+        | Some(Def::Def(DefKind::Method, _))
+        | Some(Def::Def(DefKind::Ctor(..), _)) => true,
         _ => tcx.is_closure(src.def_id()),
     };
     match (descr, 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(Def::Def(DefKind::Const, _)), _)
+        | (Some(Def::Def(DefKind::AssociatedConst, _)), _) => write!(w, "const ")?,
+        (Some(Def::Def(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),
diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs
index 881f63e994d..57cea198c72 100644
--- a/src/librustc_passes/rvalue_promotion.rs
+++ b/src/librustc_passes/rvalue_promotion.rs
@@ -15,7 +15,7 @@
 // by borrowck::gather_loans
 
 use rustc::ty::cast::CastTy;
-use rustc::hir::def::{Def, CtorKind};
+use rustc::hir::def::{Def, DefKind, CtorKind};
 use rustc::hir::def_id::DefId;
 use rustc::middle::expr_use_visitor as euv;
 use rustc::middle::mem_categorization as mc;
@@ -321,14 +321,17 @@ 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(..) =>
+                Def::Def(DefKind::Ctor(..), _)
+                | Def::Def(DefKind::Fn, _)
+                | Def::Def(DefKind::Method, _)
+                | Def::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) => {
+                Def::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) => {
+                Def::Def(DefKind::Const, did) |
+                Def::Def(DefKind::AssociatedConst, did) => {
                     let promotable = if v.tcx.trait_of_item(did).is_some() {
                         // Don't peek inside trait associated constants.
                         NotPromotable
@@ -386,10 +389,10 @@ fn check_expr_kind<'a, 'tcx>(
                 Def::Err
             };
             let def_result = match def {
-                Def::Ctor(_, _, CtorKind::Fn) |
+                Def::Def(DefKind::Ctor(_, CtorKind::Fn), _) |
                 Def::SelfCtor(..) => Promotable,
-                Def::Fn(did) => v.handle_const_fn_call(did),
-                Def::Method(did) => {
+                Def::Def(DefKind::Fn, did) => v.handle_const_fn_call(did),
+                Def::Def(DefKind::Method, did) => {
                     match v.tcx.associated_item(did).container {
                         ty::ImplContainer(_) => v.handle_const_fn_call(did),
                         ty::TraitContainer(_) => NotPromotable,
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 702b6200a16..b971de06bbf 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -12,7 +12,7 @@
 
 use rustc::bug;
 use rustc::hir::{self, Node, PatKind, AssociatedItemKind};
-use rustc::hir::def::Def;
+use rustc::hir::def::{Def, 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;
@@ -1107,9 +1107,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
     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),
+                Def::Def(DefKind::Method, _) | Def::Def(DefKind::AssociatedConst, _) |
+                Def::Def(DefKind::AssociatedTy, _) | Def::Def(DefKind::AssociatedExistential, _) |
+                Def::Def(DefKind::Static, _) => Some(path.def),
                 _ => None,
             }
             hir::QPath::TypeRelative(..) => {
@@ -1118,7 +1118,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
         };
         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 is_local_static = if let Def::Def(DefKind::Static, _) = def {
+                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(),
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 6870e97b53b..5c7e51d4057 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -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(Def::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,29 +443,32 @@ impl<'a> Resolver<'a> {
 
             // These items live in the value namespace.
             ItemKind::Static(..) => {
-                let def = Def::Static(self.definitions.local_def_id(item.id));
+                let def = Def::Def(DefKind::Static, self.definitions.local_def_id(item.id));
                 self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
             }
             ItemKind::Const(..) => {
-                let def = Def::Const(self.definitions.local_def_id(item.id));
+                let def = Def::Def(DefKind::Const, self.definitions.local_def_id(item.id));
                 self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
             }
             ItemKind::Fn(..) => {
-                let def = Def::Fn(self.definitions.local_def_id(item.id));
+                let def = Def::Def(DefKind::Fn, self.definitions.local_def_id(item.id));
                 self.define(parent, ident, ValueNS, (def, 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);
+                    let def = Def::Def(DefKind::Macro(MacroKind::ProcMacroStub), def.def_id());
                     self.define(parent, ident, MacroNS, (def, 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);
+                            let def = Def::Def(
+                                DefKind::Macro(MacroKind::ProcMacroStub),
+                                def.def_id(),
+                            );
                             self.define(parent, ident, MacroNS, (def, vis, ident.span, expansion));
                         }
                     }
@@ -474,17 +477,17 @@ impl<'a> Resolver<'a> {
 
             // These items live in the type namespace.
             ItemKind::Ty(..) => {
-                let def = Def::TyAlias(self.definitions.local_def_id(item.id));
+                let def = Def::Def(DefKind::TyAlias, self.definitions.local_def_id(item.id));
                 self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
             }
 
             ItemKind::Existential(_, _) => {
-                let def = Def::Existential(self.definitions.local_def_id(item.id));
+                let def = Def::Def(DefKind::Existential, self.definitions.local_def_id(item.id));
                 self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
             }
 
             ItemKind::Enum(ref enum_definition, _) => {
-                let def = Def::Enum(self.definitions.local_def_id(item.id));
+                let def = Def::Def(DefKind::Enum, self.definitions.local_def_id(item.id));
                 let module_kind = ModuleKind::Def(def, ident.name);
                 let module = self.new_module(parent,
                                              module_kind,
@@ -499,7 +502,7 @@ impl<'a> Resolver<'a> {
             }
 
             ItemKind::TraitAlias(..) => {
-                let def = Def::TraitAlias(self.definitions.local_def_id(item.id));
+                let def = Def::Def(DefKind::TraitAlias, self.definitions.local_def_id(item.id));
                 self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
             }
 
@@ -507,7 +510,7 @@ impl<'a> Resolver<'a> {
             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);
+                let def = Def::Def(DefKind::Struct, def_id);
                 self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
 
                 let mut ctor_vis = vis;
@@ -534,16 +537,17 @@ 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));
+                    let ctor_def = Def::Def(
+                        DefKind::Ctor(CtorOf::Struct, CtorKind::from_ast(struct_def)),
+                        self.definitions.local_def_id(ctor_node_id),
+                    );
                     self.define(parent, ident, ValueNS, (ctor_def, ctor_vis, sp, expansion));
                     self.struct_constructors.insert(def.def_id(), (ctor_def, ctor_vis));
                 }
             }
 
             ItemKind::Union(ref vdata, _) => {
-                let def = Def::Union(self.definitions.local_def_id(item.id));
+                let def = Def::Def(DefKind::Union, self.definitions.local_def_id(item.id));
                 self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
 
                 // Record field names for error reporting.
@@ -561,7 +565,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(Def::Def(DefKind::Trait, def_id), ident.name);
                 let module = self.new_module(parent,
                                              module_kind,
                                              parent.normal_ancestor_id,
@@ -586,7 +590,7 @@ 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);
+        let def = Def::Def(DefKind::Variant, def_id);
         self.define(parent, ident, TypeNS, (def, vis, variant.span, expansion));
 
         // If the variant is marked as non_exhaustive then lower the visibility to within the
@@ -605,7 +609,7 @@ 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);
+        let ctor_def = Def::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
         self.define(parent, ident, ValueNS, (ctor_def, ctor_vis, variant.span, expansion));
     }
 
@@ -613,13 +617,13 @@ impl<'a> Resolver<'a> {
     fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, expansion: Mark) {
         let (def, ns) = match item.node {
             ForeignItemKind::Fn(..) => {
-                (Def::Fn(self.definitions.local_def_id(item.id)), ValueNS)
+                (Def::Def(DefKind::Fn, self.definitions.local_def_id(item.id)), ValueNS)
             }
             ForeignItemKind::Static(..) => {
-                (Def::Static(self.definitions.local_def_id(item.id)), ValueNS)
+                (Def::Def(DefKind::Static, self.definitions.local_def_id(item.id)), ValueNS)
             }
             ForeignItemKind::Ty => {
-                (Def::ForeignTy(self.definitions.local_def_id(item.id)), TypeNS)
+                (Def::Def(DefKind::ForeignTy, self.definitions.local_def_id(item.id)), TypeNS)
             }
             ForeignItemKind::Macro(_) => unreachable!(),
         };
@@ -654,7 +658,7 @@ impl<'a> Resolver<'a> {
         let ident = ident.gensym_if_underscore();
         let expansion = Mark::root(); // FIXME(jseyfried) intercrate hygiene
         match def {
-            Def::Mod(def_id) | Def::Enum(def_id) => {
+            Def::Def(DefKind::Mod, def_id) | Def::Def(DefKind::Enum, def_id) => {
                 let module = self.new_module(parent,
                                              ModuleKind::Def(def, ident.name),
                                              def_id,
@@ -662,15 +666,22 @@ impl<'a> Resolver<'a> {
                                              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 => {
+            Def::Def(DefKind::Variant, _)
+            | Def::Def(DefKind::TyAlias, _)
+            | Def::Def(DefKind::ForeignTy, _)
+            | Def::Def(DefKind::Existential, _)
+            | Def::Def(DefKind::TraitAlias, _)
+            | Def::PrimTy(..)
+            | Def::ToolMod => {
                 self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
             }
-            Def::Fn(..) | Def::Static(..) | Def::Const(..) |
-            Def::Ctor(_, CtorOf::Variant, ..) => {
+            Def::Def(DefKind::Fn, _)
+            | Def::Def(DefKind::Static, _)
+            | Def::Def(DefKind::Const, _)
+            | Def::Def(DefKind::Ctor(CtorOf::Variant, ..), _) => {
                 self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion));
             }
-            Def::Ctor(def_id, CtorOf::Struct, ..) => {
+            Def::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) => {
                 self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion));
 
                 if let Some(struct_def_id) =
@@ -679,7 +690,7 @@ impl<'a> Resolver<'a> {
                     self.struct_constructors.insert(struct_def_id, (def, vis));
                 }
             }
-            Def::Trait(def_id) => {
+            Def::Def(DefKind::Trait, def_id) => {
                 let module_kind = ModuleKind::Def(def, ident.name);
                 let module = self.new_module(parent,
                                              module_kind,
@@ -690,7 +701,9 @@ impl<'a> Resolver<'a> {
 
                 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 ns = if let Def::Def(DefKind::AssociatedTy, _) = def {
+                        TypeNS
+                    } else { ValueNS };
                     self.define(module, child.ident, ns,
                                 (def, ty::Visibility::Public, DUMMY_SP, expansion));
 
@@ -701,14 +714,14 @@ impl<'a> Resolver<'a> {
                 }
                 module.populated.set(true);
             }
-            Def::Struct(def_id) | Def::Union(def_id) => {
+            Def::Def(DefKind::Struct, def_id) | Def::Def(DefKind::Union, def_id) => {
                 self.define(parent, ident, TypeNS, (def, 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(..) => {
+            Def::Def(DefKind::Macro(..), _) | Def::NonMacroAttr(..) => {
                 self.define(parent, ident, MacroNS, (def, vis, DUMMY_SP, expansion));
             }
             _ => bug!("unexpected definition: {:?}", def)
@@ -733,7 +746,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(Def::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);
@@ -754,11 +767,11 @@ 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::Def(DefKind::Macro(..), def_id) => def_id,
             Def::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 `Def::NonMacroAttr`"),
         };
         if let Some(ext) = self.macro_map.get(&def_id) {
             return ext.clone();
@@ -1016,14 +1029,14 @@ 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),
+            TraitItemKind::Const(..) => (Def::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)
+                (Def::Def(DefKind::Method, item_def_id), ValueNS)
             }
-            TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS),
+            TraitItemKind::Type(..) => (Def::Def(DefKind::AssociatedTy, item_def_id), TypeNS),
             TraitItemKind::Macro(_) => bug!(),  // handled above
         };
 
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index c89c222ad57..a86319801dc 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -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};
@@ -31,7 +31,9 @@ impl<'a> Resolver<'a> {
         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_enum_variant = &|def| {
+            if let Def::Def(DefKind::Variant, _) = def { true } else { false }
+        };
 
         // Make the base error.
         let expected = source.descr_expected();
@@ -117,7 +119,8 @@ impl<'a> Resolver<'a> {
                 }
             })
             .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(Def::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()
@@ -362,7 +365,7 @@ impl<'a> Resolver<'a> {
         };
 
         match (def, source) {
-            (Def::Macro(..), _) => {
+            (Def::Def(DefKind::Macro(..), _), _) => {
                 err.span_suggestion(
                     span,
                     "use `!` to invoke the macro",
@@ -373,17 +376,19 @@ impl<'a> Resolver<'a> {
                     err.note("if you want the `try` keyword, you need to be in the 2018 edition");
                 }
             }
-            (Def::TyAlias(..), PathSource::Trait(_)) => {
+            (Def::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(..))  => {
+            (Def::Def(DefKind::Mod, _), PathSource::Expr(Some(parent))) => {
+                if !path_sep(err, &parent) {
+                    return false;
+                }
+            }
+            (Def::Def(DefKind::Enum, _), PathSource::TupleStruct)
+                | (Def::Def(DefKind::Enum, _), PathSource::Expr(..))  => {
                 if let Some(variants) = self.collect_enum_variants(def) {
                     if !variants.is_empty() {
                         let msg = if variants.len() == 1 {
@@ -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 => {
+            (Def::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 => {
+            (Def::Def(DefKind::Union, _), _) |
+            (Def::Def(DefKind::Variant, _), _) |
+            (Def::Def(DefKind::Ctor(_, CtorKind::Fictive), _), _) if ns == ValueNS => {
                 bad_struct_syntax_suggestion();
             }
             (Def::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 => {
+            (Def::Def(DefKind::TyAlias, _), _)
+            | (Def::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 Def::Def(DefKind::Macro(MacroKind::Bang), _) = binding.def() {
             let module_name = crate_module.kind.name().unwrap();
             let import = match directive.subclass {
                 ImportDirectiveSubclass::SingleImport { source, target, .. } if source != target =>
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index dcfe00069c5..f7b8103a521 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -24,7 +24,7 @@ use rustc::middle::cstore::CrateStore;
 use rustc::session::Session;
 use rustc::lint;
 use rustc::hir::def::{
-    self, PathResolution, CtorKind, CtorOf, NonMacroAttrKind, DefMap, ImportMap, ExportMap
+    self, DefKind, PathResolution, CtorKind, CtorOf, NonMacroAttrKind, DefMap, ImportMap, ExportMap
 };
 use rustc::hir::def::Namespace::*;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
@@ -236,19 +236,19 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
                     }
                     return err;
                 },
-                Def::TyParam(def_id) => {
+                Def::Def(DefKind::TyParam, def_id) => {
                     if let Some(span) = resolver.definitions.opt_span(def_id) {
                         err.span_label(span, "type parameter from outer function");
                     }
                 }
-                Def::ConstParam(def_id) => {
+                Def::Def(DefKind::ConstParam, def_id) => {
                     if let Some(span) = resolver.definitions.opt_span(def_id) {
                         err.span_label(span, "const parameter from outer function");
                     }
                 }
                 _ => {
                     bug!("GenericParamsFromOuterFunction should only be used with Def::SelfTy, \
-                         Def::TyParam");
+                         DefKind::TyParam");
                 }
             }
 
@@ -570,7 +570,7 @@ impl<'a> PathSource<'a> {
                 MacroNS => bug!("associated macro"),
             },
             PathSource::Expr(parent) => match parent.map(|p| &p.node) {
-                // "function" here means "anything callable" rather than `Def::Fn`,
+                // "function" here means "anything callable" rather than `DefKind::Fn`,
                 // this is not precise but usually more helpful than just "value".
                 Some(&ExprKind::Call(..)) => "function",
                 _ => "value",
@@ -581,50 +581,70 @@ impl<'a> PathSource<'a> {
     fn is_expected(self, def: Def) -> bool {
         match self {
             PathSource::Type => match def {
-                Def::Struct(..) | Def::Union(..) | Def::Enum(..) |
-                Def::Trait(..) | Def::TraitAlias(..) | Def::TyAlias(..) |
-                Def::AssociatedTy(..) | Def::PrimTy(..) | Def::TyParam(..) |
-                Def::SelfTy(..) | Def::Existential(..) | Def::ForeignTy(..) => true,
+                Def::Def(DefKind::Struct, _)
+                | Def::Def(DefKind::Union, _)
+                | Def::Def(DefKind::Enum, _)
+                | Def::Def(DefKind::Trait, _)
+                | Def::Def(DefKind::TraitAlias, _)
+                | Def::Def(DefKind::TyAlias, _)
+                | Def::Def(DefKind::AssociatedTy, _)
+                | Def::PrimTy(..)
+                | Def::Def(DefKind::TyParam, _)
+                | Def::SelfTy(..)
+                | Def::Def(DefKind::Existential, _)
+                | Def::Def(DefKind::ForeignTy, _) => true,
                 _ => false,
             },
             PathSource::Trait(AliasPossibility::No) => match def {
-                Def::Trait(..) => true,
+                Def::Def(DefKind::Trait, _) => true,
                 _ => false,
             },
             PathSource::Trait(AliasPossibility::Maybe) => match def {
-                Def::Trait(..) => true,
-                Def::TraitAlias(..) => true,
+                Def::Def(DefKind::Trait, _) => true,
+                Def::Def(DefKind::TraitAlias, _) => true,
                 _ => false,
             },
             PathSource::Expr(..) => match def {
-                Def::Ctor(_, _, CtorKind::Const) | Def::Ctor(_, _, CtorKind::Fn) |
-                Def::Const(..) | Def::Static(..) | Def::Local(..) | Def::Upvar(..) |
-                Def::Fn(..) | Def::Method(..) | Def::AssociatedConst(..) |
-                Def::SelfCtor(..) | Def::ConstParam(..) => true,
+                Def::Def(DefKind::Ctor(_, CtorKind::Const), _)
+                | Def::Def(DefKind::Ctor(_, CtorKind::Fn), _)
+                | Def::Def(DefKind::Const, _)
+                | Def::Def(DefKind::Static, _)
+                | Def::Local(..)
+                | Def::Upvar(..)
+                | Def::Def(DefKind::Fn, _)
+                | Def::Def(DefKind::Method, _)
+                | Def::Def(DefKind::AssociatedConst, _)
+                | Def::SelfCtor(..)
+                | Def::Def(DefKind::ConstParam, _) => true,
                 _ => false,
             },
             PathSource::Pat => match def {
-                Def::Ctor(_, _, CtorKind::Const) |
-                Def::Const(..) | Def::AssociatedConst(..) |
+                Def::Def(DefKind::Ctor(_, CtorKind::Const), _) |
+                Def::Def(DefKind::Const, _) | Def::Def(DefKind::AssociatedConst, _) |
                 Def::SelfCtor(..) => true,
                 _ => false,
             },
             PathSource::TupleStruct => match def {
-                Def::Ctor(_, _, CtorKind::Fn) | Def::SelfCtor(..) => true,
+                Def::Def(DefKind::Ctor(_, CtorKind::Fn), _) | Def::SelfCtor(..) => true,
                 _ => false,
             },
             PathSource::Struct => match def {
-                Def::Struct(..) | Def::Union(..) | Def::Variant(..) |
-                Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => true,
+                Def::Def(DefKind::Struct, _)
+                | Def::Def(DefKind::Union, _)
+                | Def::Def(DefKind::Variant, _)
+                | Def::Def(DefKind::TyAlias, _)
+                | Def::Def(DefKind::AssociatedTy, _)
+                | Def::SelfTy(..) => true,
                 _ => false,
             },
             PathSource::TraitItem(ns) => match def {
-                Def::AssociatedConst(..) | Def::Method(..) if ns == ValueNS => true,
-                Def::AssociatedTy(..) if ns == TypeNS => true,
+                Def::Def(DefKind::AssociatedConst, _)
+                | Def::Def(DefKind::Method, _) if ns == ValueNS => true,
+                Def::Def(DefKind::AssociatedTy, _) if ns == TypeNS => true,
                 _ => false,
             },
             PathSource::Visibility => match def {
-                Def::Mod(..) => true,
+                Def::Def(DefKind::Mod, _) => true,
                 _ => false,
             },
         }
@@ -1263,14 +1283,14 @@ impl<'a> ModuleData<'a> {
     // `self` resolves to the first module ancestor that `is_normal`.
     fn is_normal(&self) -> bool {
         match self.kind {
-            ModuleKind::Def(Def::Mod(_), _) => true,
+            ModuleKind::Def(Def::Def(DefKind::Mod, _), _) => true,
             _ => false,
         }
     }
 
     fn is_trait(&self) -> bool {
         match self.kind {
-            ModuleKind::Def(Def::Trait(_), _) => true,
+            ModuleKind::Def(Def::Def(DefKind::Trait, _), _) => true,
             _ => false,
         }
     }
@@ -1443,8 +1463,8 @@ impl<'a> NameBinding<'a> {
 
     fn is_variant(&self) -> bool {
         match self.kind {
-            NameBindingKind::Def(Def::Variant(..), _) |
-            NameBindingKind::Def(Def::Ctor(_, CtorOf::Variant, ..), _) => true,
+            NameBindingKind::Def(Def::Def(DefKind::Variant, _), _) |
+            NameBindingKind::Def(Def::Def(DefKind::Ctor(CtorOf::Variant, ..), _), _) => true,
             _ => false,
         }
     }
@@ -1457,7 +1477,7 @@ impl<'a> NameBinding<'a> {
                 }, ..
             } => true,
             NameBindingKind::Module(
-                &ModuleData { kind: ModuleKind::Def(Def::Mod(def_id), _), .. }
+                &ModuleData { kind: ModuleKind::Def(Def::Def(DefKind::Mod, def_id), _), .. }
             ) => def_id.index == CRATE_DEF_INDEX,
             _ => false,
         }
@@ -1479,21 +1499,23 @@ impl<'a> NameBinding<'a> {
 
     fn is_importable(&self) -> bool {
         match self.def() {
-            Def::AssociatedConst(..) | Def::Method(..) | Def::AssociatedTy(..) => false,
+            Def::Def(DefKind::AssociatedConst, _)
+            | Def::Def(DefKind::Method, _)
+            | Def::Def(DefKind::AssociatedTy, _) => false,
             _ => true,
         }
     }
 
     fn is_macro_def(&self) -> bool {
         match self.kind {
-            NameBindingKind::Def(Def::Macro(..), _) => true,
+            NameBindingKind::Def(Def::Def(DefKind::Macro(..), _), _) => true,
             _ => false,
         }
     }
 
     fn macro_kind(&self) -> Option<MacroKind> {
         match self.def() {
-            Def::Macro(_, kind) => Some(kind),
+            Def::Def(DefKind::Macro(kind), _) => Some(kind),
             Def::NonMacroAttr(..) => Some(MacroKind::Attr),
             _ => None,
         }
@@ -1915,7 +1937,10 @@ impl<'a> Resolver<'a> {
                arenas: &'a ResolverArenas<'a>)
                -> Resolver<'a> {
         let root_def_id = DefId::local(CRATE_DEF_INDEX);
-        let root_module_kind = ModuleKind::Def(Def::Mod(root_def_id), keywords::Invalid.name());
+        let root_module_kind = ModuleKind::Def(
+            Def::Def(DefKind::Mod, root_def_id),
+            keywords::Invalid.name(),
+        );
         let graph_root = arenas.alloc_module(ModuleData {
             no_implicit_prelude: attr::contains_name(&krate.attrs, "no_implicit_prelude"),
             ..ModuleData::new(None, root_module_kind, root_def_id, Mark::root(), krate.span)
@@ -2663,8 +2688,11 @@ impl<'a> Resolver<'a> {
                             }
                             seen_bindings.entry(ident).or_insert(param.ident.span);
 
-                        // Plain insert (no renaming).
-                        let def = Def::TyParam(self.definitions.local_def_id(param.id));
+                            // Plain insert (no renaming).
+                            let def = Def::Def(
+                                DefKind::TyParam,
+                                self.definitions.local_def_id(param.id),
+                            );
                             function_type_rib.bindings.insert(ident, def);
                             self.record_def(param.id, PathResolution::new(def));
                         }
@@ -2682,7 +2710,10 @@ impl<'a> Resolver<'a> {
                             }
                             seen_bindings.entry(ident).or_insert(param.ident.span);
 
-                            let def = Def::ConstParam(self.definitions.local_def_id(param.id));
+                            let def = Def::Def(
+                                DefKind::ConstParam,
+                                self.definitions.local_def_id(param.id),
+                            );
                             function_value_rib.bindings.insert(ident, def);
                             self.record_def(param.id, PathResolution::new(def));
                         }
@@ -3175,14 +3206,16 @@ impl<'a> Resolver<'a> {
                         let is_syntactic_ambiguity = opt_pat.is_none() &&
                             bmode == BindingMode::ByValue(Mutability::Immutable);
                         match def {
-                            Def::Ctor(_, _, CtorKind::Const) |
-                            Def::Const(..) if is_syntactic_ambiguity => {
+                            Def::Def(DefKind::Ctor(_, CtorKind::Const), _) |
+                            Def::Def(DefKind::Const, _) if is_syntactic_ambiguity => {
                                 // Disambiguate in favor of a unit struct/variant
                                 // or constant pattern.
                                 self.record_use(ident, ValueNS, binding.unwrap(), false);
                                 Some(PathResolution::new(def))
                             }
-                            Def::Ctor(..) | Def::Const(..) | Def::Static(..) => {
+                            Def::Def(DefKind::Ctor(..), _)
+                            | Def::Def(DefKind::Const, _)
+                            | Def::Def(DefKind::Static, _) => {
                                 // This is unambiguously a fresh binding, either syntactically
                                 // (e.g., `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
                                 // to something unusable as a pattern (e.g., constructor function),
@@ -3196,7 +3229,7 @@ impl<'a> Resolver<'a> {
                                 );
                                 None
                             }
-                            Def::Fn(..) | Def::Err => {
+                            Def::Def(DefKind::Fn, _) | Def::Err => {
                                 // These entities are explicitly allowed
                                 // to be shadowed by fresh bindings.
                                 None
@@ -3310,7 +3343,7 @@ impl<'a> Resolver<'a> {
                     // Add a temporary hack to smooth the transition to new struct ctor
                     // visibility rules. See #38932 for more details.
                     let mut res = None;
-                    if let Def::Struct(def_id) = resolution.base_def() {
+                    if let Def::Def(DefKind::Struct, def_id) = resolution.base_def() {
                         if let Some((ctor_def, ctor_vis))
                                 = self.struct_constructors.get(&def_id).cloned() {
                             if is_expected(ctor_def) && self.is_accessible(ctor_vis) {
@@ -3501,9 +3534,10 @@ impl<'a> Resolver<'a> {
             self.macro_use_prelude.get(&path[0].ident.name).cloned()
                                   .and_then(NameBinding::macro_kind) == Some(MacroKind::Bang)) {
             // Return some dummy definition, it's enough for error reporting.
-            return Some(
-                PathResolution::new(Def::Macro(DefId::local(CRATE_DEF_INDEX), MacroKind::Bang))
-            );
+            return Some(PathResolution::new(Def::Def(
+                DefKind::Macro(MacroKind::Bang),
+                DefId::local(CRATE_DEF_INDEX),
+            )));
         }
         fin_res
     }
@@ -3536,7 +3570,7 @@ impl<'a> Resolver<'a> {
                 // trait to resolve.  In that case, we leave the `B`
                 // segment to be resolved by type-check.
                 return Some(PathResolution::with_unresolved_segments(
-                    Def::Mod(DefId::local(CRATE_DEF_INDEX)), path.len()
+                    Def::Def(DefKind::Mod, DefId::local(CRATE_DEF_INDEX)), path.len()
                 ));
             }
 
@@ -3862,7 +3896,9 @@ impl<'a> Resolver<'a> {
                         _ => None,
                     };
                     let (label, suggestion) = if module_def == self.graph_root.def() {
-                        let is_mod = |def| match def { Def::Mod(..) => true, _ => false };
+                        let is_mod = |def| {
+                            match def { Def::Def(DefKind::Mod, _) => true, _ => false }
+                        };
                         let mut candidates =
                             self.lookup_import_candidates(ident, TypeNS, is_mod);
                         candidates.sort_by_cached_key(|c| {
@@ -4059,7 +4095,7 @@ impl<'a> Resolver<'a> {
                      return Def::Err;
                 }
             }
-            Def::TyParam(..) | Def::SelfTy(..) => {
+            Def::Def(DefKind::TyParam, _) | Def::SelfTy(..) => {
                 for rib in ribs {
                     match rib.kind {
                         NormalRibKind | TraitOrImplItemRibKind | ClosureRibKind(..) |
@@ -4081,7 +4117,7 @@ impl<'a> Resolver<'a> {
                     }
                 }
             }
-            Def::ConstParam(..) => {
+            Def::Def(DefKind::ConstParam, _) => {
                 let mut ribs = ribs.iter().peekable();
                 if let Some(Rib { kind: FnItemRibKind, .. }) = ribs.peek() {
                     // When declaring const parameters inside function signatures, the first rib
@@ -4132,7 +4168,7 @@ impl<'a> Resolver<'a> {
                 // Look for a field with the same name in the current self_type.
                 if let Some(resolution) = self.def_map.get(&node_id) {
                     match resolution.base_def() {
-                        Def::Struct(did) | Def::Union(did)
+                        Def::Def(DefKind::Struct, did) | Def::Def(DefKind::Union, did)
                                 if resolution.unresolved_segments() == 0 => {
                             if let Some(field_names) = self.field_names.get(&did) {
                                 if field_names.iter().any(|&field_name| ident.name == field_name) {
@@ -4223,10 +4259,13 @@ impl<'a> Resolver<'a> {
                                 self.crate_loader
                                     .maybe_process_path_extern(ident.name, ident.span)
                                     .and_then(|crate_id| {
-                                        let crate_mod = Def::Mod(DefId {
-                                            krate: crate_id,
-                                            index: CRATE_DEF_INDEX,
-                                        });
+                                        let crate_mod = Def::Def(
+                                            DefKind::Mod,
+                                            DefId {
+                                                krate: crate_id,
+                                                index: CRATE_DEF_INDEX,
+                                            },
+                                        );
 
                                         if !ident.name.is_gensymed() && filter_fn(crate_mod) {
                                             Some(TypoSuggestion {
@@ -4566,8 +4605,8 @@ impl<'a> Resolver<'a> {
             module.for_each_child(|name, ns, binding| {
                 if ns != TypeNS { return }
                 match binding.def() {
-                    Def::Trait(_) |
-                    Def::TraitAlias(_) => collected_traits.push((name, binding)),
+                    Def::Def(DefKind::Trait, _) |
+                    Def::Def(DefKind::TraitAlias, _) => collected_traits.push((name, binding)),
                     _ => (),
                 }
             });
@@ -4602,7 +4641,7 @@ impl<'a> Resolver<'a> {
                     let trait_def_id = module.def_id().unwrap();
                     found_traits.push(TraitCandidate { def_id: trait_def_id, import_id });
                 }
-            } else if let Def::TraitAlias(_) = binding.def() {
+            } else if let Def::Def(DefKind::TraitAlias, _) = binding.def() {
                 // For now, just treat all trait aliases as possible candidates, since we don't
                 // know if the ident is somewhere in the transitive bounds.
 
@@ -4677,7 +4716,7 @@ impl<'a> Resolver<'a> {
                         // outside crate private modules => no need to check this)
                         if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
                             let did = match def {
-                                Def::Ctor(did, ..) => self.parent(did),
+                                Def::Def(DefKind::Ctor(..), did) => self.parent(did),
                                 _ => def.opt_def_id(),
                             };
                             candidates.push(ImportSuggestion { did, path });
@@ -4793,7 +4832,7 @@ impl<'a> Resolver<'a> {
     }
 
     fn collect_enum_variants(&mut self, enum_def: Def) -> Option<Vec<Path>> {
-        if let Def::Enum(..) = enum_def {} else {
+        if let Def::Def(DefKind::Enum, _) = enum_def {} else {
             panic!("Non-enum def passed to collect_enum_variants: {:?}", enum_def)
         }
 
@@ -4802,7 +4841,7 @@ impl<'a> Resolver<'a> {
 
             let mut variants = Vec::new();
             enum_module.for_each_child_stable(|ident, _, name_binding| {
-                if let Def::Variant(..) = name_binding.def() {
+                if let Def::Def(DefKind::Variant, _) = name_binding.def() {
                     let mut segms = enum_import_suggestion.path.segments.clone();
                     segms.push(ast::PathSegment::from_ident(ident));
                     variants.push(Path {
@@ -5050,8 +5089,8 @@ impl<'a> Resolver<'a> {
         }
 
         let container = match parent.kind {
-            ModuleKind::Def(Def::Mod(_), _) => "module",
-            ModuleKind::Def(Def::Trait(_), _) => "trait",
+            ModuleKind::Def(Def::Def(DefKind::Mod, _), _) => "module",
+            ModuleKind::Def(Def::Def(DefKind::Trait, _), _) => "trait",
             ModuleKind::Block(..) => "block",
             _ => "enum",
         };
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index cb0cfd93a60..eea48f0711f 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -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};
@@ -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::Def(Def::Def(DefKind::Macro(kind), def_id), false),
             ambiguity: None,
             span: DUMMY_SP,
             vis: ty::Visibility::Public,
@@ -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 Def::Def(DefKind::Macro(_), def_id) = def {
             if after_derive {
                 self.session.span_err(invoc.span(),
                                       "macro attributes must be placed before `#[derive]`");
@@ -297,7 +297,7 @@ impl<'a> Resolver<'a> {
         let def = def?;
 
         match def {
-            Def::Macro(def_id, macro_kind) => {
+            Def::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";
@@ -341,7 +341,7 @@ impl<'a> Resolver<'a> {
             Def::Err => {
                 return Err(Determinacy::Determined);
             }
-            _ => panic!("expected `Def::Macro` or `Def::NonMacroAttr`"),
+            _ => panic!("expected `DefKind::Macro` or `Def::NonMacroAttr`"),
         }
 
         Ok((def, self.get_macro(def)))
@@ -1028,7 +1028,7 @@ impl<'a> Resolver<'a> {
         // Then check modules.
         }).or_else(|| {
             let is_macro = |def| {
-                if let Def::Macro(_, def_kind) = def {
+                if let Def::Def(DefKind::Macro(def_kind), _) = def {
                     def_kind == kind
                 } else {
                     false
@@ -1107,7 +1107,7 @@ 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 def = Def::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
@@ -1133,7 +1133,7 @@ impl<'a> Resolver<'a> {
             }
         } else {
             let module = self.current_module;
-            let def = Def::Macro(def_id, MacroKind::Bang);
+            let def = Def::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);
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 4dddf811c05..6ad09b2f7e7 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -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};
@@ -1224,7 +1224,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
         // 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 {
+            if let Def::Def(DefKind::Macro(_), def_id) = def {
                 // `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.
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index a5ddf89d3d4..36413e76a1e 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -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::{Def as HirDef, DefKind as HirDefKind};
 use rustc::hir::def_id::DefId;
 use rustc::session::config::Input;
 use rustc::span_bug;
@@ -957,13 +957,13 @@ 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::Def(HirDefKind::Ctor(..), _) |
+                HirDef::Def(HirDefKind::Const, _) |
+                HirDef::Def(HirDefKind::AssociatedConst, _) |
+                HirDef::Def(HirDefKind::Struct, _) |
+                HirDef::Def(HirDefKind::Variant, _) |
+                HirDef::Def(HirDefKind::TyAlias, _) |
+                HirDef::Def(HirDefKind::AssociatedTy, _) |
                 HirDef::SelfTy(..) => {
                     self.dump_path_ref(id, &ast::Path::from_ident(ident));
                 }
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index c173d51fd40..47d0b5055ea 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -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, Def as HirDef, DefKind as HirDefKind};
 use rustc::hir::Node;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::middle::privacy::AccessLevels;
@@ -710,39 +710,39 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     ref_id: id_from_node_id(self.tcx.hir().hir_to_node_id(id), self),
                 })
             }
-            HirDef::Trait(def_id) if fn_type(path_seg) => {
+            HirDef::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) => {
+            HirDef::Def(HirDefKind::Struct, def_id) |
+            HirDef::Def(HirDefKind::Variant, def_id) |
+            HirDef::Def(HirDefKind::Union, def_id) |
+            HirDef::Def(HirDefKind::Enum, def_id) |
+            HirDef::Def(HirDefKind::TyAlias, def_id) |
+            HirDef::Def(HirDefKind::ForeignTy, def_id) |
+            HirDef::Def(HirDefKind::TraitAlias, def_id) |
+            HirDef::Def(HirDefKind::AssociatedExistential, def_id) |
+            HirDef::Def(HirDefKind::AssociatedTy, def_id) |
+            HirDef::Def(HirDefKind::Trait, def_id) |
+            HirDef::Def(HirDefKind::Existential, def_id) |
+            HirDef::Def(HirDefKind::TyParam, def_id) => {
                 Some(Ref {
                     kind: RefKind::Type,
                     span,
                     ref_id: id_from_def_id(def_id),
                 })
             }
-            HirDef::ConstParam(def_id) => {
+            HirDef::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, ..) => {
+            HirDef::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(..) => {
+            HirDef::Def(HirDefKind::Static, _) |
+            HirDef::Def(HirDefKind::Const, _) |
+            HirDef::Def(HirDefKind::AssociatedConst, _) |
+            HirDef::Def(HirDefKind::Ctor(..), _) => {
                 Some(Ref {
                     kind: RefKind::Variable,
                     span,
                     ref_id: id_from_def_id(def.def_id()),
                 })
             }
-            HirDef::Method(decl_id) => {
+            HirDef::Def(HirDefKind::Method, decl_id) => {
                 let def_id = if decl_id.is_local() {
                     let ti = self.tcx.associated_item(decl_id);
                     self.tcx
@@ -780,14 +780,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     ref_id: id_from_def_id(def_id.unwrap_or(decl_id)),
                 })
             }
-            HirDef::Fn(def_id) => {
+            HirDef::Def(HirDefKind::Fn, def_id) => {
                 Some(Ref {
                     kind: RefKind::Function,
                     span,
                     ref_id: id_from_def_id(def_id),
                 })
             }
-            HirDef::Mod(def_id) => {
+            HirDef::Def(HirDefKind::Mod, def_id) => {
                 Some(Ref {
                     kind: RefKind::Mod,
                     span,
@@ -797,7 +797,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
             HirDef::PrimTy(..) |
             HirDef::SelfTy(..) |
             HirDef::Label(..) |
-            HirDef::Macro(..) |
+            HirDef::Def(HirDefKind::Macro(..), _) |
             HirDef::ToolMod |
             HirDef::NonMacroAttr(..) |
             HirDef::SelfCtor(..) |
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index 5ac75d01275..bcdb6be0ebd 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -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::{Def, DefKind};
 use syntax::ast::{self, NodeId};
 use syntax::print::pprust;
 
@@ -586,7 +586,9 @@ impl Sig for ast::Path {
                     refs: vec![],
                 })
             }
-            Def::AssociatedConst(..) | Def::Variant(..) | Def::Ctor(..) => {
+            Def::Def(DefKind::AssociatedConst, _)
+            | Def::Def(DefKind::Variant, _)
+            | Def::Def(DefKind::Ctor(..), _) => {
                 let len = self.segments.len();
                 if len < 2 {
                     return Err("Bad path");
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 98d72ee03d0..8807e1aa62a 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -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, Def, DefKind};
 use crate::hir::def_id::DefId;
 use crate::hir::HirVec;
 use crate::lint;
@@ -1330,7 +1330,7 @@ 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);
+                    let def = Def::Def(DefKind::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);
@@ -1365,7 +1365,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                 }
             }
             (&ty::Param(_), Def::SelfTy(Some(param_did), None)) |
-            (&ty::Param(_), Def::TyParam(param_did)) => {
+            (&ty::Param(_), Def::Def(DefKind::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),
@@ -1427,7 +1427,7 @@ 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 def = Def::Def(DefKind::AssociatedTy, item.def_id);
         if !item.vis.is_accessible_from(def_scope, tcx) {
             let msg = format!("{} `{}` is private", def.kind_name(), assoc_ident);
             tcx.sess.span_err(span, &msg);
@@ -1617,7 +1617,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
 
         match def {
             // Case 1. Reference to a struct constructor.
-            Def::Ctor(def_id, CtorOf::Struct, ..) |
+            Def::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) |
             Def::SelfCtor(.., def_id) => {
                 // Everything but the final segment should have no
                 // parameters at all.
@@ -1629,7 +1629,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, ..) => {
+            Def::Def(DefKind::Ctor(CtorOf::Variant, ..), def_id)
+            | Def::Def(DefKind::Variant, def_id) => {
                 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 +1640,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 Def::Def(DefKind::Ctor(..), _) = def {
                         def_id = tcx.parent(def_id).unwrap()
                     }
 
-                    // `Def::Variant` -> `Def::Item` (enum)
+                    // `DefKind::Variant` -> `DefKind::Item` (enum)
                     let enum_def_id = tcx.parent(def_id).unwrap();
                     (enum_def_id, last - 1)
                 } else {
@@ -1662,16 +1663,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) => {
+            Def::Def(DefKind::Fn, def_id) |
+            Def::Def(DefKind::Const, def_id) |
+            Def::Def(DefKind::ConstParam, def_id) |
+            Def::Def(DefKind::Static, def_id) => {
                 path_segs.push(PathSeg(def_id, last));
             }
 
             // Case 4. Reference to a method or associated const.
-            Def::Method(def_id) |
-            Def::AssociatedConst(def_id) => {
+            Def::Def(DefKind::Method, def_id) |
+            Def::Def(DefKind::AssociatedConst, def_id) => {
                 if segments.len() >= 2 {
                     let generics = tcx.generics_of(def_id);
                     path_segs.push(PathSeg(generics.parent.unwrap(), last - 1));
@@ -1703,7 +1704,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
 
         let span = path.span;
         match path.def {
-            Def::Existential(did) => {
+            Def::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,13 +1715,16 @@ 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) => {
+            Def::Def(DefKind::Enum, did)
+            | Def::Def(DefKind::TyAlias, did)
+            | Def::Def(DefKind::Struct, did)
+            | Def::Def(DefKind::Union, did)
+            | Def::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 => {
+            Def::Def(DefKind::Variant, _) 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);
@@ -1739,7 +1743,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) => {
+            Def::Def(DefKind::TyParam, did) => {
                 assert_eq!(opt_self_ty, None);
                 self.prohibit_generics(&path.segments);
 
@@ -1764,7 +1768,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                 self.prohibit_generics(&path.segments);
                 tcx.mk_self_type()
             }
-            Def::AssociatedTy(def_id) => {
+            Def::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,
@@ -1911,7 +1915,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 Def::Def(DefKind::ConstParam, def_id) = path.def {
                     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);
@@ -2098,7 +2102,7 @@ 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) => {
+            Def::Def(DefKind::Trait, trait_did) if tcx.trait_is_auto(trait_did) => {
                 true
             }
             _ => false
@@ -2106,7 +2110,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 Def::Def(DefKind::Trait, trait_did) = tr.trait_ref.path.def {
             trait_did
         } else {
             unreachable!()
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 6cc7818d712..bd04e12eb24 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -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::{Def, DefKind, CtorKind};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
 use rustc::infer;
 use rustc::infer::type_variable::TypeVariableOrigin;
@@ -67,7 +67,7 @@ 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);
                 match def {
-                    Def::Const(..) | Def::AssociatedConst(..) => false,
+                    Def::Def(DefKind::Const, _) | Def::Def(DefKind::AssociatedConst, _) => false,
                     _ => true,
                 }
             }
@@ -846,17 +846,17 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
                 self.set_tainted_by_errors();
                 return tcx.types.err;
             }
-            Def::Method(..) => {
+            Def::Def(DefKind::Method, _) => {
                 report_unexpected_variant_def(tcx, &def, pat.span, qpath);
                 return tcx.types.err;
             }
-            Def::Ctor(_, _, CtorKind::Fictive) |
-            Def::Ctor(_, _, CtorKind::Fn) => {
+            Def::Def(DefKind::Ctor(_, CtorKind::Fictive), _) |
+            Def::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
                 report_unexpected_variant_def(tcx, &def, pat.span, qpath);
                 return tcx.types.err;
             }
-            Def::Ctor(_, _, CtorKind::Const) | Def::SelfCtor(..) |
-            Def::Const(..) | Def::AssociatedConst(..) => {} // OK
+            Def::Def(DefKind::Ctor(_, CtorKind::Const), _) | Def::SelfCtor(..) |
+            Def::Def(DefKind::Const, _) | Def::Def(DefKind::AssociatedConst, _) => {} // OK
             _ => bug!("unexpected pattern definition: {:?}", def)
         }
 
@@ -913,11 +913,11 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
                 on_error();
                 return tcx.types.err;
             }
-            Def::AssociatedConst(..) | Def::Method(..) => {
+            Def::Def(DefKind::AssociatedConst, _) | Def::Def(DefKind::Method, _) => {
                 report_unexpected_def(def);
                 return tcx.types.err;
             }
-            Def::Ctor(_, _, CtorKind::Fn) => {
+            Def::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
                 tcx.expect_variant_def(def)
             }
             _ => bug!("unexpected pattern definition: {:?}", def)
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index b47cce04012..a3ee6ffe8da 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -1,4 +1,5 @@
 use rustc::hir::{self, GenericParamKind, ImplItemKind, TraitItemKind};
+use rustc::hir::def::{Def, 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 Def::Def(DefKind::TyParam, def_id) = path.def {
                                         if def_id == self.1 {
                                             self.0 = Some(ty.span);
                                         }
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 8ae66a96c76..537ea9a4b44 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -5,7 +5,7 @@ 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::def::{Def, DefKind};
 use rustc::hir::Node;
 use rustc::hir::{print, lowering::is_range_literal};
 use rustc::ty::{self, Ty, AssociatedItem};
@@ -207,7 +207,7 @@ 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) => {
+            Def::Def(DefKind::Method, def_id) => {
                 self.tcx.fn_sig(def_id).inputs().skip_binder().len() == 1
             }
             _ => false,
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 34a24308e49..b0f0856615d 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -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, Def, DefKind};
 use rustc::hir::def_id::DefId;
 use rustc::traits;
 use rustc::ty::subst::{InternalSubsts, SubstsRef};
@@ -422,7 +422,10 @@ 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);
+                    let def = Def::Def(
+                        DefKind::Ctor(CtorOf::Variant, variant_def.ctor_kind),
+                        ctor_def_id,
+                    );
                     tcx.check_stability(def.def_id(), Some(expr_id), span);
                     return Ok(def);
                 }
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index a35777873ab..54260f196ce 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -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::{Def, DefKind};
 use crate::namespace::Namespace;
 
 use rustc_data_structures::sync::Lrc;
@@ -862,7 +862,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
                                self_ty: Option<Ty<'tcx>>,
                                expected: Ty<'tcx>) -> bool {
         match method.def() {
-            Def::Method(def_id) => {
+            Def::Def(DefKind::Method, def_id) => {
                 let fty = self.tcx.fn_sig(def_id);
                 self.probe(|_| {
                     let substs = self.fresh_substs_for_item(self.span, method.def_id);
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 35d4568bd9c..2c567a86991 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -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::{Def, DefKind};
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
 use rustc::hir::map as hir_map;
 use rustc::hir::print;
@@ -804,11 +804,11 @@ fn compute_all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Vec<DefId>
                            external_mods: &mut FxHashSet<DefId>,
                            def: Def) {
         match def {
-            Def::Trait(def_id) |
-            Def::TraitAlias(def_id) => {
+            Def::Def(DefKind::Trait, def_id) |
+            Def::Def(DefKind::TraitAlias, def_id) => {
                 traits.push(def_id);
             }
-            Def::Mod(def_id) => {
+            Def::Def(DefKind::Mod, def_id) => {
                 if !external_mods.insert(def_id) {
                     return;
                 }
@@ -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_def(tcx, &mut traits, &mut external_mods, Def::Def(DefKind::Mod, def_id));
     }
 
     traits
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index d2d486b52b3..47974bc5564 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -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, Def, DefKind};
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
@@ -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, Def::Def(DefKind::Method, method.def_id));
 
         self.write_substs(hir_id, method.substs);
 
@@ -3926,7 +3926,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 self.set_tainted_by_errors();
                 return None;
             }
-            Def::Variant(..) => {
+            Def::Def(DefKind::Variant, _) => {
                 match ty.sty {
                     ty::Adt(adt, substs) => {
                         Some((adt.variant_of_def(def), adt.did, substs))
@@ -3934,8 +3934,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     _ => bug!("unexpected type: {:?}", ty)
                 }
             }
-            Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
-            Def::AssociatedTy(..) | Def::SelfTy(..) => {
+            Def::Def(DefKind::Struct, _)
+            | Def::Def(DefKind::Union, _)
+            | Def::Def(DefKind::TyAlias, _)
+            | Def::Def(DefKind::AssociatedTy, _)
+            | Def::SelfTy(..) => {
                 match ty.sty {
                     ty::Adt(adt, substs) if !adt.is_enum() => {
                         Some((adt.non_enum_variant(), adt.did, substs))
@@ -4237,7 +4240,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         self.set_tainted_by_errors();
                         tcx.types.err
                     }
-                    Def::Ctor(_, _, CtorKind::Fictive) => {
+                    Def::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
                         report_unexpected_variant_def(tcx, &def, expr.span, qpath);
                         tcx.types.err
                     }
@@ -5362,7 +5365,10 @@ 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);
+                    let def = Def::Def(
+                        DefKind::Ctor(CtorOf::Struct, variant.ctor_kind),
+                        ctor_def_id,
+                    );
                     (def, ctor_def_id, tcx.type_of(ctor_def_id))
                 }
                 _ => {
@@ -5434,7 +5440,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         let mut user_self_ty = None;
         let mut is_alias_variant_ctor = false;
         match def {
-            Def::Ctor(_, CtorOf::Variant, _) => {
+            Def::Def(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,8 +5450,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     is_alias_variant_ctor = true;
                 }
             }
-            Def::Method(def_id) |
-            Def::AssociatedConst(def_id) => {
+            Def::Def(DefKind::Method, def_id) |
+            Def::Def(DefKind::AssociatedConst, def_id) => {
                 let container = tcx.associated_item(def_id).container;
                 debug!("instantiate_value_path: def={:?} container={:?}", def, container);
                 match container {
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 9c8b5ac58e3..89409deb145 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -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, Def, DefKind};
 use rustc::hir::Node;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
@@ -381,7 +381,7 @@ fn is_param<'a, 'tcx>(
 ) -> 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) => {
+            Def::SelfTy(Some(def_id), None) | Def::Def(DefKind::TyParam, def_id) => {
                 def_id == tcx.hir().local_def_id_from_hir_id(param_id)
             }
             _ => false,
@@ -1381,10 +1381,10 @@ pub fn checked_type_of<'a, 'tcx>(
                                 // 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) => {
+                                Def::Def(DefKind::Struct, def_id)
+                                | Def::Def(DefKind::Union, def_id)
+                                | Def::Def(DefKind::Enum, def_id)
+                                | Def::Def(DefKind::Fn, def_id) => {
                                     let generics = tcx.generics_of(def_id);
                                     let mut param_index = 0;
                                     for param in &generics.params {
@@ -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.def != Def::Def(DefKind::Trait, kind_id) {
                     tcx.sess.span_warn(
                         span,
                         "default bound relaxed for a type parameter, but \
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 5da74a588c9..365af15e006 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -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::{Def, DefKind, CtorKind};
 use rustc::hir::def_id::DefId;
 use rustc_metadata::cstore::LoadedMacro;
 use rustc::ty;
@@ -50,59 +50,59 @@ pub fn try_inline(
     if did.is_local() { return None }
     let mut ret = Vec::new();
     let inner = match def {
-        Def::Trait(did) => {
+        Def::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) => {
+        Def::Def(DefKind::Fn, did) => {
             record_extern_fqn(cx, did, clean::TypeKind::Function);
             clean::FunctionItem(build_external_function(cx, did))
         }
-        Def::Struct(did) => {
+        Def::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) => {
+        Def::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) => {
+        Def::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) => {
+        Def::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) => {
+        Def::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,
+        Def::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) => {
+        Def::Def(DefKind::Ctor(..), _) | Def::SelfCtor(..) => return Some(Vec::new()),
+        Def::Def(DefKind::Mod, did) => {
             record_extern_fqn(cx, did, clean::TypeKind::Module);
             clean::ModuleItem(build_module(cx, did, visited))
         }
-        Def::Static(did) => {
+        Def::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) => {
+        Def::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) => {
+        Def::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);
@@ -135,7 +135,7 @@ pub fn try_inline_glob(cx: &DocContext<'_>, def: Def, visited: &mut FxHashSet<De
     if did.is_local() { return None }
 
     match def {
-        Def::Mod(did) => {
+        Def::Def(DefKind::Mod, did) => {
             let m = build_module(cx, did, visited);
             Some(m.items)
         }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 7f5ba91900b..95a2664954d 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -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, Def, 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};
@@ -258,7 +258,7 @@ impl Clean<ExternalCrate> for CrateNum {
         // 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 {
+            if let Def::Def(DefKind::Mod, def_id) = def {
                 let attrs = cx.tcx.get_attrs(def_id).clean(cx);
                 let mut prim = None;
                 for attr in attrs.lists("doc") {
@@ -281,7 +281,10 @@ 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(Def::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() => {
@@ -299,7 +302,7 @@ impl Clean<ExternalCrate> for CrateNum {
         };
 
         let as_keyword = |def: Def| {
-            if let Def::Mod(def_id) = def {
+            if let Def::Def(DefKind::Mod, def_id) = def {
                 let attrs = cx.tcx.get_attrs(def_id).clean(cx);
                 let mut keyword = None;
                 for attr in attrs.lists("doc") {
@@ -323,7 +326,10 @@ 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(Def::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() => {
@@ -2785,14 +2791,14 @@ impl Clean<Type> for hir::Ty {
                     return new_ty;
                 }
 
-                if let Def::TyParam(did) = path.def {
+                if let Def::Def(DefKind::TyParam, did) = path.def {
                     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 Def::Def(DefKind::TyAlias, def_id) = path.def {
                     // 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) {
@@ -2835,8 +2841,10 @@ impl Clean<Type> for hir::Ty {
                                 }
                                 hir::GenericParamKind::Type { ref default, .. } => {
                                     let ty_param_def =
-                                        Def::TyParam(
-                                            cx.tcx.hir().local_def_id_from_hir_id(param.hir_id));
+                                        Def::Def(
+                                            DefKind::TyParam,
+                                            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 {
@@ -2860,8 +2868,10 @@ impl Clean<Type> for hir::Ty {
                                 }
                                 hir::GenericParamKind::Const { .. } => {
                                     let const_param_def =
-                                        Def::ConstParam(
-                                            cx.tcx.hir().local_def_id_from_hir_id(param.hir_id));
+                                        Def::Def(
+                                            DefKind::ConstParam,
+                                            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 {
@@ -2893,7 +2903,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()),
+                    def: Def::Def(
+                        DefKind::Trait,
+                        cx.tcx.associated_item(p.def.def_id()).container.id(),
+                    ),
                     segments: segments.into(),
                 };
                 Type::QPath {
@@ -2906,7 +2919,7 @@ impl Clean<Type> for hir::Ty {
                 let mut def = Def::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);
+                    def = Def::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id);
                 }
                 let trait_path = hir::Path {
                     span: self.span,
@@ -3898,10 +3911,13 @@ 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 def = Def::Def(
+                DefKind::Mod,
+                DefId {
+                    krate: self.cnum,
+                    index: CRATE_DEF_INDEX,
+                },
+            );
 
             if let Some(items) = inline::try_inline(cx, def, self.name, &mut visited) {
                 return items;
@@ -3951,10 +3967,12 @@ impl Clean<Vec<Item>> for doctree::Import {
             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;
+                    Def::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;
+                        }
                     }
                     _ => {}
                 }
@@ -4157,10 +4175,12 @@ fn resolve_type(cx: &DocContext<'_>,
         Def::SelfTy(..) if path.segments.len() == 1 => {
             return Generic(keywords::SelfUpper.name().to_string());
         }
-        Def::TyParam(..) if path.segments.len() == 1 => {
+        Def::Def(DefKind::TyParam, _) if path.segments.len() == 1 => {
             return Generic(format!("{:#}", path));
         }
-        Def::SelfTy(..) | Def::TyParam(..) | Def::AssociatedTy(..) => true,
+        Def::SelfTy(..)
+        | Def::Def(DefKind::TyParam, _)
+        | Def::Def(DefKind::AssociatedTy, _) => true,
         _ => false,
     };
     let did = register_def(&*cx, path.def);
@@ -4171,25 +4191,25 @@ pub fn register_def(cx: &DocContext<'_>, def: Def) -> DefId {
     debug!("register_def({:?})", def);
 
     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"),
+        Def::Def(DefKind::Fn, i) => (i, TypeKind::Function),
+        Def::Def(DefKind::TyAlias, i) => (i, TypeKind::Typedef),
+        Def::Def(DefKind::Enum, i) => (i, TypeKind::Enum),
+        Def::Def(DefKind::Trait, i) => (i, TypeKind::Trait),
+        Def::Def(DefKind::Struct, i) => (i, TypeKind::Struct),
+        Def::Def(DefKind::Union, i) => (i, TypeKind::Union),
+        Def::Def(DefKind::Mod, i) => (i, TypeKind::Module),
+        Def::Def(DefKind::ForeignTy, i) => (i, TypeKind::Foreign),
+        Def::Def(DefKind::Const, i) => (i, TypeKind::Const),
+        Def::Def(DefKind::Static, i) => (i, TypeKind::Static),
+        Def::Def(DefKind::Variant, i) => (cx.tcx.parent(i).expect("cannot get parent def id"),
                             TypeKind::Enum),
-        Def::Macro(i, mac_kind) => match mac_kind {
+        Def::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::Def(DefKind::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()
@@ -4418,7 +4438,7 @@ pub fn path_to_def(tcx: TyCtxt<'_, '_, '_>, path: &[&str]) -> Option<DefId> {
                 if item.ident.name == *segment {
                     if path_it.peek().is_none() {
                         return match item.def {
-                            def::Def::Trait(did) => Some(did),
+                            def::Def::Def(DefKind::Trait, did) => Some(did),
                             _ => None,
                         }
                     }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 902414bd8fd..f5b97797897 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1,5 +1,5 @@
 use errors::Applicability;
-use rustc::hir::def::{Def, Namespace::{self, *}, PerNS};
+use rustc::hir::def::{Def, DefKind, Namespace::{self, *}, PerNS};
 use rustc::hir::def_id::DefId;
 use rustc::hir;
 use rustc::lint as lint;
@@ -75,9 +75,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                 // 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),
+                    Def::Def(DefKind::Method, _) | Def::Def(DefKind::AssociatedConst, _) => true,
+                    Def::Def(DefKind::AssociatedTy, _) => false,
+                    Def::Def(DefKind::Variant, _) => return handle_variant(cx, result.def),
                     // Not a trait item; just return what we found.
                     _ => return Ok((result.def, None))
                 };
@@ -133,7 +133,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                     resolver.resolve_str_path_error(DUMMY_SP, &path, false)
             }))?;
             match ty.def {
-                Def::Struct(did) | Def::Union(did) | Def::Enum(did) | Def::TyAlias(did) => {
+                Def::Def(DefKind::Struct, did)
+                | Def::Def(DefKind::Union, did)
+                | Def::Def(DefKind::Enum, did)
+                | Def::Def(DefKind::TyAlias, did) => {
                     let item = cx.tcx.inherent_impls(did)
                                      .iter()
                                      .flat_map(|imp| cx.tcx.associated_items(*imp))
@@ -172,7 +175,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                         }
                     }
                 }
-                Def::Trait(did) => {
+                Def::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);
@@ -347,7 +350,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                                 .and_then(|(def, fragment)| {
                                     // Constructors are picked up in the type namespace.
                                     match def {
-                                        Def::Ctor(..) | Def::SelfCtor(..) => None,
+                                        Def::Def(DefKind::Ctor(..), _) | Def::SelfCtor(..) => None,
                                         _ => Some((def, fragment))
                                     }
                                 }),
@@ -427,7 +430,7 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Def> {
         let parent_scope = resolver.dummy_parent_scope();
         if let Ok(def) = resolver.resolve_macro_to_def_inner(&path, MacroKind::Bang,
                                                             &parent_scope, false, false) {
-            if let Def::Macro(_, MacroKind::ProcMacroStub) = def {
+            if let Def::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) = def {
                 // skip proc-macro stubs, they'll cause `get_macro` to crash
             } else {
                 if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(def) {
@@ -541,21 +544,21 @@ fn ambiguity_error(
 
             for (def, ns) in candidates {
                 let (action, mut suggestion) = match def {
-                    Def::Method(..) | Def::Fn(..) => {
+                    Def::Def(DefKind::Method, _) | Def::Def(DefKind::Fn, _) => {
                         ("add parentheses", format!("{}()", path_str))
                     }
-                    Def::Macro(..) => {
+                    Def::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",
+                            (Def::Def(DefKind::Const, _), _) => "const",
+                            (Def::Def(DefKind::Static, _), _) => "static",
+                            (Def::Def(DefKind::Struct, _), _) => "struct",
+                            (Def::Def(DefKind::Enum, _), _) => "enum",
+                            (Def::Def(DefKind::Union, _), _) => "union",
+                            (Def::Def(DefKind::Trait, _), _) => "trait",
+                            (Def::Def(DefKind::Mod, _), _) => "module",
                             (_, TypeNS) => "type",
                             (_, ValueNS) => "value",
                             (_, MacroNS) => "macro",
@@ -609,7 +612,7 @@ fn handle_variant(cx: &DocContext<'_>, def: Def) -> Result<(Def, Option<String>)
     } else {
         return Err(())
     };
-    let parent_def = Def::Enum(parent);
+    let parent_def = Def::Def(DefKind::Enum, parent);
     let variant = cx.tcx.expect_variant_def(def);
     Ok((parent_def, Some(format!("{}.v", variant.ident.name))))
 }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index badf37c9671..b7a617cdbd9 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -2,7 +2,7 @@
 //! usable for `clean`.
 
 use rustc::hir::{self, Node};
-use rustc::hir::def::Def;
+use rustc::hir::def::{Def, DefKind};
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::middle::privacy::AccessLevel;
 use rustc::util::nodemap::{FxHashSet, FxHashMap};
@@ -306,18 +306,18 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             let attrs = clean::inline::load_attrs(self.cx, def_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 => {
+                Def::Def(DefKind::Trait, did) |
+                Def::Def(DefKind::Struct, did) |
+                Def::Def(DefKind::Union, did) |
+                Def::Def(DefKind::Enum, did) |
+                Def::Def(DefKind::ForeignTy, did) |
+                Def::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 {
+                Def::Def(DefKind::Mod, did) => if !self_is_hidden {
                     crate::visit_lib::LibEmbargoVisitor::new(self.cx).visit_mod(did);
                 },
                 _ => {},
@@ -421,8 +421,9 @@ 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,
+                    Def::Def(DefKind::Ctor(..), _)
+                    | Def::SelfCtor(..)
+                    | Def::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) => return,
                     _ => {}
                 }
 
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index def6f8b557b..22c750011d9 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -1,5 +1,5 @@
 use rustc::middle::privacy::{AccessLevels, AccessLevel};
-use rustc::hir::def::Def;
+use rustc::hir::def::{Def, DefKind};
 use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
 use rustc::ty::Visibility;
 use rustc::util::nodemap::FxHashSet;
@@ -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 Def::Def(DefKind::Mod, _) = def {
             let orig_level = self.prev_level;
 
             self.prev_level = item_level;

From b92b1a76e175f396d7986177d0a2d5907bbba888 Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Sat, 20 Apr 2019 19:46:19 +0300
Subject: [PATCH 2/3] rustc: use DefKind instead of Def, where possible.

---
 src/librustc/hir/def.rs                     |  84 ++++++++------
 src/librustc/hir/map/mod.rs                 |  27 ++---
 src/librustc/hir/mod.rs                     |   2 +-
 src/librustc/middle/reachable.rs            |   1 +
 src/librustc/middle/stability.rs            |   8 +-
 src/librustc/query/mod.rs                   |   2 +-
 src/librustc/ty/context.rs                  |  25 +++--
 src/librustc/ty/mod.rs                      |  20 ++--
 src/librustc/ty/query/mod.rs                |   2 +-
 src/librustc_lint/unused.rs                 |  10 +-
 src/librustc_metadata/cstore_impl.rs        |   2 +-
 src/librustc_metadata/decoder.rs            |  71 ++++++------
 src/librustc_mir/const_eval.rs              |   6 +-
 src/librustc_mir/hair/cx/expr.rs            |   6 +-
 src/librustc_mir/interpret/eval_context.rs  |  10 +-
 src/librustc_mir/transform/const_prop.rs    |   6 +-
 src/librustc_mir/util/pretty.rs             |  22 ++--
 src/librustc_privacy/lib.rs                 |  30 ++---
 src/librustc_resolve/build_reduced_graph.rs |  22 ++--
 src/librustc_resolve/diagnostics.rs         |  10 +-
 src/librustc_resolve/lib.rs                 |  56 +++++-----
 src/librustc_resolve/macros.rs              |   2 +-
 src/librustc_resolve/resolve_imports.rs     |   2 +-
 src/librustc_typeck/astconv.rs              |  94 +++++++---------
 src/librustc_typeck/check/demand.rs         |   7 +-
 src/librustc_typeck/check/method/mod.rs     |  23 ++--
 src/librustc_typeck/check/method/probe.rs   |  17 +--
 src/librustc_typeck/check/method/suggest.rs |  10 +-
 src/librustc_typeck/check/mod.rs            | 115 ++++++++++++--------
 src/librustdoc/clean/mod.rs                 |  31 ++----
 src/librustdoc/core.rs                      |  15 ++-
 31 files changed, 381 insertions(+), 357 deletions(-)

diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index d4ad4225b99..b9ba1aff8f4 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -80,6 +80,53 @@ pub enum DefKind {
     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 Def<Id = hir::HirId> {
     Def(DefKind, DefId),
@@ -328,39 +375,13 @@ impl<Id> Def<Id> {
     /// A human readable name for the def kind ("function", "module", etc.).
     pub fn kind_name(&self) -> &'static str {
         match *self {
-            Def::Def(DefKind::Fn, _) => "function",
-            Def::Def(DefKind::Mod, _) => "module",
-            Def::Def(DefKind::Static, _) => "static",
-            Def::Def(DefKind::Enum, _) => "enum",
-            Def::Def(DefKind::Variant, _) => "variant",
-            Def::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), _) => "tuple variant",
-            Def::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), _) => "unit variant",
-            Def::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fictive), _) => "struct variant",
-            Def::Def(DefKind::Struct, _) => "struct",
-            Def::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), _) => "tuple struct",
-            Def::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Const), _) => "unit struct",
-            Def::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive), _) =>
-                bug!("impossible struct constructor"),
-            Def::Def(DefKind::Existential, _) => "existential type",
-            Def::Def(DefKind::TyAlias, _) => "type alias",
-            Def::Def(DefKind::TraitAlias, _) => "trait alias",
-            Def::Def(DefKind::AssociatedTy, _) => "associated type",
-            Def::Def(DefKind::AssociatedExistential, _) => "associated existential type",
+            Def::Def(kind, _) => kind.descr(),
             Def::SelfCtor(..) => "self constructor",
-            Def::Def(DefKind::Union, _) => "union",
-            Def::Def(DefKind::Trait, _) => "trait",
-            Def::Def(DefKind::ForeignTy, _) => "foreign type",
-            Def::Def(DefKind::Method, _) => "method",
-            Def::Def(DefKind::Const, _) => "constant",
-            Def::Def(DefKind::AssociatedConst, _) => "associated constant",
-            Def::Def(DefKind::TyParam, _) => "type parameter",
-            Def::Def(DefKind::ConstParam, _) => "const parameter",
             Def::PrimTy(..) => "builtin type",
             Def::Local(..) => "local variable",
             Def::Upvar(..) => "closure capture",
             Def::Label(..) => "label",
             Def::SelfTy(..) => "self type",
-            Def::Def(DefKind::Macro(macro_kind), _) => macro_kind.descr(),
             Def::ToolMod => "tool module",
             Def::NonMacroAttr(attr_kind) => attr_kind.descr(),
             Def::Err => "unresolved item",
@@ -370,13 +391,8 @@ impl<Id> Def<Id> {
     /// An English article for the def.
     pub fn article(&self) -> &'static str {
         match *self {
-            Def::Def(DefKind::AssociatedTy, _)
-            | Def::Def(DefKind::AssociatedConst, _)
-            | Def::Def(DefKind::AssociatedExistential, _)
-            | Def::Def(DefKind::Enum, _)
-            | Def::Def(DefKind::Existential, _)
-            | Def::Err => "an",
-            Def::Def(DefKind::Macro(macro_kind), _) => macro_kind.article(),
+            Def::Def(kind, _) => kind.article(),
+            Def::Err => "an",
             _ => "a",
         }
     }
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 9251f8e797b..9c895198ddd 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -17,7 +17,7 @@ use syntax::ext::base::MacroKind;
 use syntax_pos::{Span, DUMMY_SP};
 
 use crate::hir::*;
-use crate::hir::{Def, DefKind};
+use crate::hir::DefKind;
 use crate::hir::itemlikevisit::ItemLikeVisitor;
 use crate::hir::print::Nested;
 use crate::util::nodemap::FxHashMap;
@@ -310,14 +310,14 @@ 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
         };
 
-        let kind = match node {
+        Some(match node {
             Node::Item(item) => {
                 match item.node {
                     ItemKind::Static(..) => DefKind::Static,
@@ -382,15 +382,11 @@ impl<'hir> Map<'hir> {
             Node::TraitRef(_) |
             Node::Pat(_) |
             Node::Binding(_) |
+            Node::Local(_) |
             Node::Lifetime(_) |
             Node::Visibility(_) |
             Node::Block(_) |
             Node::Crate => return None,
-            // FIXME(eddyb) this is the only non-`DefKind` case here,
-            // investigate whether it's actually used, and ideally remove it.
-            Node::Local(local) => {
-                return Some(Def::Local(local.hir_id));
-            }
             Node::MacroDef(_) => DefKind::Macro(MacroKind::Bang),
             Node::GenericParam(param) => {
                 match param.kind {
@@ -399,14 +395,7 @@ impl<'hir> Map<'hir> {
                     GenericParamKind::Const { .. } => DefKind::ConstParam,
                 }
             }
-        };
-        Some(Def::Def(kind, self.local_def_id(node_id)))
-    }
-
-    // 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 {
@@ -1464,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)
     }
 }
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index f474ab1a1a5..833983d3576 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -2521,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)]
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 8647820d574..a68be387d61 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -98,6 +98,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
             }
             hir::ExprKind::MethodCall(..) => {
                 self.tables.type_dependent_def(expr.hir_id)
+                    .map(|(kind, def_id)| Def::Def(kind, def_id))
             }
             _ => None
         };
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index e651e82d304..c57b62f42d5 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -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::Def(DefKind::Method, _)) |
-            Some(Def::Def(DefKind::AssociatedTy, _)) |
-            Some(Def::Def(DefKind::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
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index b96ef1b7a86..e1e115cfe17 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -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
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 48c3400c597..dfc9e8140bb 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -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
@@ -481,30 +482,32 @@ impl<'tcx> TypeckTables<'tcx> {
     pub fn qpath_def(&self, qpath: &hir::QPath, id: hir::HirId) -> Def {
         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::TypeRelative(..) => self.type_dependent_def(id)
+                .map_or(Def::Err, |(kind, def_id)| Def::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::Def(DefKind::Method, _)) => true,
+            Some(Ok((DefKind::Method, _))) => true,
             _ => false
         }
     }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 3871b465cab..3d08dc67005 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -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::Def(DefKind::AssociatedConst, self.def_id),
-            AssociatedKind::Method => Def::Def(DefKind::Method, self.def_id),
-            AssociatedKind::Type => Def::Def(DefKind::AssociatedTy, self.def_id),
-            AssociatedKind::Existential => Def::Def(DefKind::AssociatedExistential, self.def_id),
+            AssociatedKind::Const => DefKind::AssociatedConst,
+            AssociatedKind::Method => DefKind::Method,
+            AssociatedKind::Type => DefKind::AssociatedTy,
+            AssociatedKind::Existential => DefKind::AssociatedExistential,
         }
     }
 
@@ -2805,10 +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::Def(DefKind::AssociatedConst, _)
-                | Def::Def(DefKind::Method, _)
-                | Def::Def(DefKind::AssociatedTy, _) => true,
+            match self.def_kind(def_id).expect("no def for def-id") {
+                DefKind::AssociatedConst
+                | DefKind::Method
+                | DefKind::AssociatedTy => true,
                 _ => false,
             }
         };
@@ -3046,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::Def(DefKind::Method, _)) = self.describe_def(def_id) {
+            if let Some(DefKind::Method) = self.def_kind(def_id) {
                 Some(self.associated_item(def_id))
             } else {
                 None
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index cd29ca81890..18d575f7364 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -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;
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 9962caf0731..5155ac410aa 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -87,13 +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::Def(DefKind::Fn, _) | Def::Def(DefKind::Method, _) => Some(def),
+                            Def::Def(DefKind::Fn, def_id)
+                            | Def::Def(DefKind::Method, def_id) => Some(def_id),
                             // `Def::Local` if it was a closure, for which we
                             // do not currently support must-use linting
                             _ => None
@@ -103,12 +104,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.
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index b3439e4c970..892a7a8355c 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -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))
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index cc7a72c7593..5e71a74c9bb 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -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::Def(DefKind::Const, did),
-            EntryKind::AssociatedConst(..) => Def::Def(DefKind::AssociatedConst, did),
+            EntryKind::Const(..) => DefKind::Const,
+            EntryKind::AssociatedConst(..) => DefKind::AssociatedConst,
             EntryKind::ImmStatic |
             EntryKind::MutStatic |
             EntryKind::ForeignImmStatic |
-            EntryKind::ForeignMutStatic => Def::Def(DefKind::Static, did),
-            EntryKind::Struct(_, _) => Def::Def(DefKind::Struct, did),
-            EntryKind::Union(_, _) => Def::Def(DefKind::Union, did),
+            EntryKind::ForeignMutStatic => DefKind::Static,
+            EntryKind::Struct(_, _) => DefKind::Struct,
+            EntryKind::Union(_, _) => DefKind::Union,
             EntryKind::Fn(_) |
-            EntryKind::ForeignFn(_) => Def::Def(DefKind::Fn, did),
-            EntryKind::Method(_) => Def::Def(DefKind::Method, did),
-            EntryKind::Type => Def::Def(DefKind::TyAlias, did),
-            EntryKind::TypeParam => Def::Def(DefKind::TyParam, did),
-            EntryKind::ConstParam => Def::Def(DefKind::ConstParam, did),
-            EntryKind::Existential => Def::Def(DefKind::Existential, did),
-            EntryKind::AssociatedType(_) => Def::Def(DefKind::AssociatedTy, did),
-            EntryKind::AssociatedExistential(_) => Def::Def(DefKind::AssociatedExistential, did),
-            EntryKind::Mod(_) => Def::Def(DefKind::Mod, did),
-            EntryKind::Variant(_) => Def::Def(DefKind::Variant, did),
-            EntryKind::Trait(_) => Def::Def(DefKind::Trait, did),
-            EntryKind::TraitAlias(_) => Def::Def(DefKind::TraitAlias, did),
-            EntryKind::Enum(..) => Def::Def(DefKind::Enum, did),
-            EntryKind::MacroDef(_) => Def::Def(DefKind::Macro(MacroKind::Bang), did),
-            EntryKind::ForeignType => Def::Def(DefKind::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::Def(DefKind::Macro(kind), self.local_def_id(index)))
+            Some(DefKind::Macro(kind))
         }
     }
 
@@ -745,10 +745,7 @@ impl<'a, 'tcx> CrateMetadata {
                 for (id, &(name, ref ext)) in proc_macros.iter().enumerate() {
                     let def = Def::Def(
                         DefKind::Macro(ext.kind()),
-                        DefId {
-                            krate: self.cnum,
-                            index: DefIndex::from_proc_macro_index(id),
-                        },
+                        self.local_def_id(DefIndex::from_proc_macro_index(id)),
                     );
                     let ident = Ident::with_empty_ctxt(name);
                     callback(def::Export {
@@ -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,
+                                    def: Def::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,15 +804,17 @@ 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);
+                    let def_id = self.local_def_id(child_index);
+                    let def = Def::Def(kind, def_id);
                     callback(def::Export { def, 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::Def(DefKind::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::Def(
@@ -826,7 +825,7 @@ impl<'a, 'tcx> CrateMetadata {
                                 callback(def::Export { def: ctor_def, vis, ident, span });
                             }
                         }
-                        Def::Def(DefKind::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
@@ -845,7 +844,7 @@ 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);
                                 }
                             }
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index f4c7b40647c..866b6492d10 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -6,7 +6,7 @@ use std::borrow::{Borrow, Cow};
 use std::hash::Hash;
 use std::collections::hash_map::Entry;
 
-use rustc::hir::def::{Def, DefKind};
+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::Def(DefKind::Const, _)) | Some(Def::Def(DefKind::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)),
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index b1c3cdc9dc8..51bb4134341 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -830,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_def(cx, expr.hir_id, &Def::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);
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 7a8530b31ce..ad4bc6a91f5 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -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, DefKind};
+use rustc::hir::def::DefKind;
 use rustc::mir;
 use rustc::ty::layout::{
     self, Size, Align, HasDataLayout, LayoutOf, TyLayout
@@ -501,11 +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::Def(DefKind::Static, _))
-                | Some(Def::Def(DefKind::Const, _))
-                | Some(Def::Def(DefKind::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() {
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index a114c18ace8..72af0278201 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -1,7 +1,7 @@
 //! Propagates constants for early reporting of statically known
 //! assertion failures
 
-use rustc::hir::def::{Def, DefKind};
+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::Def(DefKind::AssociatedConst, _)) => true,
+        let is_assoc_const = match tcx.def_kind(source.def_id()) {
+            Some(DefKind::AssociatedConst) => true,
             _ => false,
         };
 
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index 790d3c6624a..94259fa523c 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -575,25 +575,25 @@ fn write_mir_sig(
     mir: &Mir<'_>,
     w: &mut dyn Write,
 ) -> io::Result<()> {
-    use rustc::hir::def::{Def, DefKind};
+    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::Def(DefKind::Fn, _))
-        | Some(Def::Def(DefKind::Method, _))
-        | Some(Def::Def(DefKind::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::Def(DefKind::Const, _)), _)
-        | (Some(Def::Def(DefKind::AssociatedConst, _)), _) => write!(w, "const ")?,
-        (Some(Def::Def(DefKind::Static, _)), _) =>
+        (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(|| {
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index b971de06bbf..a7e59e8368f 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -1105,20 +1105,22 @@ 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::Def(DefKind::Method, _) | Def::Def(DefKind::AssociatedConst, _) |
-                Def::Def(DefKind::AssociatedTy, _) | Def::Def(DefKind::AssociatedExistential, _) |
-                Def::Def(DefKind::Static, _) => Some(path.def),
-                _ => None,
-            }
-            hir::QPath::TypeRelative(..) => {
-                self.tables.type_dependent_def(id)
-            }
+        let def = match self.tables.qpath_def(qpath, id) {
+            Def::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::Def(DefKind::Static, _) = def {
+        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 {
@@ -1126,7 +1128,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
                     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;
             }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 5c7e51d4057..3be4ff77375 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -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::Def(DefKind::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")
@@ -487,8 +487,11 @@ impl<'a> Resolver<'a> {
             }
 
             ItemKind::Enum(ref enum_definition, _) => {
-                let def = Def::Def(DefKind::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,
@@ -565,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::Def(DefKind::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,
@@ -658,9 +661,10 @@ impl<'a> Resolver<'a> {
         let ident = ident.gensym_if_underscore();
         let expansion = Mark::root(); // FIXME(jseyfried) intercrate hygiene
         match def {
-            Def::Def(DefKind::Mod, def_id) | Def::Def(DefKind::Enum, def_id) => {
+            Def::Def(kind @ DefKind::Mod, def_id)
+            | Def::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);
@@ -691,7 +695,7 @@ impl<'a> Resolver<'a> {
                 }
             }
             Def::Def(DefKind::Trait, def_id) => {
-                let module_kind = ModuleKind::Def(def, 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,
@@ -746,7 +750,7 @@ impl<'a> Resolver<'a> {
              Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id })))
         };
 
-        let kind = ModuleKind::Def(Def::Def(DefKind::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);
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index a86319801dc..0329c78bdf6 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -56,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),
@@ -387,9 +387,9 @@ impl<'a> Resolver<'a> {
                     return false;
                 }
             }
-            (Def::Def(DefKind::Enum, _), PathSource::TupleStruct)
-                | (Def::Def(DefKind::Enum, _), PathSource::Expr(..))  => {
-                if let Some(variants) = self.collect_enum_variants(def) {
+            (Def::Def(DefKind::Enum, def_id), PathSource::TupleStruct)
+                | (Def::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"
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index f7b8103a521..ad8233fd554 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1133,7 +1133,7 @@ impl ModuleOrUniformRoot<'_> {
     fn same_def(lhs: Self, rhs: Self) -> bool {
         match (lhs, rhs) {
             (ModuleOrUniformRoot::Module(lhs),
-             ModuleOrUniformRoot::Module(rhs)) => lhs.def() == rhs.def(),
+             ModuleOrUniformRoot::Module(rhs)) => lhs.def_id() == rhs.def_id(),
             (ModuleOrUniformRoot::CrateRootAndExternPrelude,
              ModuleOrUniformRoot::CrateRootAndExternPrelude) |
             (ModuleOrUniformRoot::ExternPrelude, ModuleOrUniformRoot::ExternPrelude) |
@@ -1177,7 +1177,7 @@ enum ModuleKind {
     /// * A normal module ‒ either `mod from_file;` or `mod from_block { }`.
     /// * A trait or an enum (it implicitly contains associated types, methods and variant
     ///   constructors).
-    Def(Def, Name),
+    Def(DefKind, DefId, Name),
 }
 
 impl ModuleKind {
@@ -1185,7 +1185,7 @@ impl ModuleKind {
     pub fn name(&self) -> Option<Name> {
         match self {
             ModuleKind::Block(..) => None,
-            ModuleKind::Def(_, name) => Some(*name),
+            ModuleKind::Def(.., name) => Some(*name),
         }
     }
 }
@@ -1271,26 +1271,36 @@ impl<'a> ModuleData<'a> {
 
     fn def(&self) -> Option<Def> {
         match self.kind {
-            ModuleKind::Def(def, _) => Some(def),
+            ModuleKind::Def(kind, def_id, _) => Some(Def::Def(kind, def_id)),
+            _ => None,
+        }
+    }
+
+    fn def_kind(&self) -> Option<DefKind> {
+        match self.kind {
+            ModuleKind::Def(kind, ..) => Some(kind),
             _ => None,
         }
     }
 
     fn def_id(&self) -> Option<DefId> {
-        self.def().as_ref().map(Def::def_id)
+        match self.kind {
+            ModuleKind::Def(_, def_id, _) => Some(def_id),
+            _ => None,
+        }
     }
 
     // `self` resolves to the first module ancestor that `is_normal`.
     fn is_normal(&self) -> bool {
         match self.kind {
-            ModuleKind::Def(Def::Def(DefKind::Mod, _), _) => true,
+            ModuleKind::Def(DefKind::Mod, _, _) => true,
             _ => false,
         }
     }
 
     fn is_trait(&self) -> bool {
         match self.kind {
-            ModuleKind::Def(Def::Def(DefKind::Trait, _), _) => true,
+            ModuleKind::Def(DefKind::Trait, _, _) => true,
             _ => false,
         }
     }
@@ -1477,7 +1487,7 @@ impl<'a> NameBinding<'a> {
                 }, ..
             } => true,
             NameBindingKind::Module(
-                &ModuleData { kind: ModuleKind::Def(Def::Def(DefKind::Mod, def_id), _), .. }
+                &ModuleData { kind: ModuleKind::Def(DefKind::Mod, def_id, _), .. }
             ) => def_id.index == CRATE_DEF_INDEX,
             _ => false,
         }
@@ -1938,7 +1948,8 @@ impl<'a> Resolver<'a> {
                -> Resolver<'a> {
         let root_def_id = DefId::local(CRATE_DEF_INDEX);
         let root_module_kind = ModuleKind::Def(
-            Def::Def(DefKind::Mod, root_def_id),
+            DefKind::Mod,
+            root_def_id,
             keywords::Invalid.name(),
         );
         let graph_root = arenas.alloc_module(ModuleData {
@@ -4788,10 +4799,7 @@ impl<'a> Resolver<'a> {
         suggestions
     }
 
-    fn find_module(&mut self,
-                   module_def: Def)
-                   -> Option<(Module<'a>, ImportSuggestion)>
-    {
+    fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> {
         let mut result = None;
         let mut seen_modules = FxHashSet::default();
         let mut worklist = vec![(self.graph_root, Vec::new())];
@@ -4811,16 +4819,16 @@ impl<'a> Resolver<'a> {
                     // form the path
                     let mut path_segments = path_segments.clone();
                     path_segments.push(ast::PathSegment::from_ident(ident));
-                    if module.def() == Some(module_def) {
+                    let module_def_id = module.def_id().unwrap();
+                    if module_def_id == def_id {
                         let path = Path {
                             span: name_binding.span,
                             segments: path_segments,
                         };
-                        let did = module.def().and_then(|def| def.opt_def_id());
-                        result = Some((module, ImportSuggestion { did, path }));
+                        result = Some((module, ImportSuggestion { did: Some(def_id), path }));
                     } else {
                         // add the module to the lookup
-                        if seen_modules.insert(module.def_id().unwrap()) {
+                        if seen_modules.insert(module_def_id) {
                             worklist.push((module, path_segments));
                         }
                     }
@@ -4831,12 +4839,8 @@ impl<'a> Resolver<'a> {
         result
     }
 
-    fn collect_enum_variants(&mut self, enum_def: Def) -> Option<Vec<Path>> {
-        if let Def::Def(DefKind::Enum, _) = enum_def {} else {
-            panic!("Non-enum def passed to collect_enum_variants: {:?}", enum_def)
-        }
-
-        self.find_module(enum_def).map(|(enum_module, enum_import_suggestion)| {
+    fn collect_enum_variants(&mut self, def_id: DefId) -> Option<Vec<Path>> {
+        self.find_module(def_id).map(|(enum_module, enum_import_suggestion)| {
             self.populate_module_if_necessary(enum_module);
 
             let mut variants = Vec::new();
@@ -5089,8 +5093,8 @@ impl<'a> Resolver<'a> {
         }
 
         let container = match parent.kind {
-            ModuleKind::Def(Def::Def(DefKind::Mod, _), _) => "module",
-            ModuleKind::Def(Def::Def(DefKind::Trait, _), _) => "trait",
+            ModuleKind::Def(DefKind::Mod, _, _) => "module",
+            ModuleKind::Def(DefKind::Trait, _, _) => "trait",
             ModuleKind::Block(..) => "block",
             _ => "enum",
         };
@@ -5458,7 +5462,7 @@ fn module_to_string(module: Module<'_>) -> Option<String> {
     let mut names = Vec::new();
 
     fn collect_mod(names: &mut Vec<Ident>, module: Module<'_>) {
-        if let ModuleKind::Def(_, name) = module.kind {
+        if let ModuleKind::Def(.., name) = module.kind {
             if let Some(parent) = module.parent {
                 names.push(Ident::with_empty_ctxt(name));
                 collect_mod(names, parent);
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index eea48f0711f..3df09369f89 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -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);
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 6ad09b2f7e7..7dbc7536440 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -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;
         }
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 8807e1aa62a..241d77c2575 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1314,7 +1314,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
         qself_def: Def,
         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::Def(DefKind::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);
                     }
                 }
             }
@@ -1352,24 +1351,18 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                     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::Def(DefKind::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),
-                }
+                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::Def(DefKind::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()), &note_msg);
+                                       assoc_ident, also, kind.descr());
+                err.span_note(tcx.def_span(def_id), &note_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::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) |
-            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,8 +1620,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
             }
 
             // Case 2. Reference to a variant constructor.
-            Def::Def(DefKind::Ctor(CtorOf::Variant, ..), def_id)
-            | Def::Def(DefKind::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());
@@ -1641,11 +1632,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                     let mut def_id = def_id;
 
                     // `DefKind::Ctor` -> `DefKind::Variant`
-                    if let Def::Def(DefKind::Ctor(..), _) = def {
+                    if let DefKind::Ctor(..) = kind {
                         def_id = tcx.parent(def_id).unwrap()
                     }
 
-                    // `DefKind::Variant` -> `DefKind::Item` (enum)
+                    // `DefKind::Variant` -> `DefKind::Enum`
                     let enum_def_id = tcx.parent(def_id).unwrap();
                     (enum_def_id, last - 1)
                 } else {
@@ -1663,16 +1654,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
             }
 
             // Case 3. Reference to a top-level value.
-            Def::Def(DefKind::Fn, def_id) |
-            Def::Def(DefKind::Const, def_id) |
-            Def::Def(DefKind::ConstParam, def_id) |
-            Def::Def(DefKind::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::Def(DefKind::Method, def_id) |
-            Def::Def(DefKind::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));
@@ -1680,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);
@@ -1724,12 +1712,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                 self.prohibit_generics(path.segments.split_last().unwrap().1);
                 self.ast_path_to_ty(span, did, path.segments.last().unwrap())
             }
-            Def::Def(DefKind::Variant, _) if permit_variants => {
+            Def::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)| {
@@ -1854,7 +1843,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                 } else {
                     Def::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, def, 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);
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 537ea9a4b44..6fe7abda16d 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -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, DefKind};
 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::Def(DefKind::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,
         }
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index b0f0856615d..bbdc7df4441 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -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, DefKind};
+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,12 +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::Def(
+                    tcx.check_stability(ctor_def_id, Some(expr_id), span);
+                    return Ok((
                         DefKind::Ctor(CtorOf::Variant, variant_def.ctor_kind),
                         ctor_def_id,
-                    );
-                    tcx.check_stability(def.def_id(), Some(expr_id), span);
-                    return Ok(def);
+                    ));
                 }
             }
         }
@@ -442,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`
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 54260f196ce..8c61a127d10 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -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, DefKind};
+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::Def(DefKind::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()?;
 
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 2c567a86991..eef6627789d 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -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();
             }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 47974bc5564..95e20e4e170 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2149,7 +2149,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         self.tables
             .borrow_mut()
             .type_dependent_defs_mut()
-            .insert(hir_id, Def::Def(DefKind::Method, method.def_id));
+            .insert(hir_id, Ok((DefKind::Method, method.def_id)));
 
         self.write_substs(hir_id, method.substs);
 
@@ -4797,13 +4797,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 } else {
                     Def::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,
+                    def,
+                    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)| Def::Def(kind, def_id)).unwrap_or(Def::Err), ty)
             }
         }
     }
@@ -4827,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)| Def::Def(kind, def_id))
+                .unwrap_or(Def::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)| Def::Def(kind, def_id)).unwrap_or(Def::Err),
+            Some(ty),
+            slice::from_ref(&**item_segment),
+        )
     }
 
     pub fn check_decl_initializer(&self,
@@ -5355,7 +5369,11 @@ 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,
+        def: Def,
+        span: Span,
+    ) -> Result<(DefKind, DefId, Ty<'tcx>), ErrorReported> {
         let tcx = self.tcx;
         if let Def::SelfCtor(impl_def_id) = def {
             let ty = self.impl_self_ty(span, impl_def_id).ty;
@@ -5365,11 +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::Def(
+                    Ok((
                         DefKind::Ctor(CtorOf::Struct, variant.ctor_kind),
                         ctor_def_id,
-                    );
-                    (def, ctor_def_id, tcx.type_of(ctor_def_id))
+                        tcx.type_of(ctor_def_id),
+                    ))
                 }
                 _ => {
                     let mut err = tcx.sess.struct_span_err(span,
@@ -5392,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 def {
+                Def::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 def in rewrite_self_ctor: {:?}", def),
+            }
         }
     }
 
@@ -5434,13 +5455,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             _ => {}
         }
 
-        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(def, span) {
+            Ok(result) => result,
+            Err(ErrorReported) => return (tcx.types.err, def),
+        };
+        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::Def(DefKind::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 {
@@ -5450,10 +5475,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     is_alias_variant_ctor = true;
                 }
             }
-            Def::Def(DefKind::Method, def_id) |
-            Def::Def(DefKind::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)
@@ -5643,7 +5668,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                ty_substituted);
         self.write_substs(hir_id, substs);
 
-        (ty_substituted, def)
+        (ty_substituted, Def::Def(kind, def_id))
     }
 
     fn check_rustc_args_require_const(&self,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 95a2664954d..d252a935e35 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2787,11 +2787,10 @@ 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::Def(DefKind::TyParam, did) = path.def {
+                    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);
                     }
@@ -2811,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() {
@@ -2840,11 +2839,8 @@ impl Clean<Type> for hir::Ty {
                                     indices.lifetimes += 1;
                                 }
                                 hir::GenericParamKind::Type { ref default, .. } => {
-                                    let ty_param_def =
-                                        Def::Def(
-                                            DefKind::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 {
@@ -2859,19 +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::Def(
-                                            DefKind::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 {
@@ -2886,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;
@@ -2894,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)
             }
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 831adb301ef..5555ea302c9 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -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) = (

From ff174fe09e2e0a8f959b970e6ec410b3aafbc58a Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Sat, 20 Apr 2019 19:36:05 +0300
Subject: [PATCH 3/3] rustc: rename hir::def::Def to Res (short for
 "resolution").

---
 src/librustc/hir/def.rs                       | 114 ++--
 src/librustc/hir/lowering.rs                  | 136 ++---
 src/librustc/hir/mod.rs                       |  46 +-
 src/librustc/hir/pat_util.rs                  |  12 +-
 src/librustc/lint/internal.rs                 |   6 +-
 src/librustc/middle/dead.rs                   |  42 +-
 src/librustc/middle/expr_use_visitor.rs       |  28 +-
 src/librustc/middle/intrinsicck.rs            |  10 +-
 src/librustc/middle/liveness.rs               |  12 +-
 src/librustc/middle/mem_categorization.rs     |  58 +-
 src/librustc/middle/reachable.rs              |  24 +-
 src/librustc/middle/resolve_lifetime.rs       |  46 +-
 src/librustc/middle/stability.rs              |   6 +-
 src/librustc/ty/context.rs                    |   8 +-
 src/librustc/ty/mod.rs                        |  40 +-
 src/librustc/ty/print/pretty.rs               |   2 +-
 src/librustc/ty/structural_impls.rs           |   6 +-
 src/librustc_lint/builtin.rs                  |  14 +-
 src/librustc_lint/nonstandard_style.rs        |   4 +-
 src/librustc_lint/unused.rs                   |  11 +-
 src/librustc_metadata/cstore_impl.rs          |   4 +-
 src/librustc_metadata/decoder.rs              |  24 +-
 .../error_reporting/region_name.rs            |   6 +-
 src/librustc_mir/hair/cx/expr.rs              |  94 +--
 src/librustc_mir/hair/pattern/check_match.rs  |   2 +-
 src/librustc_mir/hair/pattern/mod.rs          |  52 +-
 src/librustc_passes/rvalue_promotion.rs       |  32 +-
 src/librustc_privacy/lib.rs                   |  34 +-
 src/librustc_resolve/build_reduced_graph.rs   | 162 ++---
 src/librustc_resolve/diagnostics.rs           |  58 +-
 src/librustc_resolve/lib.rs                   | 556 +++++++++---------
 src/librustc_resolve/macros.rs                | 134 ++---
 src/librustc_resolve/resolve_imports.rs       |  58 +-
 src/librustc_save_analysis/dump_visitor.rs    |  32 +-
 src/librustc_save_analysis/lib.rs             |  94 +--
 src/librustc_save_analysis/sig.rs             |  20 +-
 src/librustc_typeck/astconv.rs                |  66 +--
 src/librustc_typeck/check/_match.rs           |  60 +-
 src/librustc_typeck/check/callee.rs           |  14 +-
 src/librustc_typeck/check/compare_method.rs   |   4 +-
 src/librustc_typeck/check/demand.rs           |   2 +-
 src/librustc_typeck/check/method/suggest.rs   |  20 +-
 src/librustc_typeck/check/mod.rs              |  98 +--
 src/librustc_typeck/collect.rs                |  20 +-
 src/librustdoc/clean/inline.rs                |  51 +-
 src/librustdoc/clean/mod.rs                   | 122 ++--
 .../passes/collect_intra_doc_links.rs         | 160 ++---
 src/librustdoc/visit_ast.rs                   |  50 +-
 src/librustdoc/visit_lib.rs                   |  12 +-
 src/test/ui/imports/issue-53269.rs            |   2 +-
 src/test/ui/imports/issue-53512.rs            |   2 +-
 51 files changed, 1334 insertions(+), 1336 deletions(-)

diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index b9ba1aff8f4..6366c1f93e6 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -128,7 +128,7 @@ impl DefKind {
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
-pub enum Def<Id = hir::HirId> {
+pub enum Res<Id = hir::HirId> {
     Def(DefKind, DefId),
 
     // Type namespace
@@ -152,38 +152,38 @@ pub enum Def<Id = hir::HirId> {
 }
 
 /// 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]
@@ -270,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.
@@ -284,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.
@@ -297,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,
         }
@@ -334,85 +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::Def(_, 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::Def(DefKind::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::Def(kind, _) => kind.descr(),
-            Def::SelfCtor(..) => "self constructor",
-            Def::PrimTy(..) => "builtin type",
-            Def::Local(..) => "local variable",
-            Def::Upvar(..) => "closure capture",
-            Def::Label(..) => "label",
-            Def::SelfTy(..) => "self type",
-            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::Def(kind, _) => kind.article(),
-            Def::Err => "an",
+            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::Def(kind, id) => Def::Def(kind, id),
-            Def::SelfCtor(id) => Def::SelfCtor(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::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,
         }
     }
 }
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 583508bfb7e..8361a62c07e 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -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, DefKind, 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::Def(DefKind::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,43 +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::Def(DefKind::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::Def(DefKind::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::Def(DefKind::Struct, def_id)
-                        | Def::Def(DefKind::Union, def_id)
-                        | Def::Def(DefKind::Enum, def_id)
-                        | Def::Def(DefKind::TyAlias, def_id)
-                        | Def::Def(DefKind::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::Def(DefKind::Trait, _)
+                        Res::Def(DefKind::Trait, _)
                             if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
                         // `a::b::Trait(Args)::TraitItem`
-                        Def::Def(DefKind::Method, _)
-                        | Def::Def(DefKind::AssociatedConst, _)
-                        | Def::Def(DefKind::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::Def(DefKind::Struct, _)
-                        | Def::Def(DefKind::Enum, _)
-                        | Def::Def(DefKind::Union, _)
-                        | Def::Def(DefKind::TyAlias, _)
-                        | Def::Def(DefKind::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
                         }
@@ -2000,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| {
@@ -2026,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(
@@ -2159,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 {
@@ -2173,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,
         )
@@ -2791,9 +2791,9 @@ impl<'a> LoweringContext<'a> {
                                 if path.segments.len() == 1
                                     && bound_pred.bound_generic_params.is_empty() =>
                             {
-                                if let Some(Def::Def(DefKind::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)
@@ -3245,7 +3245,7 @@ impl<'a> LoweringContext<'a> {
                         });
 
                         if let Some(ref trait_ref) = trait_ref {
-                            if let Def::Def(DefKind::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);
                             }
@@ -3342,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();
@@ -3363,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,
@@ -3395,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 => {
@@ -3513,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)
             }
         }
@@ -3769,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())
                 {
@@ -3946,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,
                         };
 
@@ -3961,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)],
                         }),
                     )),
@@ -4957,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,
@@ -5073,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)],
             }),
         ));
@@ -5279,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::Def(DefKind::Trait, _) | Def::Def(DefKind::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 {
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 833983d3576..ae7358df9d8 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -10,7 +10,7 @@ pub use self::PrimTy::*;
 pub use self::UnOp::*;
 pub use self::UnsafeSource::*;
 
-use crate::hir::def::{Def, DefKind};
+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,11 +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::Def(DefKind::Static, _)
-                    | Def::Err => true,
+                match path.res {
+                    Res::Local(..)
+                    | Res::Upvar(..)
+                    | Res::Def(DefKind::Static, _)
+                    | Res::Err => true,
                     _ => false,
                 }
             }
@@ -2142,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,
@@ -2154,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::Def(DefKind::Trait, did) => did,
-            Def::Def(DefKind::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!(),
@@ -2479,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
@@ -2488,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)
         }
     }
 }
diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs
index a1ff3dcda2d..0d2c7d393bb 100644
--- a/src/librustc/hir/pat_util.rs
+++ b/src/librustc/hir/pat_util.rs
@@ -1,4 +1,4 @@
-use crate::hir::def::{CtorOf, Def, DefKind};
+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::Def(DefKind::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::Def(DefKind::Variant, id) => variants.push(id),
-                        Def::Def(DefKind::Ctor(CtorOf::Variant, ..), id) => variants.push(id),
+                    match path.res {
+                        Res::Def(DefKind::Variant, id) => variants.push(id),
+                        Res::Def(DefKind::Ctor(CtorOf::Variant, ..), id) => variants.push(id),
                         _ => ()
                     }
                 }
diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs
index 126a7cd3349..c7802620976 100644
--- a/src/librustc/lint/internal.rs
+++ b/src/librustc/lint/internal.rs
@@ -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"]) {
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index a58fb1a933e..a0107ed0546 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -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, DefKind};
+use crate::hir::def::{CtorOf, Res, DefKind};
 use crate::hir::CodegenFnAttrFlags;
 use crate::hir::def_id::{DefId, LOCAL_CRATE};
 use crate::lint;
@@ -68,17 +68,17 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
         }
     }
 
-    fn handle_definition(&mut self, def: Def) {
-        match def {
-            Def::Def(DefKind::Const, _)
-            | Def::Def(DefKind::AssociatedConst, _)
-            | Def::Def(DefKind::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::Def(DefKind::Ctor(CtorOf::Variant, ..), ctor_def_id) => {
+            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);
@@ -86,16 +86,16 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                     self.check_def_id(variant_id);
                 }
             }
-            Def::Def(DefKind::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());
             }
         }
     }
@@ -119,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 {
@@ -231,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);
@@ -270,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);
             }
             _ => ()
         }
@@ -285,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);
     }
 
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 149f9fe96f6..cf3f613b08e 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -9,7 +9,7 @@ pub use self::MatchMode::*;
 use self::TrackMatchMode::*;
 use self::OverloadedCallType::*;
 
-use crate::hir::def::{CtorOf, Def, DefKind};
+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,27 +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::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_did) => {
+            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::Def(DefKind::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::Def(DefKind::Struct, _)
-                | Def::Def(DefKind::Ctor(..), _)
-                | Def::Def(DefKind::Union, _)
-                | Def::Def(DefKind::TyAlias, _)
-                | Def::Def(DefKind::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);
                 }
@@ -972,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)
     }
 }
 
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index 507aff69005..5c28d480571 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -1,4 +1,4 @@
-use crate::hir::def::{Def, DefKind};
+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::Def(DefKind::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);
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 2ae53a5df3a..15736218a79 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -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
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 21c7152ed7d..f6caf357b39 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -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, DefKind, 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,27 +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::Def(DefKind::Ctor(..), _)
-            | Def::Def(DefKind::Const, _)
-            | Def::Def(DefKind::ConstParam, _)
-            | Def::Def(DefKind::AssociatedConst, _)
-            | Def::Def(DefKind::Fn, _)
-            | Def::Def(DefKind::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::Def(DefKind::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)[..]
@@ -736,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,
@@ -1273,21 +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::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), variant_ctor_did) => {
+                    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::Def(DefKind::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, _) => {
@@ -1316,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::Def(DefKind::Ctor(CtorOf::Variant, _), variant_ctor_did) => {
+                    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::Def(DefKind::Variant, variant_did) => {
+                    Res::Def(DefKind::Variant, variant_did) => {
                         self.cat_downcast_if_needed(pat, cmt, variant_did)
                     }
                     _ => cmt,
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index a68be387d61..e58083b5b76 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -7,7 +7,7 @@
 
 use crate::hir::{CodegenFnAttrs, CodegenFnAttrFlags};
 use crate::hir::Node;
-use crate::hir::def::{Def, DefKind};
+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,33 +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)| Def::Def(kind, def_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::Def(DefKind::Const, _) | Def::Def(DefKind::AssociatedConst, _) => {
+                            Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssociatedConst, _) => {
                                 self.worklist.push(hir_id);
                             }
 
@@ -357,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::Def(DefKind::Trait, def_id) => def_id,
+                let trait_def_id = match trait_ref.path.res {
+                    Res::Def(DefKind::Trait, def_id) => def_id,
                     _ => unreachable!()
                 };
 
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 1e886c08d41..d835d872d76 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -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, DefKind};
+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::Def(DefKind::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,16 +1928,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                 index: def_key.parent.expect("missing parent"),
             }
         };
-        let type_def_id = match def {
-            Def::Def(DefKind::AssociatedTy, def_id)
+        let type_def_id = match res {
+            Res::Def(DefKind::AssociatedTy, def_id)
                 if depth == 1 => Some(parent_def_id(self, def_id)),
-            Def::Def(DefKind::Variant, def_id)
+            Res::Def(DefKind::Variant, def_id)
                 if depth == 0 => Some(parent_def_id(self, def_id)),
-            Def::Def(DefKind::Struct, def_id)
-            | Def::Def(DefKind::Union, def_id)
-            | Def::Def(DefKind::Enum, def_id)
-            | Def::Def(DefKind::TyAlias, def_id)
-            | Def::Def(DefKind::Trait, def_id) if depth == 0 =>
+            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)
             }
@@ -2128,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;
                 }
 
@@ -2137,15 +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::Def(DefKind::Struct, _)
-                        | Def::Def(DefKind::Union, _)
-                        | Def::Def(DefKind::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
                         }
                         _ => {}
                     }
@@ -2156,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),
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index c57b62f42d5..5078bd7c594 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -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, DefKind};
+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;
@@ -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::Def(DefKind::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)
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index dfc9e8140bb..fddae024091 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -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, DefKind, 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;
@@ -479,11 +479,11 @@ 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::Resolved(_, ref path) => path.res,
             hir::QPath::TypeRelative(..) => self.type_dependent_def(id)
-                .map_or(Def::Err, |(kind, def_id)| Def::Def(kind, def_id)),
+                .map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
         }
     }
 
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 3d08dc67005..ffd34c7cdc3 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -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, DefKind, 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;
@@ -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::Def(DefKind::Variant, vid) => self.variant_with_id(vid),
-            Def::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid),
-            Def::Def(DefKind::Struct, _) | Def::Def(DefKind::Union, _) |
-            Def::Def(DefKind::TyAlias, _) | Def::Def(DefKind::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)
         }
     }
 
@@ -2950,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::Def(DefKind::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::Def(DefKind::Struct, did) | Def::Def(DefKind::Union, did) => {
+            Res::Def(DefKind::Struct, did) | Res::Def(DefKind::Union, did) => {
                 self.adt_def(did).non_enum_variant()
             }
-            Def::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_did) => {
+            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::Def(DefKind::Ctor(CtorOf::Struct, ..), ctor_did) => {
+            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)
         }
     }
 
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index d2cc2514536..d10da495ee7 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -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;
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index 504b939c5f2..bab9527dd07 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -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
     }
 }
 
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 8f583f3546b..f70429c22b6 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -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, DefKind};
+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::Def(DefKind::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::Def(DefKind::TyParam, _) => true,
+                        match path.res {
+                            Res::Def(DefKind::TyParam, _) => true,
                             _ => false
                         }
                     }
diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs
index 7e6af43c500..7a003d14b2b 100644
--- a/src/librustc_lint/nonstandard_style.rs
+++ b/src/librustc_lint/nonstandard_style.rs
@@ -1,5 +1,5 @@
 use rustc::hir::{self, GenericParamKind, PatKind};
-use rustc::hir::def::{Def, DefKind};
+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::Def(DefKind::Const, _) = path.def {
+            if let Res::Def(DefKind::Const, _) = path.res {
                 if path.segments.len() == 1 {
                     NonUpperCaseGlobals::check_upper_case(
                         cx,
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 5155ac410aa..92508ad51f1 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -1,4 +1,4 @@
-use rustc::hir::def::{Def, DefKind};
+use rustc::hir::def::{Res, DefKind};
 use rustc::hir::def_id::DefId;
 use rustc::lint;
 use rustc::ty;
@@ -91,11 +91,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
             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::Def(DefKind::Fn, def_id)
-                            | Def::Def(DefKind::Method, def_id) => Some(def_id),
-                            // `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
                         }
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 892a7a8355c..dfeaeca323f 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -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) }
@@ -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) => {
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 5e71a74c9bb..ad28f47ba04 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -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, DefKind, 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;
@@ -743,14 +743,14 @@ impl<'a, 'tcx> CrateMetadata {
              */
             if id == CRATE_DEF_INDEX {
                 for (id, &(name, ref ext)) in proc_macros.iter().enumerate() {
-                    let def = Def::Def(
+                    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,
                     });
@@ -788,7 +788,7 @@ impl<'a, 'tcx> CrateMetadata {
                         for child_index in child.children.decode((self, sess)) {
                             if let Some(kind) = self.def_kind(child_index) {
                                 callback(def::Export {
-                                    def: Def::Def(kind, self.local_def_id(child_index)),
+                                    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)),
@@ -809,20 +809,20 @@ impl<'a, 'tcx> CrateMetadata {
                     let ident = Ident::from_interned_str(name);
                     let vis = self.get_visibility(child_index);
                     let def_id = self.local_def_id(child_index);
-                    let def = Def::Def(kind, def_id);
-                    callback(def::Export { def, ident, vis, span });
+                    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 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::Def(
+                                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 });
                             }
                         }
                         DefKind::Variant => {
@@ -832,7 +832,7 @@ impl<'a, 'tcx> CrateMetadata {
                             // 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::Def(
+                            let ctor_res = Res::Def(
                                 DefKind::Ctor(CtorOf::Variant, ctor_kind),
                                 ctor_def_id,
                             );
@@ -848,7 +848,7 @@ impl<'a, 'tcx> CrateMetadata {
                                     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 });
                         }
                         _ => {}
                     }
@@ -858,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::Def(DefKind::Macro(..), _) => {}
+                match exp.res {
+                    Res::Def(DefKind::Macro(..), _) => {}
                     _ if macros_only => continue,
                     _ => {}
                 }
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
index 4a636fa87c6..4e197867bfb 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
@@ -4,7 +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::{Def, DefKind};
+use rustc::hir::def::{Res, DefKind};
 use rustc::hir::def_id::DefId;
 use rustc::infer::InferCtxt;
 use rustc::mir::Mir;
@@ -492,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.
-                        Def::Def(DefKind::TyAlias, _) => (),
+                        Res::Def(DefKind::TyAlias, _) => (),
                         _ => if let Some(last_segment) = path.segments.last() {
                             if let Some(name) = self.match_adt_and_segment(
                                 substs,
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 51bb4134341..5ac1ccd8fad 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -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, DefKind, 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::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) =>
+                        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::Def(DefKind::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,14 @@ 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::Def(
+                        match res {
+                            Res::Def(
                                 DefKind::Ctor(CtorOf::Variant, CtorKind::Const),
                                 variant_ctor_id,
                             ) => {
@@ -785,38 +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::Def(DefKind::Fn, _) |
-        Def::Def(DefKind::Method, _) |
-        Def::Def(DefKind::Ctor(_, CtorKind::Fn), _) |
-        Def::Def(DefKind::Const, _) |
-        Def::Def(DefKind::AssociatedConst, _) =>
+        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::Def(DefKind::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
 }
 
@@ -834,7 +834,7 @@ fn method_callee<'a, 'gcx, 'tcx>(
                 .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::Def(kind, def_id));
+            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_id, cx.tables().node_substs(expr.hir_id), user_ty)
         }
@@ -894,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::Def(DefKind::Fn, _) |
-        Def::Def(DefKind::Method, _) |
-        Def::Def(DefKind::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(
@@ -913,7 +913,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             }
         }
 
-        Def::Def(DefKind::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);
@@ -932,9 +932,9 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             }
         }
 
-        Def::Def(DefKind::Const, def_id) |
-        Def::Def(DefKind::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 {
@@ -945,7 +945,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             }
         },
 
-        Def::Def(DefKind::Ctor(_, CtorKind::Const), def_id) => {
+        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);
@@ -967,24 +967,24 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             }
         }
 
-        Def::Def(DefKind::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,
@@ -1202,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(),
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index d6a6b111f49..b08499b981c 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -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),
             };
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 90551d8d167..01b1780a205 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -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, DefKind, 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::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => {
+        let res = match res {
+            Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => {
                 let variant_id = self.tcx.parent(variant_ctor_id).unwrap();
-                Def::Def(DefKind::Variant, variant_id)
+                Res::Def(DefKind::Variant, variant_id)
             },
-            def => def,
+            res => res,
         };
 
-        let mut kind = match def {
-            Def::Def(DefKind::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,13 +764,13 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                 }
             }
 
-            Def::Def(DefKind::Struct, _)
-            | Def::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
-            | Def::Def(DefKind::Union, _)
-            | Def::Def(DefKind::TyAlias, _)
-            | Def::Def(DefKind::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 }
             }
 
@@ -808,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::Def(DefKind::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::Def(DefKind::Const, def_id) | Def::Def(DefKind::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,
@@ -876,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 {
diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs
index 57cea198c72..b6e2aacd559 100644
--- a/src/librustc_passes/rvalue_promotion.rs
+++ b/src/librustc_passes/rvalue_promotion.rs
@@ -15,7 +15,7 @@
 // by borrowck::gather_loans
 
 use rustc::ty::cast::CastTy;
-use rustc::hir::def::{Def, DefKind, 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,19 +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::Def(DefKind::Ctor(..), _)
-                | Def::Def(DefKind::Fn, _)
-                | Def::Def(DefKind::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::Def(DefKind::Static, did) => {
+                Res::Def(DefKind::Static, did) => {
 
                     if v.in_static {
                         for attr in &v.tcx.get_attrs(did)[..] {
@@ -349,8 +349,8 @@ fn check_expr_kind<'a, 'tcx>(
                     }
                 }
 
-                Def::Def(DefKind::Const, did) |
-                Def::Def(DefKind::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
@@ -384,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::Def(DefKind::Ctor(_, CtorKind::Fn), _) |
-                Def::SelfCtor(..) => Promotable,
-                Def::Def(DefKind::Fn, did) => v.handle_const_fn_call(did),
-                Def::Def(DefKind::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,
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index a7e59e8368f..e561b387389 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -12,7 +12,7 @@
 
 use rustc::bug;
 use rustc::hir::{self, Node, PatKind, AssociatedItemKind};
-use rustc::hir::def::{Def, DefKind};
+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,8 +1105,8 @@ 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 self.tables.qpath_def(qpath, id) {
-            Def::Def(kind, def_id) => Some((kind, def_id)),
+        let def = match self.tables.qpath_res(qpath, id) {
+            Res::Def(kind, def_id) => Some((kind, def_id)),
             _ => None,
         };
         let def = def.filter(|(kind, _)| {
@@ -1231,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:
@@ -1353,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)
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 3be4ff77375..3c5760c746f 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -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,
@@ -443,33 +443,33 @@ impl<'a> Resolver<'a> {
 
             // These items live in the value namespace.
             ItemKind::Static(..) => {
-                let def = Def::Def(DefKind::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::Def(DefKind::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::Def(DefKind::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::Def(DefKind::Macro(MacroKind::ProcMacroStub), def.def_id());
-                    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::Def(
+                            let res = Res::Def(
                                 DefKind::Macro(MacroKind::ProcMacroStub),
-                                def.def_id(),
+                                res.def_id(),
                             );
-                            self.define(parent, ident, MacroNS, (def, vis, ident.span, expansion));
+                            self.define(parent, ident, MacroNS, (res, vis, ident.span, expansion));
                         }
                     }
                 }
@@ -477,13 +477,13 @@ impl<'a> Resolver<'a> {
 
             // These items live in the type namespace.
             ItemKind::Ty(..) => {
-                let def = Def::Def(DefKind::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::Def(DefKind::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, _) => {
@@ -505,16 +505,16 @@ impl<'a> Resolver<'a> {
             }
 
             ItemKind::TraitAlias(..) => {
-                let def = Def::Def(DefKind::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::Def(DefKind::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;
 
@@ -540,18 +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::Def(
+                    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_def, ctor_vis, sp, expansion));
-                    self.struct_constructors.insert(def.def_id(), (ctor_def, ctor_vis));
+                    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::Def(DefKind::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| {
@@ -593,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::Def(DefKind::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.
@@ -612,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::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
-        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::Def(DefKind::Fn, self.definitions.local_def_id(item.id)), ValueNS)
+                (Res::Def(DefKind::Fn, self.definitions.local_def_id(item.id)), ValueNS)
             }
             ForeignItemKind::Static(..) => {
-                (Def::Def(DefKind::Static, self.definitions.local_def_id(item.id)), ValueNS)
+                (Res::Def(DefKind::Static, self.definitions.local_def_id(item.id)), ValueNS)
             }
             ForeignItemKind::Ty => {
-                (Def::Def(DefKind::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) {
@@ -649,20 +649,20 @@ 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::Def(kind @ DefKind::Mod, def_id)
-            | Def::Def(kind @ DefKind::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(kind, def_id, ident.name),
                                              def_id,
@@ -670,31 +670,31 @@ impl<'a> Resolver<'a> {
                                              span);
                 self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
             }
-            Def::Def(DefKind::Variant, _)
-            | Def::Def(DefKind::TyAlias, _)
-            | Def::Def(DefKind::ForeignTy, _)
-            | Def::Def(DefKind::Existential, _)
-            | Def::Def(DefKind::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::Def(DefKind::Fn, _)
-            | Def::Def(DefKind::Static, _)
-            | Def::Def(DefKind::Const, _)
-            | Def::Def(DefKind::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::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) => {
-                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::Def(DefKind::Trait, def_id) => {
+            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,
@@ -704,31 +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::Def(DefKind::AssociatedTy, _) = def {
+                    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::Def(DefKind::Struct, def_id) | Def::Def(DefKind::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::Def(DefKind::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)
         }
     }
 
@@ -769,13 +769,13 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    pub fn get_macro(&mut self, def: Def) -> Lrc<SyntaxExtension> {
-        let def_id = match def {
-            Def::Def(DefKind::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 `DefKind::Macro` or `Def::NonMacroAttr`"),
+            _ => panic!("expected `DefKind::Macro` or `Res::NonMacroAttr`"),
         };
         if let Some(ext) = self.macro_map.get(&def_id) {
             return ext.clone();
@@ -801,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)
     }
@@ -1032,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::Def(DefKind::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::Def(DefKind::Method, item_def_id), ValueNS)
+                (Res::Def(DefKind::Method, item_def_id), ValueNS)
             }
-            TraitItemKind::Type(..) => (Def::Def(DefKind::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);
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 0329c78bdf6..bbfc39fc6ea 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -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,22 +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::Def(DefKind::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 {
@@ -113,14 +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<_>>();
         let crate_def_id = DefId::local(CRATE_DEF_INDEX);
-        if candidates.is_empty() && is_expected(Def::Def(DefKind::Enum, crate_def_id)) {
+        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()
@@ -132,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(),
@@ -224,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);
@@ -301,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) => {
@@ -364,8 +364,8 @@ impl<'a> Resolver<'a> {
             }
         };
 
-        match (def, source) {
-            (Def::Def(DefKind::Macro(..), _), _) => {
+        match (res, source) {
+            (Res::Def(DefKind::Macro(..), _), _) => {
                 err.span_suggestion(
                     span,
                     "use `!` to invoke the macro",
@@ -376,19 +376,19 @@ impl<'a> Resolver<'a> {
                     err.note("if you want the `try` keyword, you need to be in the 2018 edition");
                 }
             }
-            (Def::Def(DefKind::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::Def(DefKind::Mod, _), PathSource::Expr(Some(parent))) => {
+            (Res::Def(DefKind::Mod, _), PathSource::Expr(Some(parent))) => {
                 if !path_sep(err, &parent) {
                     return false;
                 }
             }
-            (Def::Def(DefKind::Enum, def_id), PathSource::TupleStruct)
-                | (Def::Def(DefKind::Enum, def_id), PathSource::Expr(..))  => {
+            (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 {
@@ -408,7 +408,7 @@ impl<'a> Resolver<'a> {
                     err.note("did you mean to use one of the enum's variants?");
                 }
             },
-            (Def::Def(DefKind::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);
@@ -422,17 +422,17 @@ impl<'a> Resolver<'a> {
                     bad_struct_syntax_suggestion();
                 }
             }
-            (Def::Def(DefKind::Union, _), _) |
-            (Def::Def(DefKind::Variant, _), _) |
-            (Def::Def(DefKind::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::Def(DefKind::TyAlias, _), _)
-            | (Def::Def(DefKind::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,
@@ -628,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::Def(DefKind::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 =>
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index ad8233fd554..e0892f98d31 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -24,7 +24,7 @@ use rustc::middle::cstore::CrateStore;
 use rustc::session::Session;
 use rustc::lint;
 use rustc::hir::def::{
-    self, DefKind, PathResolution, CtorKind, CtorOf, NonMacroAttrKind, DefMap, ImportMap, ExportMap
+    self, DefKind, PathResolution, CtorKind, CtorOf, NonMacroAttrKind, ResMap, ImportMap, ExportMap
 };
 use rustc::hir::def::Namespace::*;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
@@ -71,7 +71,7 @@ use diagnostics::{find_span_of_binding_until_next_binding, extend_span_to_previo
 use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver};
 use macros::{InvocationData, LegacyBinding, ParentScope};
 
-type Def = def::Def<NodeId>;
+type Res = def::Res<NodeId>;
 
 // N.B., this module needs to be declared first so diagnostics are
 // registered before they are used.
@@ -151,7 +151,7 @@ type Suggestion = (Vec<(Span, String)>, String, Applicability);
 
 enum ResolutionError<'a> {
     /// Error E0401: can't use type or const parameters from outer function.
-    GenericParamsFromOuterFunction(Def),
+    GenericParamsFromOuterFunction(Res),
     /// Error E0403: the name is already used for a type or const parameter in this generic
     /// parameter list.
     NameAlreadyUsedInParameterList(Name, &'a Span),
@@ -206,7 +206,7 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
                                    resolution_error: ResolutionError<'a>)
                                    -> DiagnosticBuilder<'sess> {
     match resolution_error {
-        ResolutionError::GenericParamsFromOuterFunction(outer_def) => {
+        ResolutionError::GenericParamsFromOuterFunction(outer_res) => {
             let mut err = struct_span_err!(resolver.session,
                 span,
                 E0401,
@@ -215,8 +215,8 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
             err.span_label(span, format!("use of generic parameter from outer function"));
 
             let cm = resolver.session.source_map();
-            match outer_def {
-                Def::SelfTy(maybe_trait_defid, maybe_impl_defid) => {
+            match outer_res {
+                Res::SelfTy(maybe_trait_defid, maybe_impl_defid) => {
                     if let Some(impl_span) = maybe_impl_defid.and_then(|def_id| {
                         resolver.definitions.opt_span(def_id)
                     }) {
@@ -236,18 +236,18 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
                     }
                     return err;
                 },
-                Def::Def(DefKind::TyParam, def_id) => {
+                Res::Def(DefKind::TyParam, def_id) => {
                     if let Some(span) = resolver.definitions.opt_span(def_id) {
                         err.span_label(span, "type parameter from outer function");
                     }
                 }
-                Def::Def(DefKind::ConstParam, def_id) => {
+                Res::Def(DefKind::ConstParam, def_id) => {
                     if let Some(span) = resolver.definitions.opt_span(def_id) {
                         err.span_label(span, "const parameter from outer function");
                     }
                 }
                 _ => {
-                    bug!("GenericParamsFromOuterFunction should only be used with Def::SelfTy, \
+                    bug!("GenericParamsFromOuterFunction should only be used with Res::SelfTy, \
                          DefKind::TyParam");
                 }
             }
@@ -578,73 +578,73 @@ impl<'a> PathSource<'a> {
         }
     }
 
-    fn is_expected(self, def: Def) -> bool {
+    fn is_expected(self, res: Res) -> bool {
         match self {
-            PathSource::Type => match def {
-                Def::Def(DefKind::Struct, _)
-                | Def::Def(DefKind::Union, _)
-                | Def::Def(DefKind::Enum, _)
-                | Def::Def(DefKind::Trait, _)
-                | Def::Def(DefKind::TraitAlias, _)
-                | Def::Def(DefKind::TyAlias, _)
-                | Def::Def(DefKind::AssociatedTy, _)
-                | Def::PrimTy(..)
-                | Def::Def(DefKind::TyParam, _)
-                | Def::SelfTy(..)
-                | Def::Def(DefKind::Existential, _)
-                | Def::Def(DefKind::ForeignTy, _) => true,
+            PathSource::Type => match res {
+                Res::Def(DefKind::Struct, _)
+                | Res::Def(DefKind::Union, _)
+                | Res::Def(DefKind::Enum, _)
+                | Res::Def(DefKind::Trait, _)
+                | Res::Def(DefKind::TraitAlias, _)
+                | Res::Def(DefKind::TyAlias, _)
+                | Res::Def(DefKind::AssociatedTy, _)
+                | Res::PrimTy(..)
+                | Res::Def(DefKind::TyParam, _)
+                | Res::SelfTy(..)
+                | Res::Def(DefKind::Existential, _)
+                | Res::Def(DefKind::ForeignTy, _) => true,
                 _ => false,
             },
-            PathSource::Trait(AliasPossibility::No) => match def {
-                Def::Def(DefKind::Trait, _) => true,
+            PathSource::Trait(AliasPossibility::No) => match res {
+                Res::Def(DefKind::Trait, _) => true,
                 _ => false,
             },
-            PathSource::Trait(AliasPossibility::Maybe) => match def {
-                Def::Def(DefKind::Trait, _) => true,
-                Def::Def(DefKind::TraitAlias, _) => true,
+            PathSource::Trait(AliasPossibility::Maybe) => match res {
+                Res::Def(DefKind::Trait, _) => true,
+                Res::Def(DefKind::TraitAlias, _) => true,
                 _ => false,
             },
-            PathSource::Expr(..) => match def {
-                Def::Def(DefKind::Ctor(_, CtorKind::Const), _)
-                | Def::Def(DefKind::Ctor(_, CtorKind::Fn), _)
-                | Def::Def(DefKind::Const, _)
-                | Def::Def(DefKind::Static, _)
-                | Def::Local(..)
-                | Def::Upvar(..)
-                | Def::Def(DefKind::Fn, _)
-                | Def::Def(DefKind::Method, _)
-                | Def::Def(DefKind::AssociatedConst, _)
-                | Def::SelfCtor(..)
-                | Def::Def(DefKind::ConstParam, _) => true,
+            PathSource::Expr(..) => match res {
+                Res::Def(DefKind::Ctor(_, CtorKind::Const), _)
+                | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
+                | Res::Def(DefKind::Const, _)
+                | Res::Def(DefKind::Static, _)
+                | Res::Local(..)
+                | Res::Upvar(..)
+                | Res::Def(DefKind::Fn, _)
+                | Res::Def(DefKind::Method, _)
+                | Res::Def(DefKind::AssociatedConst, _)
+                | Res::SelfCtor(..)
+                | Res::Def(DefKind::ConstParam, _) => true,
                 _ => false,
             },
-            PathSource::Pat => match def {
-                Def::Def(DefKind::Ctor(_, CtorKind::Const), _) |
-                Def::Def(DefKind::Const, _) | Def::Def(DefKind::AssociatedConst, _) |
-                Def::SelfCtor(..) => true,
+            PathSource::Pat => match res {
+                Res::Def(DefKind::Ctor(_, CtorKind::Const), _) |
+                Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssociatedConst, _) |
+                Res::SelfCtor(..) => true,
                 _ => false,
             },
-            PathSource::TupleStruct => match def {
-                Def::Def(DefKind::Ctor(_, CtorKind::Fn), _) | Def::SelfCtor(..) => true,
+            PathSource::TupleStruct => match res {
+                Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) | Res::SelfCtor(..) => true,
                 _ => false,
             },
-            PathSource::Struct => match def {
-                Def::Def(DefKind::Struct, _)
-                | Def::Def(DefKind::Union, _)
-                | Def::Def(DefKind::Variant, _)
-                | Def::Def(DefKind::TyAlias, _)
-                | Def::Def(DefKind::AssociatedTy, _)
-                | Def::SelfTy(..) => true,
+            PathSource::Struct => match res {
+                Res::Def(DefKind::Struct, _)
+                | Res::Def(DefKind::Union, _)
+                | Res::Def(DefKind::Variant, _)
+                | Res::Def(DefKind::TyAlias, _)
+                | Res::Def(DefKind::AssociatedTy, _)
+                | Res::SelfTy(..) => true,
                 _ => false,
             },
-            PathSource::TraitItem(ns) => match def {
-                Def::Def(DefKind::AssociatedConst, _)
-                | Def::Def(DefKind::Method, _) if ns == ValueNS => true,
-                Def::Def(DefKind::AssociatedTy, _) if ns == TypeNS => true,
+            PathSource::TraitItem(ns) => match res {
+                Res::Def(DefKind::AssociatedConst, _)
+                | Res::Def(DefKind::Method, _) if ns == ValueNS => true,
+                Res::Def(DefKind::AssociatedTy, _) if ns == TypeNS => true,
                 _ => false,
             },
-            PathSource::Visibility => match def {
-                Def::Def(DefKind::Mod, _) => true,
+            PathSource::Visibility => match res {
+                Res::Def(DefKind::Mod, _) => true,
                 _ => false,
             },
         }
@@ -819,9 +819,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
             }
             TyKind::ImplicitSelf => {
                 let self_ty = keywords::SelfUpper.ident();
-                let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span)
-                              .map_or(Def::Err, |d| d.def());
-                self.record_def(ty.id, PathResolution::new(def));
+                let res = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span)
+                              .map_or(Res::Err, |d| d.res());
+                self.record_res(ty.id, PathResolution::new(res));
             }
             _ => (),
         }
@@ -951,7 +951,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
                 GenericParamKind::Type { ref default, .. } => {
                     found_default |= default.is_some();
                     if found_default {
-                        Some((Ident::with_empty_ctxt(param.ident.name), Def::Err))
+                        Some((Ident::with_empty_ctxt(param.ident.name), Res::Err))
                     } else {
                         None
                     }
@@ -968,7 +968,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
                     false
                 }
             })
-            .map(|param| (Ident::with_empty_ctxt(param.ident.name), Def::Err)));
+            .map(|param| (Ident::with_empty_ctxt(param.ident.name), Res::Err)));
 
         for param in &generics.params {
             match param.kind {
@@ -1017,7 +1017,7 @@ enum GenericParameters<'a, 'b> {
 }
 
 /// The rib kind controls the translation of local
-/// definitions (`Def::Local`) to upvars (`Def::Upvar`).
+/// definitions (`Res::Local`) to upvars (`Res::Upvar`).
 #[derive(Copy, Clone, Debug)]
 enum RibKind<'a> {
     /// No translation needs to be applied.
@@ -1072,7 +1072,7 @@ enum RibKind<'a> {
 /// resolving, the name is looked up from inside out.
 #[derive(Debug)]
 struct Rib<'a> {
-    bindings: FxHashMap<Ident, Def>,
+    bindings: FxHashMap<Ident, Res>,
     kind: RibKind<'a>,
 }
 
@@ -1087,12 +1087,12 @@ impl<'a> Rib<'a> {
 
 /// An intermediate resolution result.
 ///
-/// This refers to the thing referred by a name. The difference between `Def` and `Item` is that
-/// items are visible in their whole block, while defs only from the place they are defined
+/// This refers to the thing referred by a name. The difference between `Res` and `Item` is that
+/// items are visible in their whole block, while `Res`es only from the place they are defined
 /// forward.
 enum LexicalScopeBinding<'a> {
     Item(&'a NameBinding<'a>),
-    Def(Def),
+    Res(Res),
 }
 
 impl<'a> LexicalScopeBinding<'a> {
@@ -1103,10 +1103,10 @@ impl<'a> LexicalScopeBinding<'a> {
         }
     }
 
-    fn def(self) -> Def {
+    fn res(self) -> Res {
         match self {
-            LexicalScopeBinding::Item(binding) => binding.def(),
-            LexicalScopeBinding::Def(def) => def,
+            LexicalScopeBinding::Item(binding) => binding.res(),
+            LexicalScopeBinding::Res(res) => res,
         }
     }
 }
@@ -1202,7 +1202,7 @@ pub struct ModuleData<'a> {
     single_segment_macro_resolutions: RefCell<Vec<(Ident, MacroKind, ParentScope<'a>,
                                                    Option<&'a NameBinding<'a>>)>>,
     multi_segment_macro_resolutions: RefCell<Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'a>,
-                                                  Option<Def>)>>,
+                                                  Option<Res>)>>,
     builtin_attrs: RefCell<Vec<(Ident, ParentScope<'a>)>>,
 
     // Macro invocations that can expand into items in this module.
@@ -1269,9 +1269,9 @@ impl<'a> ModuleData<'a> {
         }
     }
 
-    fn def(&self) -> Option<Def> {
+    fn res(&self) -> Option<Res> {
         match self.kind {
-            ModuleKind::Def(kind, def_id, _) => Some(Def::Def(kind, def_id)),
+            ModuleKind::Def(kind, def_id, _) => Some(Res::Def(kind, def_id)),
             _ => None,
         }
     }
@@ -1323,7 +1323,7 @@ impl<'a> ModuleData<'a> {
 
 impl<'a> fmt::Debug for ModuleData<'a> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{:?}", self.def())
+        write!(f, "{:?}", self.res())
     }
 }
 
@@ -1349,7 +1349,7 @@ impl<'a> ToNameBinding<'a> for &'a NameBinding<'a> {
 
 #[derive(Clone, Debug)]
 enum NameBindingKind<'a> {
-    Def(Def, /* is_macro_export */ bool),
+    Res(Res, /* is_macro_export */ bool),
     Module(Module<'a>),
     Import {
         binding: &'a NameBinding<'a>,
@@ -1447,11 +1447,11 @@ impl<'a> NameBinding<'a> {
         }
     }
 
-    fn def(&self) -> Def {
+    fn res(&self) -> Res {
         match self.kind {
-            NameBindingKind::Def(def, _) => def,
-            NameBindingKind::Module(module) => module.def().unwrap(),
-            NameBindingKind::Import { binding, .. } => binding.def(),
+            NameBindingKind::Res(res, _) => res,
+            NameBindingKind::Module(module) => module.res().unwrap(),
+            NameBindingKind::Import { binding, .. } => binding.res(),
         }
     }
 
@@ -1464,7 +1464,7 @@ impl<'a> NameBinding<'a> {
 
     // We sometimes need to treat variants as `pub` for backwards compatibility.
     fn pseudo_vis(&self) -> ty::Visibility {
-        if self.is_variant() && self.def().def_id().is_local() {
+        if self.is_variant() && self.res().def_id().is_local() {
             ty::Visibility::Public
         } else {
             self.vis
@@ -1473,8 +1473,8 @@ impl<'a> NameBinding<'a> {
 
     fn is_variant(&self) -> bool {
         match self.kind {
-            NameBindingKind::Def(Def::Def(DefKind::Variant, _), _) |
-            NameBindingKind::Def(Def::Def(DefKind::Ctor(CtorOf::Variant, ..), _), _) => true,
+            NameBindingKind::Res(Res::Def(DefKind::Variant, _), _) |
+            NameBindingKind::Res(Res::Def(DefKind::Ctor(CtorOf::Variant, ..), _), _) => true,
             _ => false,
         }
     }
@@ -1508,35 +1508,35 @@ impl<'a> NameBinding<'a> {
     }
 
     fn is_importable(&self) -> bool {
-        match self.def() {
-            Def::Def(DefKind::AssociatedConst, _)
-            | Def::Def(DefKind::Method, _)
-            | Def::Def(DefKind::AssociatedTy, _) => false,
+        match self.res() {
+            Res::Def(DefKind::AssociatedConst, _)
+            | Res::Def(DefKind::Method, _)
+            | Res::Def(DefKind::AssociatedTy, _) => false,
             _ => true,
         }
     }
 
     fn is_macro_def(&self) -> bool {
         match self.kind {
-            NameBindingKind::Def(Def::Def(DefKind::Macro(..), _), _) => true,
+            NameBindingKind::Res(Res::Def(DefKind::Macro(..), _), _) => true,
             _ => false,
         }
     }
 
     fn macro_kind(&self) -> Option<MacroKind> {
-        match self.def() {
-            Def::Def(DefKind::Macro(kind), _) => Some(kind),
-            Def::NonMacroAttr(..) => Some(MacroKind::Attr),
+        match self.res() {
+            Res::Def(DefKind::Macro(kind), _) => Some(kind),
+            Res::NonMacroAttr(..) => Some(MacroKind::Attr),
             _ => None,
         }
     }
 
     fn descr(&self) -> &'static str {
-        if self.is_extern_crate() { "extern crate" } else { self.def().kind_name() }
+        if self.is_extern_crate() { "extern crate" } else { self.res().kind_name() }
     }
 
     fn article(&self) -> &'static str {
-        if self.is_extern_crate() { "an" } else { self.def().article() }
+        if self.is_extern_crate() { "an" } else { self.res().article() }
     }
 
     // Suppose that we resolved macro invocation with `invoc_parent_expansion` to binding `binding`
@@ -1659,7 +1659,7 @@ pub struct Resolver<'a> {
     /// The idents for the primitive types.
     primitive_type_table: PrimitiveTypeTable,
 
-    def_map: DefMap,
+    res_map: ResMap,
     import_map: ImportMap,
     pub freevars: FreevarMap,
     freevars_seen: NodeMap<NodeMap<usize>>,
@@ -1712,7 +1712,7 @@ pub struct Resolver<'a> {
     macro_names: FxHashSet<Ident>,
     builtin_macros: FxHashMap<Name, &'a NameBinding<'a>>,
     macro_use_prelude: FxHashMap<Name, &'a NameBinding<'a>>,
-    pub all_macros: FxHashMap<Name, Def>,
+    pub all_macros: FxHashMap<Name, Res>,
     macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
     macro_defs: FxHashMap<Mark, DefId>,
     local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
@@ -1731,7 +1731,7 @@ pub struct Resolver<'a> {
 
     /// Table for mapping struct IDs into struct constructor IDs,
     /// it's not used during normal resolution, only for better error reporting.
-    struct_constructors: DefIdMap<(Def, ty::Visibility)>,
+    struct_constructors: DefIdMap<(Res, ty::Visibility)>,
 
     /// Only used for better errors on `fn(): fn()`.
     current_type_ascription: Vec<Span>,
@@ -1831,7 +1831,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
     }
 
     fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution> {
-        self.def_map.get(&id).cloned()
+        self.res_map.get(&id).cloned()
     }
 
     fn get_import(&mut self, id: NodeId) -> PerNS<Option<PathResolution>> {
@@ -1873,7 +1873,7 @@ impl<'a> Resolver<'a> {
             }
         };
         let path = self.resolve_hir_path_cb(&path, is_value, |_, _, _| errored = true);
-        if errored || path.def == def::Def::Err {
+        if errored || path.res == def::Res::Err {
             Err(())
         } else {
             Ok(path)
@@ -1894,18 +1894,18 @@ impl<'a> Resolver<'a> {
         let segments = &path.segments;
         let path = Segment::from_path(&path);
         // FIXME(Manishearth): intra-doc links won't get warned of epoch changes.
-        let def = match self.resolve_path_without_parent_scope(&path, Some(namespace), true,
+        let res = match self.resolve_path_without_parent_scope(&path, Some(namespace), true,
                                                                span, CrateLint::No) {
             PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
-                module.def().unwrap(),
+                module.res().unwrap(),
             PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
-                path_res.base_def(),
+                path_res.base_res(),
             PathResult::NonModule(..) => {
                 error_callback(self, span, ResolutionError::FailedToResolve {
                     label: String::from("type-relative paths are not supported in this context"),
                     suggestion: None,
                 });
-                Def::Err
+                Res::Err
             }
             PathResult::Module(..) | PathResult::Indeterminate => unreachable!(),
             PathResult::Failed { span, label, suggestion, .. } => {
@@ -1913,20 +1913,20 @@ impl<'a> Resolver<'a> {
                     label,
                     suggestion,
                 });
-                Def::Err
+                Res::Err
             }
         };
 
         let segments: Vec<_> = segments.iter().map(|seg| {
             let mut hir_seg = hir::PathSegment::from_ident(seg.ident);
-            hir_seg.def = Some(self.def_map.get(&seg.id).map_or(def::Def::Err, |p| {
-                p.base_def().map_id(|_| panic!("unexpected node_id"))
+            hir_seg.res = Some(self.res_map.get(&seg.id).map_or(def::Res::Err, |p| {
+                p.base_res().map_id(|_| panic!("unexpected node_id"))
             }));
             hir_seg
         }).collect();
         hir::Path {
             span,
-            def: def.map_id(|_| panic!("unexpected node_id")),
+            res: res.map_id(|_| panic!("unexpected node_id")),
             segments: segments.into(),
         }
     }
@@ -2019,7 +2019,7 @@ impl<'a> Resolver<'a> {
 
             primitive_type_table: PrimitiveTypeTable::new(),
 
-            def_map: Default::default(),
+            res_map: Default::default(),
             import_map: Default::default(),
             freevars: Default::default(),
             freevars_seen: Default::default(),
@@ -2045,7 +2045,7 @@ impl<'a> Resolver<'a> {
 
             arenas,
             dummy_binding: arenas.alloc_name_binding(NameBinding {
-                kind: NameBindingKind::Def(Def::Err, false),
+                kind: NameBindingKind::Res(Res::Err, false),
                 ambiguity: None,
                 expansion: Mark::root(),
                 span: DUMMY_SP,
@@ -2176,7 +2176,7 @@ impl<'a> Resolver<'a> {
                                       -> Option<LexicalScopeBinding<'a>> {
         assert!(ns == TypeNS  || ns == ValueNS);
         if ident.name == keywords::Invalid.name() {
-            return Some(LexicalScopeBinding::Def(Def::Err));
+            return Some(LexicalScopeBinding::Res(Res::Err));
         }
         ident.span = if ident.name == keywords::SelfUpper.name() {
             // FIXME(jseyfried) improve `Self` hygiene
@@ -2192,10 +2192,10 @@ impl<'a> Resolver<'a> {
         let mut module = self.graph_root;
         for i in (0 .. self.ribs[ns].len()).rev() {
             debug!("walk rib\n{:?}", self.ribs[ns][i].bindings);
-            if let Some(def) = self.ribs[ns][i].bindings.get(&ident).cloned() {
+            if let Some(res) = self.ribs[ns][i].bindings.get(&ident).cloned() {
                 // The ident resolves to a type parameter or local variable.
-                return Some(LexicalScopeBinding::Def(
-                    self.adjust_local_def(ns, i, def, record_used, path_span)
+                return Some(LexicalScopeBinding::Res(
+                    self.adjust_local_res(ns, i, res, record_used, path_span)
                 ));
             }
 
@@ -2275,7 +2275,7 @@ impl<'a> Resolver<'a> {
                 }
             }
             if ns == TypeNS && 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);
                 return Some(LexicalScopeBinding::Item(binding));
             }
@@ -2517,7 +2517,7 @@ impl<'a> Resolver<'a> {
         self.with_current_self_item(item, |this| {
             this.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| {
                 let item_def_id = this.definitions.local_def_id(item.id);
-                this.with_self_rib(Def::SelfTy(None, Some(item_def_id)), |this| {
+                this.with_self_rib(Res::SelfTy(None, Some(item_def_id)), |this| {
                     visit::walk_item(this, item);
                 });
             });
@@ -2543,13 +2543,13 @@ impl<'a> Resolver<'a> {
 
             for &ns in nss {
                 match self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) {
-                    Some(LexicalScopeBinding::Def(..)) => {
+                    Some(LexicalScopeBinding::Res(..)) => {
                         report_error(self, ns);
                     }
                     Some(LexicalScopeBinding::Item(binding)) => {
                         let orig_blacklisted_binding =
                             mem::replace(&mut self.blacklisted_binding, Some(binding));
-                        if let Some(LexicalScopeBinding::Def(..)) =
+                        if let Some(LexicalScopeBinding::Res(..)) =
                                 self.resolve_ident_in_lexical_scope(ident, ns, None,
                                                                     use_tree.prefix.span) {
                             report_error(self, ns);
@@ -2595,7 +2595,7 @@ impl<'a> Resolver<'a> {
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| {
                     let local_def_id = this.definitions.local_def_id(item.id);
-                    this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
+                    this.with_self_rib(Res::SelfTy(Some(local_def_id), None), |this| {
                         this.visit_generics(generics);
                         walk_list!(this, visit_param_bound, bounds);
 
@@ -2636,7 +2636,7 @@ impl<'a> Resolver<'a> {
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| {
                     let local_def_id = this.definitions.local_def_id(item.id);
-                    this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
+                    this.with_self_rib(Res::SelfTy(Some(local_def_id), None), |this| {
                         this.visit_generics(generics);
                         walk_list!(this, visit_param_bound, bounds);
                     });
@@ -2700,12 +2700,12 @@ impl<'a> Resolver<'a> {
                             seen_bindings.entry(ident).or_insert(param.ident.span);
 
                             // Plain insert (no renaming).
-                            let def = Def::Def(
+                            let res = Res::Def(
                                 DefKind::TyParam,
                                 self.definitions.local_def_id(param.id),
                             );
-                            function_type_rib.bindings.insert(ident, def);
-                            self.record_def(param.id, PathResolution::new(def));
+                            function_type_rib.bindings.insert(ident, res);
+                            self.record_res(param.id, PathResolution::new(res));
                         }
                         GenericParamKind::Const { .. } => {
                             let ident = param.ident.modern();
@@ -2721,12 +2721,12 @@ impl<'a> Resolver<'a> {
                             }
                             seen_bindings.entry(ident).or_insert(param.ident.span);
 
-                            let def = Def::Def(
+                            let res = Res::Def(
                                 DefKind::ConstParam,
                                 self.definitions.local_def_id(param.id),
                             );
-                            function_value_rib.bindings.insert(ident, def);
-                            self.record_def(param.id, PathResolution::new(def));
+                            function_value_rib.bindings.insert(ident, res);
+                            self.record_res(param.id, PathResolution::new(res));
                         }
                     }
                 }
@@ -2803,16 +2803,16 @@ impl<'a> Resolver<'a> {
         let mut new_id = None;
         if let Some(trait_ref) = opt_trait_ref {
             let path: Vec<_> = Segment::from_path(&trait_ref.path);
-            let def = self.smart_resolve_path_fragment(
+            let res = self.smart_resolve_path_fragment(
                 trait_ref.ref_id,
                 None,
                 &path,
                 trait_ref.path.span,
                 PathSource::Trait(AliasPossibility::No),
                 CrateLint::SimplePath(trait_ref.ref_id),
-            ).base_def();
-            if def != Def::Err {
-                new_id = Some(def.def_id());
+            ).base_res();
+            if res != Res::Err {
+                new_id = Some(res.def_id());
                 let span = trait_ref.path.span;
                 if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
                     self.resolve_path_without_parent_scope(
@@ -2833,13 +2833,13 @@ impl<'a> Resolver<'a> {
         result
     }
 
-    fn with_self_rib<F>(&mut self, self_def: Def, f: F)
+    fn with_self_rib<F>(&mut self, self_res: Res, f: F)
         where F: FnOnce(&mut Resolver<'_>)
     {
         let mut self_type_rib = Rib::new(NormalRibKind);
 
         // Plain insert (no renaming, since types are not currently hygienic)
-        self_type_rib.bindings.insert(keywords::SelfUpper.ident(), self_def);
+        self_type_rib.bindings.insert(keywords::SelfUpper.ident(), self_res);
         self.ribs[TypeNS].push(self_type_rib);
         f(self);
         self.ribs[TypeNS].pop();
@@ -2848,9 +2848,9 @@ impl<'a> Resolver<'a> {
     fn with_self_struct_ctor_rib<F>(&mut self, impl_id: DefId, f: F)
         where F: FnOnce(&mut Resolver<'_>)
     {
-        let self_def = Def::SelfCtor(impl_id);
+        let self_res = Res::SelfCtor(impl_id);
         let mut self_type_rib = Rib::new(NormalRibKind);
-        self_type_rib.bindings.insert(keywords::SelfUpper.ident(), self_def);
+        self_type_rib.bindings.insert(keywords::SelfUpper.ident(), self_res);
         self.ribs[ValueNS].push(self_type_rib);
         f(self);
         self.ribs[ValueNS].pop();
@@ -2866,11 +2866,11 @@ impl<'a> Resolver<'a> {
         // If applicable, create a rib for the type parameters.
         self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| {
             // Dummy self type for better errors if `Self` is used in the trait path.
-            this.with_self_rib(Def::SelfTy(None, None), |this| {
+            this.with_self_rib(Res::SelfTy(None, None), |this| {
                 // Resolve the trait reference, if necessary.
                 this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
                     let item_def_id = this.definitions.local_def_id(item_id);
-                    this.with_self_rib(Def::SelfTy(trait_id, Some(item_def_id)), |this| {
+                    this.with_self_rib(Res::SelfTy(trait_id, Some(item_def_id)), |this| {
                         if let Some(trait_ref) = opt_trait_reference.as_ref() {
                             // Resolve type arguments in the trait path.
                             visit::walk_trait_ref(this, trait_ref);
@@ -2994,8 +2994,8 @@ impl<'a> Resolver<'a> {
 
         pat.walk(&mut |pat| {
             if let PatKind::Ident(binding_mode, ident, ref sub_pat) = pat.node {
-                if sub_pat.is_some() || match self.def_map.get(&pat.id).map(|res| res.base_def()) {
-                    Some(Def::Local(..)) => true,
+                if sub_pat.is_some() || match self.res_map.get(&pat.id).map(|res| res.base_res()) {
+                    Some(Res::Local(..)) => true,
                     _ => false,
                 } {
                     let binding_info = BindingInfo { span: ident.span, binding_mode: binding_mode };
@@ -3118,9 +3118,9 @@ impl<'a> Resolver<'a> {
             if let ast::StmtKind::Item(ref item) = stmt.node {
                 if let ast::ItemKind::MacroDef(..) = item.node {
                     num_macro_definition_ribs += 1;
-                    let def = self.definitions.local_def_id(item.id);
-                    self.ribs[ValueNS].push(Rib::new(MacroDefinition(def)));
-                    self.label_ribs.push(Rib::new(MacroDefinition(def)));
+                    let res = self.definitions.local_def_id(item.id);
+                    self.ribs[ValueNS].push(Rib::new(MacroDefinition(res)));
+                    self.label_ribs.push(Rib::new(MacroDefinition(res)));
                 }
             }
 
@@ -3153,7 +3153,7 @@ impl<'a> Resolver<'a> {
         // because that breaks the assumptions later
         // passes make about or-patterns.)
         let ident = ident.modern_and_legacy();
-        let mut def = Def::Local(pat_id);
+        let mut res = Res::Local(pat_id);
         match bindings.get(&ident).cloned() {
             Some(id) if id == outer_pat_id => {
                 // `Variant(a, a)`, error
@@ -3178,7 +3178,7 @@ impl<'a> Resolver<'a> {
                         pat_src == PatternSource::WhileLet => {
                 // `Variant1(a) | Variant2(a)`, ok
                 // Reuse definition from the first `a`.
-                def = self.ribs[ValueNS].last_mut().unwrap().bindings[&ident];
+                res = self.ribs[ValueNS].last_mut().unwrap().bindings[&ident];
             }
             Some(..) => {
                 span_bug!(ident.span, "two bindings with the same name from \
@@ -3188,12 +3188,12 @@ impl<'a> Resolver<'a> {
                 // A completely fresh binding, add to the lists if it's valid.
                 if ident.name != keywords::Invalid.name() {
                     bindings.insert(ident, outer_pat_id);
-                    self.ribs[ValueNS].last_mut().unwrap().bindings.insert(ident, def);
+                    self.ribs[ValueNS].last_mut().unwrap().bindings.insert(ident, res);
                 }
             }
         }
 
-        PathResolution::new(def)
+        PathResolution::new(res)
     }
 
     fn resolve_pattern(&mut self,
@@ -3213,20 +3213,20 @@ impl<'a> Resolver<'a> {
                     let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS,
                                                                       None, pat.span)
                                       .and_then(LexicalScopeBinding::item);
-                    let resolution = binding.map(NameBinding::def).and_then(|def| {
+                    let resolution = binding.map(NameBinding::res).and_then(|res| {
                         let is_syntactic_ambiguity = opt_pat.is_none() &&
                             bmode == BindingMode::ByValue(Mutability::Immutable);
-                        match def {
-                            Def::Def(DefKind::Ctor(_, CtorKind::Const), _) |
-                            Def::Def(DefKind::Const, _) if is_syntactic_ambiguity => {
+                        match res {
+                            Res::Def(DefKind::Ctor(_, CtorKind::Const), _) |
+                            Res::Def(DefKind::Const, _) if is_syntactic_ambiguity => {
                                 // Disambiguate in favor of a unit struct/variant
                                 // or constant pattern.
                                 self.record_use(ident, ValueNS, binding.unwrap(), false);
-                                Some(PathResolution::new(def))
+                                Some(PathResolution::new(res))
                             }
-                            Def::Def(DefKind::Ctor(..), _)
-                            | Def::Def(DefKind::Const, _)
-                            | Def::Def(DefKind::Static, _) => {
+                            Res::Def(DefKind::Ctor(..), _)
+                            | Res::Def(DefKind::Const, _)
+                            | Res::Def(DefKind::Static, _) => {
                                 // This is unambiguously a fresh binding, either syntactically
                                 // (e.g., `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
                                 // to something unusable as a pattern (e.g., constructor function),
@@ -3240,21 +3240,21 @@ impl<'a> Resolver<'a> {
                                 );
                                 None
                             }
-                            Def::Def(DefKind::Fn, _) | Def::Err => {
+                            Res::Def(DefKind::Fn, _) | Res::Err => {
                                 // These entities are explicitly allowed
                                 // to be shadowed by fresh bindings.
                                 None
                             }
-                            def => {
-                                span_bug!(ident.span, "unexpected definition for an \
-                                                       identifier in pattern: {:?}", def);
+                            res => {
+                                span_bug!(ident.span, "unexpected resolution for an \
+                                                       identifier in pattern: {:?}", res);
                             }
                         }
                     }).unwrap_or_else(|| {
                         self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
                     });
 
-                    self.record_def(pat.id, resolution);
+                    self.record_res(pat.id, resolution);
                 }
 
                 PatKind::TupleStruct(ref path, ..) => {
@@ -3326,13 +3326,13 @@ impl<'a> Resolver<'a> {
                                    crate_lint: CrateLint)
                                    -> PathResolution {
         let ns = source.namespace();
-        let is_expected = &|def| source.is_expected(def);
+        let is_expected = &|res| source.is_expected(res);
 
-        let report_errors = |this: &mut Self, def: Option<Def>| {
-            let (err, candidates) = this.smart_resolve_report_errors(path, span, source, def);
+        let report_errors = |this: &mut Self, res: Option<Res>| {
+            let (err, candidates) = this.smart_resolve_report_errors(path, span, source, res);
             let def_id = this.current_module.normal_ancestor_id;
             let node_id = this.definitions.as_local_node_id(def_id).unwrap();
-            let better = def.is_some();
+            let better = res.is_some();
             this.use_injections.push(UseError { err, candidates, node_id, better });
             err_path_resolution()
         };
@@ -3348,27 +3348,27 @@ impl<'a> Resolver<'a> {
             crate_lint,
         ) {
             Some(resolution) if resolution.unresolved_segments() == 0 => {
-                if is_expected(resolution.base_def()) || resolution.base_def() == Def::Err {
+                if is_expected(resolution.base_res()) || resolution.base_res() == Res::Err {
                     resolution
                 } else {
                     // Add a temporary hack to smooth the transition to new struct ctor
                     // visibility rules. See #38932 for more details.
                     let mut res = None;
-                    if let Def::Def(DefKind::Struct, def_id) = resolution.base_def() {
-                        if let Some((ctor_def, ctor_vis))
+                    if let Res::Def(DefKind::Struct, def_id) = resolution.base_res() {
+                        if let Some((ctor_res, ctor_vis))
                                 = self.struct_constructors.get(&def_id).cloned() {
-                            if is_expected(ctor_def) && self.is_accessible(ctor_vis) {
+                            if is_expected(ctor_res) && self.is_accessible(ctor_vis) {
                                 let lint = lint::builtin::LEGACY_CONSTRUCTOR_VISIBILITY;
                                 self.session.buffer_lint(lint, id, span,
                                     "private struct constructors are not usable through \
                                      re-exports in outer modules",
                                 );
-                                res = Some(PathResolution::new(ctor_def));
+                                res = Some(PathResolution::new(ctor_res));
                             }
                         }
                     }
 
-                    res.unwrap_or_else(|| report_errors(self, Some(resolution.base_def())))
+                    res.unwrap_or_else(|| report_errors(self, Some(resolution.base_res())))
                 }
             }
             Some(resolution) if source.defer_to_typeck() => {
@@ -3406,7 +3406,7 @@ impl<'a> Resolver<'a> {
 
         if let PathSource::TraitItem(..) = source {} else {
             // Avoid recording definition of `A::B` in `<T as A>::B::C`.
-            self.record_def(id, resolution);
+            self.record_res(id, resolution);
         }
         resolution
     }
@@ -3503,13 +3503,13 @@ impl<'a> Resolver<'a> {
     fn self_type_is_available(&mut self, span: Span) -> bool {
         let binding = self.resolve_ident_in_lexical_scope(keywords::SelfUpper.ident(),
                                                           TypeNS, None, span);
-        if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
+        if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false }
     }
 
     fn self_value_is_available(&mut self, self_span: Span, path_span: Span) -> bool {
         let ident = Ident::new(keywords::SelfLower.name(), self_span);
         let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, path_span);
-        if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
+        if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false }
     }
 
     // Resolve in alternative namespaces if resolution in the primary namespace fails.
@@ -3545,7 +3545,7 @@ impl<'a> Resolver<'a> {
             self.macro_use_prelude.get(&path[0].ident.name).cloned()
                                   .and_then(NameBinding::macro_kind) == Some(MacroKind::Bang)) {
             // Return some dummy definition, it's enough for error reporting.
-            return Some(PathResolution::new(Def::Def(
+            return Some(PathResolution::new(Res::Def(
                 DefKind::Macro(MacroKind::Bang),
                 DefId::local(CRATE_DEF_INDEX),
             )));
@@ -3581,7 +3581,7 @@ impl<'a> Resolver<'a> {
                 // trait to resolve.  In that case, we leave the `B`
                 // segment to be resolved by type-check.
                 return Some(PathResolution::with_unresolved_segments(
-                    Def::Def(DefKind::Mod, DefId::local(CRATE_DEF_INDEX)), path.len()
+                    Res::Def(DefKind::Mod, DefId::local(CRATE_DEF_INDEX)), path.len()
                 ));
             }
 
@@ -3616,7 +3616,7 @@ impl<'a> Resolver<'a> {
             // have to be resolved by type-check, since that requires doing
             // trait resolution.
             return Some(PathResolution::with_unresolved_segments(
-                res.base_def(), res.unresolved_segments() + path.len() - qself.position - 1
+                res.base_res(), res.unresolved_segments() + path.len() - qself.position - 1
             ));
         }
 
@@ -3629,7 +3629,7 @@ impl<'a> Resolver<'a> {
         ) {
             PathResult::NonModule(path_res) => path_res,
             PathResult::Module(ModuleOrUniformRoot::Module(module)) if !module.is_normal() => {
-                PathResolution::new(module.def().unwrap())
+                PathResolution::new(module.res().unwrap())
             }
             // In `a(::assoc_item)*` `a` cannot be a module. If `a` does resolve to a module we
             // don't report an error right away, but try to fallback to a primitive type.
@@ -3649,10 +3649,10 @@ impl<'a> Resolver<'a> {
                        self.primitive_type_table.primitive_types
                            .contains_key(&path[0].ident.name) => {
                 let prim = self.primitive_type_table.primitive_types[&path[0].ident.name];
-                PathResolution::with_unresolved_segments(Def::PrimTy(prim), path.len() - 1)
+                PathResolution::with_unresolved_segments(Res::PrimTy(prim), path.len() - 1)
             }
             PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
-                PathResolution::new(module.def().unwrap()),
+                PathResolution::new(module.res().unwrap()),
             PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => {
                 resolve_error(self, span, ResolutionError::FailedToResolve { label, suggestion });
                 err_path_resolution()
@@ -3661,7 +3661,7 @@ impl<'a> Resolver<'a> {
             PathResult::Indeterminate => bug!("indetermined path result in resolve_qpath"),
         };
 
-        if path.len() > 1 && !global_by_default && result.base_def() != Def::Err &&
+        if path.len() > 1 && !global_by_default && result.base_res() != Res::Err &&
            path[0].ident.name != keywords::PathRoot.name() &&
            path[0].ident.name != keywords::DollarCrate.name() {
             let unqualified_result = {
@@ -3672,13 +3672,13 @@ impl<'a> Resolver<'a> {
                     span,
                     CrateLint::No,
                 ) {
-                    PathResult::NonModule(path_res) => path_res.base_def(),
+                    PathResult::NonModule(path_res) => path_res.base_res(),
                     PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
-                        module.def().unwrap(),
+                        module.res().unwrap(),
                     _ => return Some(result),
                 }
             };
-            if result.base_def() == unqualified_result {
+            if result.base_res() == unqualified_result {
                 let lint = lint::builtin::UNUSED_QUALIFICATIONS;
                 self.session.buffer_lint(lint, id, span, "unnecessary qualification")
             }
@@ -3728,12 +3728,12 @@ impl<'a> Resolver<'a> {
 
         for (i, &Segment { ident, id }) in path.iter().enumerate() {
             debug!("resolve_path ident {} {:?} {:?}", i, ident, id);
-            let record_segment_def = |this: &mut Self, def| {
+            let record_segment_res = |this: &mut Self, res| {
                 if record_used {
                     if let Some(id) = id {
-                        if !this.def_map.contains_key(&id) {
+                        if !this.res_map.contains_key(&id) {
                             assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");
-                            this.record_def(id, PathResolution::new(def));
+                            this.record_res(id, PathResolution::new(res));
                         }
                     }
                 }
@@ -3834,11 +3834,11 @@ impl<'a> Resolver<'a> {
                     // we found a locally-imported or available item/module
                     Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
                     // we found a local variable or type param
-                    Some(LexicalScopeBinding::Def(def))
+                    Some(LexicalScopeBinding::Res(res))
                             if opt_ns == Some(TypeNS) || opt_ns == Some(ValueNS) => {
-                        record_segment_def(self, def);
+                        record_segment_res(self, res);
                         return PathResult::NonModule(PathResolution::with_unresolved_segments(
-                            def, path.len() - 1
+                            res, path.len() - 1
                         ));
                     }
                     _ => Err(Determinacy::determined(record_used)),
@@ -3850,12 +3850,12 @@ impl<'a> Resolver<'a> {
                     if i == 1 {
                         second_binding = Some(binding);
                     }
-                    let def = binding.def();
-                    let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(def);
+                    let res = binding.res();
+                    let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(res);
                     if let Some(next_module) = binding.module() {
                         module = Some(ModuleOrUniformRoot::Module(next_module));
-                        record_segment_def(self, def);
-                    } else if def == Def::ToolMod && i + 1 != path.len() {
+                        record_segment_res(self, res);
+                    } else if res == Res::ToolMod && i + 1 != path.len() {
                         if binding.is_import() {
                             self.session.struct_span_err(
                                 ident.span, "cannot use a tool module through an import"
@@ -3863,9 +3863,9 @@ impl<'a> Resolver<'a> {
                                 binding.span, "the tool module imported here"
                             ).emit();
                         }
-                        let def = Def::NonMacroAttr(NonMacroAttrKind::Tool);
-                        return PathResult::NonModule(PathResolution::new(def));
-                    } else if def == Def::Err {
+                        let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);
+                        return PathResult::NonModule(PathResolution::new(res));
+                    } else if res == Res::Err {
                         return PathResult::NonModule(err_path_resolution());
                     } else if opt_ns.is_some() && (is_last || maybe_assoc) {
                         self.lint_if_path_starts_with_module(
@@ -3875,14 +3875,14 @@ impl<'a> Resolver<'a> {
                             second_binding,
                         );
                         return PathResult::NonModule(PathResolution::with_unresolved_segments(
-                            def, path.len() - i - 1
+                            res, path.len() - i - 1
                         ));
                     } else {
                         let label = format!(
                             "`{}` is {} {}, not a module",
                             ident,
-                            def.article(),
-                            def.kind_name(),
+                            res.article(),
+                            res.kind_name(),
                         );
 
                         return PathResult::Failed {
@@ -3898,17 +3898,17 @@ impl<'a> Resolver<'a> {
                     if let Some(ModuleOrUniformRoot::Module(module)) = module {
                         if opt_ns.is_some() && !module.is_normal() {
                             return PathResult::NonModule(PathResolution::with_unresolved_segments(
-                                module.def().unwrap(), path.len() - i
+                                module.res().unwrap(), path.len() - i
                             ));
                         }
                     }
-                    let module_def = match module {
-                        Some(ModuleOrUniformRoot::Module(module)) => module.def(),
+                    let module_res = match module {
+                        Some(ModuleOrUniformRoot::Module(module)) => module.res(),
                         _ => None,
                     };
-                    let (label, suggestion) = if module_def == self.graph_root.def() {
-                        let is_mod = |def| {
-                            match def { Def::Def(DefKind::Mod, _) => true, _ => false }
+                    let (label, suggestion) = if module_res == self.graph_root.res() {
+                        let is_mod = |res| {
+                            match res { Res::Def(DefKind::Mod, _) => true, _ => false }
                         };
                         let mut candidates =
                             self.lookup_import_candidates(ident, TypeNS, is_mod);
@@ -4015,13 +4015,13 @@ impl<'a> Resolver<'a> {
     }
 
     // Resolve a local definition, potentially adjusting for closures.
-    fn adjust_local_def(&mut self,
+    fn adjust_local_res(&mut self,
                         ns: Namespace,
                         rib_index: usize,
-                        mut def: Def,
+                        mut res: Res,
                         record_used: bool,
-                        span: Span) -> Def {
-        debug!("adjust_local_def");
+                        span: Span) -> Res {
+        debug!("adjust_local_res");
         let ribs = &self.ribs[ns][rib_index + 1..];
 
         // An invalid forward use of a type parameter from a previous default.
@@ -4029,8 +4029,8 @@ impl<'a> Resolver<'a> {
             if record_used {
                 resolve_error(self, span, ResolutionError::ForwardDeclaredTyParam);
             }
-            assert_eq!(def, Def::Err);
-            return Def::Err;
+            assert_eq!(res, Res::Err);
+            return Res::Err;
         }
 
         // An invalid use of a type parameter as the type of a const parameter.
@@ -4038,15 +4038,15 @@ impl<'a> Resolver<'a> {
             if record_used {
                 resolve_error(self, span, ResolutionError::ConstParamDependentOnTypeParam);
             }
-            assert_eq!(def, Def::Err);
-            return Def::Err;
+            assert_eq!(res, Res::Err);
+            return Res::Err;
         }
 
-        match def {
-            Def::Upvar(..) => {
-                span_bug!(span, "unexpected {:?} in bindings", def)
+        match res {
+            Res::Upvar(..) => {
+                span_bug!(span, "unexpected {:?} in bindings", res)
             }
-            Def::Local(node_id) => {
+            Res::Local(node_id) => {
                 use ResolutionError::*;
                 let mut res_err = None;
 
@@ -4057,24 +4057,24 @@ impl<'a> Resolver<'a> {
                             // Nothing to do. Continue.
                         }
                         ClosureRibKind(function_id) => {
-                            let prev_def = def;
+                            let prev_res = res;
 
                             let seen = self.freevars_seen
                                            .entry(function_id)
                                            .or_default();
                             if let Some(&index) = seen.get(&node_id) {
-                                def = Def::Upvar(node_id, index, function_id);
+                                res = Res::Upvar(node_id, index, function_id);
                                 continue;
                             }
                             let vec = self.freevars
                                           .entry(function_id)
                                           .or_default();
                             let depth = vec.len();
-                            def = Def::Upvar(node_id, depth, function_id);
+                            res = Res::Upvar(node_id, depth, function_id);
 
                             if record_used {
                                 vec.push(Freevar {
-                                    def: prev_def,
+                                    res: prev_res,
                                     span,
                                 });
                                 seen.insert(node_id, depth);
@@ -4097,16 +4097,16 @@ impl<'a> Resolver<'a> {
                             if record_used {
                                 resolve_error(self, span, AttemptToUseNonConstantValueInConstant);
                             }
-                            return Def::Err;
+                            return Res::Err;
                         }
                     }
                 }
                 if let Some(res_err) = res_err {
                      resolve_error(self, span, res_err);
-                     return Def::Err;
+                     return Res::Err;
                 }
             }
-            Def::Def(DefKind::TyParam, _) | Def::SelfTy(..) => {
+            Res::Def(DefKind::TyParam, _) | Res::SelfTy(..) => {
                 for rib in ribs {
                     match rib.kind {
                         NormalRibKind | TraitOrImplItemRibKind | ClosureRibKind(..) |
@@ -4120,15 +4120,15 @@ impl<'a> Resolver<'a> {
                                 resolve_error(
                                     self,
                                     span,
-                                    ResolutionError::GenericParamsFromOuterFunction(def),
+                                    ResolutionError::GenericParamsFromOuterFunction(res),
                                 );
                             }
-                            return Def::Err;
+                            return Res::Err;
                         }
                     }
                 }
             }
-            Def::Def(DefKind::ConstParam, _) => {
+            Res::Def(DefKind::ConstParam, _) => {
                 let mut ribs = ribs.iter().peekable();
                 if let Some(Rib { kind: FnItemRibKind, .. }) = ribs.peek() {
                     // When declaring const parameters inside function signatures, the first rib
@@ -4143,16 +4143,16 @@ impl<'a> Resolver<'a> {
                             resolve_error(
                                 self,
                                 span,
-                                ResolutionError::GenericParamsFromOuterFunction(def),
+                                ResolutionError::GenericParamsFromOuterFunction(res),
                             );
                         }
-                        return Def::Err;
+                        return Res::Err;
                     }
                 }
             }
             _ => {}
         }
-        def
+        res
     }
 
     fn lookup_assoc_candidate<FilterFn>(&mut self,
@@ -4160,7 +4160,7 @@ impl<'a> Resolver<'a> {
                                         ns: Namespace,
                                         filter_fn: FilterFn)
                                         -> Option<AssocSuggestion>
-        where FilterFn: Fn(Def) -> bool
+        where FilterFn: Fn(Res) -> bool
     {
         fn extract_node_id(t: &Ty) -> Option<NodeId> {
             match t.node {
@@ -4174,12 +4174,12 @@ impl<'a> Resolver<'a> {
         }
 
         // Fields are generally expected in the same contexts as locals.
-        if filter_fn(Def::Local(ast::DUMMY_NODE_ID)) {
+        if filter_fn(Res::Local(ast::DUMMY_NODE_ID)) {
             if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) {
                 // Look for a field with the same name in the current self_type.
-                if let Some(resolution) = self.def_map.get(&node_id) {
-                    match resolution.base_def() {
-                        Def::Def(DefKind::Struct, did) | Def::Def(DefKind::Union, did)
+                if let Some(resolution) = self.res_map.get(&node_id) {
+                    match resolution.base_res() {
+                        Res::Def(DefKind::Struct, did) | Res::Def(DefKind::Union, did)
                                 if resolution.unresolved_segments() == 0 => {
                             if let Some(field_names) = self.field_names.get(&did) {
                                 if field_names.iter().any(|&field_name| ident.name == field_name) {
@@ -4203,9 +4203,9 @@ impl<'a> Resolver<'a> {
                     false,
                     module.span,
                 ) {
-                let def = binding.def();
-                if filter_fn(def) {
-                    return Some(if self.has_self.contains(&def.def_id()) {
+                let res = binding.res();
+                if filter_fn(res) {
+                    return Some(if self.has_self.contains(&res.def_id()) {
                         AssocSuggestion::MethodWithSelf
                     } else {
                         AssocSuggestion::AssocItem
@@ -4225,16 +4225,16 @@ impl<'a> Resolver<'a> {
         span: Span,
     ) -> Option<TypoSuggestion>
     where
-        FilterFn: Fn(Def) -> bool,
+        FilterFn: Fn(Res) -> bool,
     {
         let add_module_candidates = |module: Module<'_>, names: &mut Vec<TypoSuggestion>| {
             for (&(ident, _), resolution) in module.resolutions.borrow().iter() {
                 if let Some(binding) = resolution.borrow().binding {
-                    if !ident.name.is_gensymed() && filter_fn(binding.def()) {
+                    if !ident.name.is_gensymed() && filter_fn(binding.res()) {
                         names.push(TypoSuggestion {
                             candidate: ident.name,
-                            article: binding.def().article(),
-                            kind: binding.def().kind_name(),
+                            article: binding.res().article(),
+                            kind: binding.res().kind_name(),
                         });
                     }
                 }
@@ -4247,12 +4247,12 @@ impl<'a> Resolver<'a> {
             // Walk backwards up the ribs in scope and collect candidates.
             for rib in self.ribs[ns].iter().rev() {
                 // Locals and type parameters
-                for (ident, def) in &rib.bindings {
-                    if !ident.name.is_gensymed() && filter_fn(*def) {
+                for (ident, &res) in &rib.bindings {
+                    if !ident.name.is_gensymed() && filter_fn(res) {
                         names.push(TypoSuggestion {
                             candidate: ident.name,
-                            article: def.article(),
-                            kind: def.kind_name(),
+                            article: res.article(),
+                            kind: res.kind_name(),
                         });
                     }
                 }
@@ -4270,7 +4270,7 @@ impl<'a> Resolver<'a> {
                                 self.crate_loader
                                     .maybe_process_path_extern(ident.name, ident.span)
                                     .and_then(|crate_id| {
-                                        let crate_mod = Def::Def(
+                                        let crate_mod = Res::Def(
                                             DefKind::Mod,
                                             DefId {
                                                 krate: crate_id,
@@ -4299,7 +4299,7 @@ impl<'a> Resolver<'a> {
                 }
             }
             // Add primitive types to the mix
-            if filter_fn(Def::PrimTy(Bool)) {
+            if filter_fn(Res::PrimTy(Bool)) {
                 names.extend(
                     self.primitive_type_table.primitive_types
                         .iter()
@@ -4346,10 +4346,10 @@ impl<'a> Resolver<'a> {
     {
         if let Some(label) = label {
             self.unused_labels.insert(id, label.ident.span);
-            let def = Def::Label(id);
+            let res = Res::Label(id);
             self.with_label_rib(|this| {
                 let ident = label.ident.modern_and_legacy();
-                this.label_ribs.last_mut().unwrap().bindings.insert(ident, def);
+                this.label_ribs.last_mut().unwrap().bindings.insert(ident, res);
                 f(this);
             });
         } else {
@@ -4380,10 +4380,10 @@ impl<'a> Resolver<'a> {
             }
 
             ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => {
-                let def = self.search_label(label.ident, |rib, ident| {
+                let res = self.search_label(label.ident, |rib, ident| {
                     rib.bindings.get(&ident.modern_and_legacy()).cloned()
                 });
-                match def {
+                match res {
                     None => {
                         // Search again for close matches...
                         // Picks the first label that is "close enough", which is not necessarily
@@ -4398,19 +4398,19 @@ impl<'a> Resolver<'a> {
                             });
                             find_best_match_for_name(names, &*ident.as_str(), None)
                         });
-                        self.record_def(expr.id, err_path_resolution());
+                        self.record_res(expr.id, err_path_resolution());
                         resolve_error(self,
                                       label.ident.span,
                                       ResolutionError::UndeclaredLabel(&label.ident.as_str(),
                                                                        close_match));
                     }
-                    Some(Def::Label(id)) => {
-                        // Since this def is a label, it is never read.
-                        self.record_def(expr.id, PathResolution::new(Def::Label(id)));
+                    Some(Res::Label(id)) => {
+                        // Since this res is a label, it is never read.
+                        self.record_res(expr.id, PathResolution::new(Res::Label(id)));
                         self.unused_labels.remove(&id);
                     }
                     Some(_) => {
-                        span_bug!(expr.span, "label wasn't mapped to a label def!");
+                        span_bug!(expr.span, "label wasn't mapped to a label res!");
                     }
                 }
 
@@ -4615,9 +4615,9 @@ impl<'a> Resolver<'a> {
             let mut collected_traits = Vec::new();
             module.for_each_child(|name, ns, binding| {
                 if ns != TypeNS { return }
-                match binding.def() {
-                    Def::Def(DefKind::Trait, _) |
-                    Def::Def(DefKind::TraitAlias, _) => collected_traits.push((name, binding)),
+                match binding.res() {
+                    Res::Def(DefKind::Trait, _) |
+                    Res::Def(DefKind::TraitAlias, _) => collected_traits.push((name, binding)),
                     _ => (),
                 }
             });
@@ -4652,7 +4652,7 @@ impl<'a> Resolver<'a> {
                     let trait_def_id = module.def_id().unwrap();
                     found_traits.push(TraitCandidate { def_id: trait_def_id, import_id });
                 }
-            } else if let Def::Def(DefKind::TraitAlias, _) = binding.def() {
+            } else if let Res::Def(DefKind::TraitAlias, _) = binding.res() {
                 // For now, just treat all trait aliases as possible candidates, since we don't
                 // know if the ident is somewhere in the transitive bounds.
 
@@ -4664,7 +4664,7 @@ impl<'a> Resolver<'a> {
                     }
                     _ => None,
                 };
-                let trait_def_id = binding.def().def_id();
+                let trait_def_id = binding.res().def_id();
                 found_traits.push(TraitCandidate { def_id: trait_def_id, import_id });
             } else {
                 bug!("candidate is not trait or trait alias?")
@@ -4679,7 +4679,7 @@ impl<'a> Resolver<'a> {
                                           crate_name: Ident,
                                           filter_fn: FilterFn)
                                           -> Vec<ImportSuggestion>
-        where FilterFn: Fn(Def) -> bool
+        where FilterFn: Fn(Res) -> bool
     {
         let mut candidates = Vec::new();
         let mut seen_modules = FxHashSet::default();
@@ -4701,8 +4701,8 @@ impl<'a> Resolver<'a> {
 
                 // collect results based on the filter function
                 if ident.name == lookup_ident.name && ns == namespace {
-                    let def = name_binding.def();
-                    if filter_fn(def) {
+                    let res = name_binding.res();
+                    if filter_fn(res) {
                         // create the path
                         let mut segms = path_segments.clone();
                         if lookup_ident.span.rust_2018() {
@@ -4726,9 +4726,9 @@ impl<'a> Resolver<'a> {
                         // declared as public (due to pruning, we don't explore
                         // outside crate private modules => no need to check this)
                         if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
-                            let did = match def {
-                                Def::Def(DefKind::Ctor(..), did) => self.parent(did),
-                                _ => def.opt_def_id(),
+                            let did = match res {
+                                Res::Def(DefKind::Ctor(..), did) => self.parent(did),
+                                _ => res.opt_def_id(),
                             };
                             candidates.push(ImportSuggestion { did, path });
                         }
@@ -4774,7 +4774,7 @@ impl<'a> Resolver<'a> {
                                           namespace: Namespace,
                                           filter_fn: FilterFn)
                                           -> Vec<ImportSuggestion>
-        where FilterFn: Fn(Def) -> bool
+        where FilterFn: Fn(Res) -> bool
     {
         let mut suggestions = self.lookup_import_candidates_from_module(
             lookup_ident, namespace, self.graph_root, keywords::Crate.ident(), &filter_fn);
@@ -4845,7 +4845,7 @@ impl<'a> Resolver<'a> {
 
             let mut variants = Vec::new();
             enum_module.for_each_child_stable(|ident, _, name_binding| {
-                if let Def::Def(DefKind::Variant, _) = name_binding.def() {
+                if let Res::Def(DefKind::Variant, _) = name_binding.res() {
                     let mut segms = enum_import_suggestion.path.segments.clone();
                     segms.push(ast::PathSegment::from_ident(ident));
                     variants.push(Path {
@@ -4858,9 +4858,9 @@ impl<'a> Resolver<'a> {
         })
     }
 
-    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
-        debug!("(recording def) recording {:?} for {}", resolution, node_id);
-        if let Some(prev_res) = self.def_map.insert(node_id, resolution) {
+    fn record_res(&mut self, node_id: NodeId, resolution: PathResolution) {
+        debug!("(recording res) recording {:?} for {}", resolution, node_id);
+        if let Some(prev_res) = self.res_map.insert(node_id, resolution) {
             panic!("path resolved multiple times ({:?} before, {:?} now)", prev_res, resolution);
         }
     }
@@ -4902,18 +4902,18 @@ impl<'a> Resolver<'a> {
 
                 let segments = crate_root.into_iter()
                     .chain(path.segments.iter().map(|seg| seg.into())).collect::<Vec<_>>();
-                let def = self.smart_resolve_path_fragment(
+                let res = self.smart_resolve_path_fragment(
                     id,
                     None,
                     &segments,
                     path.span,
                     PathSource::Visibility,
                     CrateLint::SimplePath(id),
-                ).base_def();
-                if def == Def::Err {
+                ).base_res();
+                if res == Res::Err {
                     ty::Visibility::Public
                 } else {
-                    let vis = ty::Visibility::Restricted(def.def_id());
+                    let vis = ty::Visibility::Restricted(res.def_id());
                     if self.is_accessible(vis) {
                         vis
                     } else {
@@ -4961,9 +4961,9 @@ impl<'a> Resolver<'a> {
 
     fn binding_description(&self, b: &NameBinding<'_>, ident: Ident, from_prelude: bool) -> String {
         if b.span.is_dummy() {
-            let add_built_in = match b.def() {
+            let add_built_in = match b.res() {
                 // These already contain the "built-in" prefix or look bad with it.
-                Def::NonMacroAttr(..) | Def::PrimTy(..) | Def::ToolMod => false,
+                Res::NonMacroAttr(..) | Res::PrimTy(..) | Res::ToolMod => false,
                 _ => true,
             };
             let (built_in, from) = if from_prelude {
@@ -5176,7 +5176,7 @@ impl<'a> Resolver<'a> {
         };
 
         // Check if the target of the use for both bindings is the same.
-        let duplicate = new_binding.def().opt_def_id() == old_binding.def().opt_def_id();
+        let duplicate = new_binding.res().opt_def_id() == old_binding.res().opt_def_id();
         let has_dummy_span = new_binding.span.is_dummy() || old_binding.span.is_dummy();
         let from_item = self.extern_prelude.get(&ident)
             .map(|entry| entry.introduced_by_item)
@@ -5484,7 +5484,7 @@ fn module_to_string(module: Module<'_>) -> Option<String> {
 }
 
 fn err_path_resolution() -> PathResolution {
-    PathResolution::new(Def::Err)
+    PathResolution::new(Res::Err)
 }
 
 #[derive(Copy, Clone, Debug)]
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 3df09369f89..18573a4594f 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -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> {
@@ -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::Def(DefKind::Macro(kind), def_id), 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::Def(DefKind::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::Def(DefKind::Macro(macro_kind), def_id) => {
+        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 `DefKind::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::Def(DefKind::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::Def(DefKind::Macro(MacroKind::Bang), def_id);
+            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::Def(DefKind::Macro(MacroKind::Bang), def_id);
+            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));
         }
     }
 }
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 7dbc7536440..522a49ee2c1 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -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::Def(DefKind::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(
@@ -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,
                     });
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 36413e76a1e..a45e32ddb66 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -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, DefKind as HirDefKind};
+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::Def(HirDefKind::Ctor(..), _) |
-                HirDef::Def(HirDefKind::Const, _) |
-                HirDef::Def(HirDefKind::AssociatedConst, _) |
-                HirDef::Def(HirDefKind::Struct, _) |
-                HirDef::Def(HirDefKind::Variant, _) |
-                HirDef::Def(HirDefKind::TyAlias, _) |
-                HirDef::Def(HirDefKind::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, _) => {
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 47d0b5055ea..c242b4d6a41 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -15,7 +15,7 @@ mod span_utils;
 mod sig;
 
 use rustc::hir;
-use rustc::hir::def::{CtorOf, Def as HirDef, DefKind as HirDefKind};
+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::Def(HirDefKind::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::Def(HirDefKind::Struct, def_id) |
-            HirDef::Def(HirDefKind::Variant, def_id) |
-            HirDef::Def(HirDefKind::Union, def_id) |
-            HirDef::Def(HirDefKind::Enum, def_id) |
-            HirDef::Def(HirDefKind::TyAlias, def_id) |
-            HirDef::Def(HirDefKind::ForeignTy, def_id) |
-            HirDef::Def(HirDefKind::TraitAlias, def_id) |
-            HirDef::Def(HirDefKind::AssociatedExistential, def_id) |
-            HirDef::Def(HirDefKind::AssociatedTy, def_id) |
-            HirDef::Def(HirDefKind::Trait, def_id) |
-            HirDef::Def(HirDefKind::Existential, def_id) |
-            HirDef::Def(HirDefKind::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::Def(HirDefKind::ConstParam, def_id) => {
+            Res::Def(HirDefKind::ConstParam, def_id) => {
                 Some(Ref {
                     kind: RefKind::Variable,
                     span,
                     ref_id: id_from_def_id(def_id),
                 })
             }
-            HirDef::Def(HirDefKind::Ctor(CtorOf::Struct, ..), def_id) => {
+            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::Def(HirDefKind::Static, _) |
-            HirDef::Def(HirDefKind::Const, _) |
-            HirDef::Def(HirDefKind::AssociatedConst, _) |
-            HirDef::Def(HirDefKind::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::Def(HirDefKind::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::Def(HirDefKind::Fn, def_id) => {
+            Res::Def(HirDefKind::Fn, def_id) => {
                 Some(Ref {
                     kind: RefKind::Function,
                     span,
                     ref_id: id_from_def_id(def_id),
                 })
             }
-            HirDef::Def(HirDefKind::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::Def(HirDefKind::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()),
         }
     }
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index bcdb6be0ebd..4f759b8a73f 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -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, DefKind};
+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,19 +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::Def(DefKind::AssociatedConst, _)
-            | Def::Def(DefKind::Variant, _)
-            | Def::Def(DefKind::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");
@@ -608,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![],
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 241d77c2575..4932d77ef04 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -4,7 +4,7 @@
 
 use errors::{Applicability, DiagnosticId};
 use crate::hir::{self, GenericArg, GenericArgs, ExprKind};
-use crate::hir::def::{CtorOf, Def, DefKind};
+use crate::hir::def::{CtorOf, Res, DefKind};
 use crate::hir::def_id::DefId;
 use crate::hir::HirVec;
 use crate::lint;
@@ -1311,7 +1311,7 @@ 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,
     ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorReported> {
@@ -1343,8 +1343,8 @@ 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) {
@@ -1360,8 +1360,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
 
                 self.one_bound_for_assoc_type(candidates, "Self", assoc_ident, span)?
             }
-            (&ty::Param(_), Def::SelfTy(Some(param_did), None)) |
-            (&ty::Param(_), Def::Def(DefKind::TyParam, param_did)) => {
+            (&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)?
             }
             _ => {
@@ -1680,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::Def(DefKind::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();
@@ -1703,16 +1703,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                     tcx.mk_opaque(did, substs),
                 )
             }
-            Def::Def(DefKind::Enum, did)
-            | Def::Def(DefKind::TyAlias, did)
-            | Def::Def(DefKind::Struct, did)
-            | Def::Def(DefKind::Union, did)
-            | Def::Def(DefKind::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::Def(kind @ DefKind::Variant, def_id) 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);
@@ -1732,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::Def(DefKind::TyParam, did) => {
+            Res::Def(DefKind::TyParam, did) => {
                 assert_eq!(opt_self_ty, None);
                 self.prohibit_generics(&path.segments);
 
@@ -1744,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::Def(DefKind::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,
@@ -1766,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 {
@@ -1778,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)
         }
     }
 
@@ -1828,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);
@@ -1838,12 +1838,12 @@ 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)
+                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) => {
@@ -1905,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::Def(DefKind::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);
@@ -2091,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::Def(DefKind::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
@@ -2100,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::Def(DefKind::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!()
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index bd04e12eb24..62afbc44d07 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -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, DefKind, 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::Def(DefKind::Const, _) | Def::Def(DefKind::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::Def(DefKind::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::Def(DefKind::Ctor(_, CtorKind::Fictive), _) |
-            Def::Def(DefKind::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::Def(DefKind::Ctor(_, CtorKind::Const), _) | Def::SelfCtor(..) |
-            Def::Def(DefKind::Const, _) | Def::Def(DefKind::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::Def(DefKind::AssociatedConst, _) | Def::Def(DefKind::Method, _) => {
-                report_unexpected_def(def);
+            Res::Def(DefKind::AssociatedConst, _) | Res::Def(DefKind::Method, _) => {
+                report_unexpected_res(res);
                 return tcx.types.err;
             }
-            Def::Def(DefKind::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()))
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index b8c0baff69b..61c281d3dd9 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -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
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index a3ee6ffe8da..647d947485e 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -1,5 +1,5 @@
 use rustc::hir::{self, GenericParamKind, ImplItemKind, TraitItemKind};
-use rustc::hir::def::{Def, DefKind};
+use rustc::hir::def::{Res, DefKind};
 use rustc::infer::{self, InferOk};
 use rustc::ty::{self, TyCtxt, GenericParamDefKind};
 use rustc::ty::util::ExplicitSelf;
@@ -845,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 Def::Def(DefKind::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);
                                         }
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 6fe7abda16d..1377f88df8f 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -234,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,
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index eef6627789d..b57ae361eb6 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -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, DefKind};
+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();
@@ -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::Def(DefKind::Trait, def_id) |
-            Def::Def(DefKind::TraitAlias, def_id) => {
+                           res: Res) {
+        match res {
+            Res::Def(DefKind::Trait, def_id) |
+            Res::Def(DefKind::TraitAlias, def_id) => {
                 traits.push(def_id);
             }
-            Def::Def(DefKind::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::Def(DefKind::Mod, def_id));
+        handle_external_res(tcx, &mut traits, &mut external_mods, Res::Def(DefKind::Mod, def_id));
     }
 
     traits
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 95e20e4e170..4ae75511322 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -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, DefKind};
+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)));
 }
 
@@ -3922,23 +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::Def(DefKind::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::Def(DefKind::Struct, _)
-            | Def::Def(DefKind::Union, _)
-            | Def::Def(DefKind::TyAlias, _)
-            | Def::Def(DefKind::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))
@@ -4233,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::Def(DefKind::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 {
@@ -4781,28 +4781,28 @@ 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 result = AstConv::associated_path_to_ty(
                     self,
                     hir_id,
                     path_span,
                     ty,
-                    def,
+                    res,
                     segment,
                     true,
                 );
@@ -4812,23 +4812,23 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 // Write back the new resolution.
                 self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, result);
 
-                (result.map(|(kind, def_id)| Def::Def(kind, def_id)).unwrap_or(Def::Err), 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[..]);
             }
@@ -4839,8 +4839,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         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.
-            let def = cached_result.map(|(kind, def_id)| Def::Def(kind, def_id))
-                .unwrap_or(Def::Err);
+            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;
@@ -4865,7 +4865,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // Write back the new resolution.
         self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, result);
         (
-            result.map(|(kind, def_id)| Def::Def(kind, def_id)).unwrap_or(Def::Err),
+            result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err),
             Some(ty),
             slice::from_ref(&**item_segment),
         )
@@ -5371,11 +5371,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     // Rewrite `SelfCtor` to `Ctor`
     pub fn rewrite_self_ctor(
         &self,
-        def: Def,
+        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();
 
@@ -5414,14 +5414,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 }
             }
         } else {
-            match def {
-                Def::Def(kind, def_id) => {
+            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 def in rewrite_self_ctor: {:?}", def),
+                _ => span_bug!(span, "unexpected res in rewrite_self_ctor: {:?}", res),
             }
         }
     }
@@ -5431,33 +5431,33 @@ 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 (kind, def_id, ty) = match self.rewrite_self_ctor(def, span) {
+        let (kind, def_id, ty) = match self.rewrite_self_ctor(res, span) {
             Ok(result) => result,
-            Err(ErrorReported) => return (tcx.types.err, def),
+            Err(ErrorReported) => return (tcx.types.err, res),
         };
         let path_segs =
             AstConv::def_ids_for_value_path_segments(self, segments, self_ty, kind, def_id);
@@ -5668,7 +5668,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                ty_substituted);
         self.write_substs(hir_id, substs);
 
-        (ty_substituted, Def::Def(kind, def_id))
+        (ty_substituted, Res::Def(kind, def_id))
     }
 
     fn check_rustc_args_require_const(&self,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 89409deb145..ed8ac89912c 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -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, DefKind};
+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::Def(DefKind::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::Def(DefKind::Struct, def_id)
-                                | Def::Def(DefKind::Union, def_id)
-                                | Def::Def(DefKind::Enum, def_id)
-                                | Def::Def(DefKind::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::Def(DefKind::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 \
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 365af15e006..d9d6b8e07e9 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -7,7 +7,7 @@ use syntax::ext::base::{MacroKind, SyntaxExtension};
 use syntax_pos::Span;
 
 use rustc::hir;
-use rustc::hir::def::{Def, DefKind, 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::Def(DefKind::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::Def(DefKind::Fn, did) => {
+        Res::Def(DefKind::Fn, did) => {
             record_extern_fqn(cx, did, clean::TypeKind::Function);
             clean::FunctionItem(build_external_function(cx, did))
         }
-        Def::Def(DefKind::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::Def(DefKind::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::Def(DefKind::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::Def(DefKind::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::Def(DefKind::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::Def(DefKind::Variant, _) => return None,
+        Res::Def(DefKind::Variant, _) => return None,
         // Assume that enum variants and struct types are re-exported next to
         // their constructors.
-        Def::Def(DefKind::Ctor(..), _) | Def::SelfCtor(..) => return Some(Vec::new()),
-        Def::Def(DefKind::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::Def(DefKind::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::Def(DefKind::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::Def(DefKind::Macro(MacroKind::Bang), did) => {
+        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::Def(DefKind::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)
                 }
             }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index d252a935e35..de74a6a5400 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -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, DefKind, 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::Def(DefKind::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,14 +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::Def(
+                        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)
                         })
@@ -297,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::Def(DefKind::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") {
@@ -326,14 +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::Def(
+                        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)
                         })
                     }
@@ -341,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()
         };
 
@@ -1163,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)
@@ -2787,7 +2787,7 @@ impl Clean<Type> for hir::Ty {
                 }
             }
             TyKind::Path(hir::QPath::Resolved(None, ref path)) => {
-                if let Def::Def(DefKind::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;
                     }
@@ -2797,7 +2797,7 @@ impl Clean<Type> for hir::Ty {
                 }
 
                 let mut alias = None;
-                if let Def::Def(DefKind::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) {
@@ -2896,9 +2896,9 @@ impl Clean<Type> for hir::Ty {
                 segments.pop();
                 let trait_path = hir::Path {
                     span: p.span,
-                    def: Def::Def(
+                    res: Res::Def(
                         DefKind::Trait,
-                        cx.tcx.associated_item(p.def.def_id()).container.id(),
+                        cx.tcx.associated_item(p.res.def_id()).container.id(),
                     ),
                     segments: segments.into(),
                 };
@@ -2909,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::Def(DefKind::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 {
@@ -3202,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)
             }
         })
@@ -3440,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>,
 }
 
@@ -3454,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),
         }
     }
@@ -3570,7 +3570,7 @@ fn strip_path(path: &Path) -> Path {
 
     Path {
         global: path.global,
-        def: path.def.clone(),
+        res: path.res.clone(),
         segments,
     }
 }
@@ -3904,7 +3904,7 @@ impl Clean<Vec<Item>> for doctree::ExternCrate {
         if please_inline {
             let mut visited = FxHashSet::default();
 
-            let def = Def::Def(
+            let res = Res::Def(
                 DefKind::Mod,
                 DefId {
                     krate: self.cnum,
@@ -3912,7 +3912,7 @@ impl Clean<Vec<Item>> for doctree::ExternCrate {
                 },
             );
 
-            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;
             }
         }
@@ -3950,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;
                 }
             }
@@ -3959,8 +3959,8 @@ impl Clean<Vec<Item>> for doctree::Import {
         } else {
             let name = self.name;
             if !please_inline {
-                match path.def {
-                    Def::Def(DefKind::Mod, did) => {
+                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
@@ -3972,7 +3972,7 @@ impl Clean<Vec<Item>> for doctree::Import {
             }
             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;
                 }
             }
@@ -4156,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),
@@ -4165,47 +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::Def(DefKind::TyParam, _) if path.segments.len() == 1 => {
+        Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => {
             return Generic(format!("{:#}", path));
         }
-        Def::SelfTy(..)
-        | Def::Def(DefKind::TyParam, _)
-        | Def::Def(DefKind::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::Def(DefKind::Fn, i) => (i, TypeKind::Function),
-        Def::Def(DefKind::TyAlias, i) => (i, TypeKind::Typedef),
-        Def::Def(DefKind::Enum, i) => (i, TypeKind::Enum),
-        Def::Def(DefKind::Trait, i) => (i, TypeKind::Trait),
-        Def::Def(DefKind::Struct, i) => (i, TypeKind::Struct),
-        Def::Def(DefKind::Union, i) => (i, TypeKind::Union),
-        Def::Def(DefKind::Mod, i) => (i, TypeKind::Module),
-        Def::Def(DefKind::ForeignTy, i) => (i, TypeKind::Foreign),
-        Def::Def(DefKind::Const, i) => (i, TypeKind::Const),
-        Def::Def(DefKind::Static, i) => (i, TypeKind::Static),
-        Def::Def(DefKind::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::Def(DefKind::Macro(mac_kind), i) => 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::Def(DefKind::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);
@@ -4217,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,
     }
@@ -4430,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::Def(DefKind::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;
                 }
             }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index f5b97797897..705b222efe8 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1,5 +1,5 @@
 use errors::Applicability;
-use rustc::hir::def::{Def, DefKind, 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::Def(DefKind::Method, _) | Def::Def(DefKind::AssociatedConst, _) => true,
-                    Def::Def(DefKind::AssociatedTy, _) => false,
-                    Def::Def(DefKind::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,11 +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::Def(DefKind::Struct, did)
-                | Def::Def(DefKind::Union, did)
-                | Def::Def(DefKind::Enum, did)
-                | Def::Def(DefKind::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))
@@ -147,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, _) => {
@@ -159,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"
@@ -175,7 +175,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                         }
                     }
                 }
-                Def::Def(DefKind::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);
@@ -193,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(())
                     }
@@ -283,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@",
@@ -318,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, &current_item, parent_node) {
-                            def
+                        if let Ok(res) = self.resolve(path_str, ns, &current_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
@@ -329,8 +329,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
                         }
                     }
                     Some(ns @ TypeNS) => {
-                        if let Ok(def) = self.resolve(path_str, ns, &current_item, parent_node) {
-                            def
+                        if let Ok(res) = self.resolve(path_str, ns, &current_item, parent_node) {
+                            res
                         } else {
                             resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
                             // This could just be a normal link.
@@ -340,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, &current_item, parent_node)
                                 .ok(),
                             value_ns: self
                                 .resolve(path_str, ValueNS, &current_item, parent_node)
                                 .ok()
-                                .and_then(|(def, fragment)| {
+                                .and_then(|(res, fragment)| {
                                     // Constructors are picked up in the type namespace.
-                                    match def {
-                                        Def::Def(DefKind::Ctor(..), _) | Def::SelfCtor(..) => None,
-                                        _ => Some((def, fragment))
+                                    match res {
+                                        Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) => None,
+                                        _ => Some((res, fragment))
                                     }
                                 }),
                         };
@@ -372,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
@@ -388,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));
             }
         }
@@ -422,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::Def(DefKind::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
     })
@@ -499,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, _)] => {
@@ -520,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());
                 }
             }
         }
@@ -542,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::Def(DefKind::Method, _) | Def::Def(DefKind::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::Def(DefKind::Macro(..), _) => {
+                    Res::Def(DefKind::Macro(..), _) => {
                         ("add an exclamation mark", format!("{}!", path_str))
                     }
                     _ => {
-                        let type_ = match (def, ns) {
-                            (Def::Def(DefKind::Const, _), _) => "const",
-                            (Def::Def(DefKind::Static, _), _) => "static",
-                            (Def::Def(DefKind::Struct, _), _) => "struct",
-                            (Def::Def(DefKind::Enum, _), _) => "enum",
-                            (Def::Def(DefKind::Union, _), _) => "union",
-                            (Def::Def(DefKind::Trait, _), _) => "trait",
-                            (Def::Def(DefKind::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",
@@ -575,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,
                 );
@@ -603,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::Def(DefKind::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 {
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index b7a617cdbd9..94d2d7ffdb8 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -2,7 +2,7 @@
 //! usable for `clean`.
 
 use rustc::hir::{self, Node};
-use rustc::hir::def::{Def, DefKind};
+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::Def(DefKind::Trait, did) |
-                Def::Def(DefKind::Struct, did) |
-                Def::Def(DefKind::Union, did) |
-                Def::Def(DefKind::Enum, did) |
-                Def::Def(DefKind::ForeignTy, did) |
-                Def::Def(DefKind::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::Def(DefKind::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,10 +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::Def(DefKind::Ctor(..), _)
-                    | Def::SelfCtor(..)
-                    | Def::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) => return,
+                match path.res {
+                    Res::Def(DefKind::Ctor(..), _)
+                    | Res::SelfCtor(..)
+                    | Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) => return,
                     _ => {}
                 }
 
@@ -440,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,
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 22c750011d9..326c9a10f7d 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -1,5 +1,5 @@
 use rustc::middle::privacy::{AccessLevels, AccessLevel};
-use rustc::hir::def::{Def, DefKind};
+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::Def(DefKind::Mod, _) = def {
+        if let Res::Def(DefKind::Mod, _) = res {
             let orig_level = self.prev_level;
 
             self.prev_level = item_level;
diff --git a/src/test/ui/imports/issue-53269.rs b/src/test/ui/imports/issue-53269.rs
index 444a16f7e7a..1031d507101 100644
--- a/src/test/ui/imports/issue-53269.rs
+++ b/src/test/ui/imports/issue-53269.rs
@@ -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 { () => () }
 
diff --git a/src/test/ui/imports/issue-53512.rs b/src/test/ui/imports/issue-53512.rs
index 61d93531a15..615b36a0b21 100644
--- a/src/test/ui/imports/issue-53512.rs
+++ b/src/test/ui/imports/issue-53512.rs
@@ -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`