about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-01-21 01:43:18 +0000
committerbors <bors@rust-lang.org>2016-01-21 01:43:18 +0000
commit51108b64ca3c84d9973736e6b9e094e79c12dc60 (patch)
tree822dd85b5aa9da12a90e48190be33afe0b01db89
parent7dce32e65d53ff9cfd8dba89121efa4c977030de (diff)
parent2084c2c33a47407c5ec514898d72701cf0233ba9 (diff)
downloadrust-51108b64ca3c84d9973736e6b9e094e79c12dc60.tar.gz
rust-51108b64ca3c84d9973736e6b9e094e79c12dc60.zip
Auto merge of #31010 - petrochenkov:def, r=arielb1
All structs and their constructors are defined as `DefStruct`.
`DefTy` is splitted into `DefEnum` and `DefTyAlias`.
Ad hoc flag `bool is_structure` is removed from `DefVariant`, it was required in one place in resolve and could be obtained by other means.
Flag `bool is_ctor` is removed from `DefFn`, it wasn't really used for constructors outside of metadata decoding.

Observable effects:
More specific error messages are selected in some cases.
Two name resolution bugs fixed (https://github.com/rust-lang/rust/issues/30992 and FIXME in compile-fail/empty-struct-braces-expr.rs).

Fixes https://github.com/rust-lang/rust/issues/30992
Closes https://github.com/rust-lang/rust/issues/30361
-rw-r--r--src/librustc/middle/astconv_util.rs4
-rw-r--r--src/librustc/middle/cfg/construct.rs4
-rw-r--r--src/librustc/middle/check_const.rs24
-rw-r--r--src/librustc/middle/check_match.rs30
-rw-r--r--src/librustc/middle/check_static_recursion.rs12
-rw-r--r--src/librustc/middle/const_eval.rs31
-rw-r--r--src/librustc/middle/cstore.rs11
-rw-r--r--src/librustc/middle/dead.rs11
-rw-r--r--src/librustc/middle/def.rs87
-rw-r--r--src/librustc/middle/effect.rs4
-rw-r--r--src/librustc/middle/expr_use_visitor.rs30
-rw-r--r--src/librustc/middle/infer/error_reporting.rs5
-rw-r--r--src/librustc/middle/intrinsicck.rs4
-rw-r--r--src/librustc/middle/liveness.rs10
-rw-r--r--src/librustc/middle/mem_categorization.rs47
-rw-r--r--src/librustc/middle/pat_util.rs10
-rw-r--r--src/librustc/middle/reachable.rs4
-rw-r--r--src/librustc/middle/resolve_lifetime.rs4
-rw-r--r--src/librustc/middle/stability.rs8
-rw-r--r--src/librustc/middle/ty/mod.rs34
-rw-r--r--src/librustc_lint/bad_style.rs6
-rw-r--r--src/librustc_lint/builtin.rs9
-rw-r--r--src/librustc_metadata/astencode.rs57
-rw-r--r--src/librustc_metadata/csearch.rs13
-rw-r--r--src/librustc_metadata/decoder.rs102
-rw-r--r--src/librustc_metadata/encoder.rs11
-rw-r--r--src/librustc_mir/hair/cx/expr.rs34
-rw-r--r--src/librustc_mir/hair/cx/pattern.rs10
-rw-r--r--src/librustc_privacy/lib.rs40
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs119
-rw-r--r--src/librustc_resolve/lib.rs83
-rw-r--r--src/librustc_resolve/resolve_imports.rs2
-rw-r--r--src/librustc_trans/save/dump_csv.rs76
-rw-r--r--src/librustc_trans/save/mod.rs31
-rw-r--r--src/librustc_trans/trans/_match.rs18
-rw-r--r--src/librustc_trans/trans/callee.rs34
-rw-r--r--src/librustc_trans/trans/common.rs6
-rw-r--r--src/librustc_trans/trans/consts.rs23
-rw-r--r--src/librustc_trans/trans/controlflow.rs4
-rw-r--r--src/librustc_trans/trans/expr.rs54
-rw-r--r--src/librustc_typeck/astconv.rs46
-rw-r--r--src/librustc_typeck/check/_match.rs22
-rw-r--r--src/librustc_typeck/check/callee.rs4
-rw-r--r--src/librustc_typeck/check/method/mod.rs8
-rw-r--r--src/librustc_typeck/check/method/suggest.rs6
-rw-r--r--src/librustc_typeck/check/mod.rs90
-rw-r--r--src/librustc_typeck/collect.rs12
-rw-r--r--src/librustc_typeck/lib.rs4
-rw-r--r--src/librustdoc/clean/inline.rs29
-rw-r--r--src/librustdoc/clean/mod.rs32
-rw-r--r--src/test/compile-fail/empty-struct-braces-expr.rs5
-rw-r--r--src/test/compile-fail/empty-struct-braces-pat-2.rs2
-rw-r--r--src/test/compile-fail/issue-10545.rs2
-rw-r--r--src/test/compile-fail/privacy1.rs2
-rw-r--r--src/test/compile-fail/struct-field-privacy.rs2
-rw-r--r--src/test/compile-fail/xcrate-unit-struct.rs3
-rw-r--r--src/test/run-pass/associated-const-match-patterns.rs21
57 files changed, 725 insertions, 671 deletions
diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs
index 2bf749d93ce..8b1bdc31beb 100644
--- a/src/librustc/middle/astconv_util.rs
+++ b/src/librustc/middle/astconv_util.rs
@@ -14,7 +14,7 @@
  * Almost certainly this could (and should) be refactored out of existence.
  */
 
-use middle::def;
+use middle::def::Def;
 use middle::ty::{self, Ty};
 
 use syntax::codemap::Span;
@@ -72,7 +72,7 @@ pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
             }
             Some(d) => d.full_def()
         };
-        if let def::DefPrimTy(nty) = def {
+        if let Def::PrimTy(nty) = def {
             Some(prim_ty_to_ty(tcx, &path.segments, nty))
         } else {
             None
diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs
index abe85125215..a6bcf70925c 100644
--- a/src/librustc/middle/cfg/construct.rs
+++ b/src/librustc/middle/cfg/construct.rs
@@ -10,7 +10,7 @@
 
 use rustc_data_structures::graph;
 use middle::cfg::*;
-use middle::def;
+use middle::def::Def;
 use middle::pat_util;
 use middle::ty;
 use syntax::ast;
@@ -591,7 +591,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
         }
 
         match self.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
-            Some(def::DefLabel(loop_id)) => {
+            Some(Def::Label(loop_id)) => {
                 for l in &self.loop_scopes {
                     if l.loop_id == loop_id {
                         return *l;
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index 5822b3dc5e9..68016a153b0 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -29,7 +29,7 @@ use middle::ty::cast::{CastKind};
 use middle::const_eval::{self, ConstEvalErr};
 use middle::const_eval::ErrKind::IndexOpFeatureGated;
 use middle::const_eval::EvalHint::ExprTypeChecked;
-use middle::def;
+use middle::def::Def;
 use middle::def_id::DefId;
 use middle::expr_use_visitor as euv;
 use middle::infer;
@@ -610,21 +610,21 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
         hir::ExprPath(..) => {
             let def = v.tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
             match def {
-                Some(def::DefVariant(_, _, _)) => {
+                Some(Def::Variant(..)) => {
                     // Count the discriminator or function pointer.
                     v.add_qualif(ConstQualif::NON_ZERO_SIZED);
                 }
-                Some(def::DefStruct(_)) => {
+                Some(Def::Struct(..)) => {
                     if let ty::TyBareFn(..) = node_ty.sty {
                         // Count the function pointer.
                         v.add_qualif(ConstQualif::NON_ZERO_SIZED);
                     }
                 }
-                Some(def::DefFn(..)) | Some(def::DefMethod(..)) => {
+                Some(Def::Fn(..)) | Some(Def::Method(..)) => {
                     // Count the function pointer.
                     v.add_qualif(ConstQualif::NON_ZERO_SIZED);
                 }
-                Some(def::DefStatic(..)) => {
+                Some(Def::Static(..)) => {
                     match v.mode {
                         Mode::Static | Mode::StaticMut => {}
                         Mode::Const | Mode::ConstFn => {
@@ -635,8 +635,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                         Mode::Var => v.add_qualif(ConstQualif::NOT_CONST)
                     }
                 }
-                Some(def::DefConst(did)) |
-                Some(def::DefAssociatedConst(did)) => {
+                Some(Def::Const(did)) |
+                Some(Def::AssociatedConst(did)) => {
                     if let Some(expr) = const_eval::lookup_const_by_id(v.tcx, did,
                                                                        Some(e.id),
                                                                        None) {
@@ -644,7 +644,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                         v.add_qualif(inner);
                     }
                 }
-                Some(def::DefLocal(..)) if v.mode == Mode::ConstFn => {
+                Some(Def::Local(..)) if v.mode == Mode::ConstFn => {
                     // Sadly, we can't determine whether the types are zero-sized.
                     v.add_qualif(ConstQualif::NOT_CONST | ConstQualif::NON_ZERO_SIZED);
                 }
@@ -672,16 +672,16 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
             }
             let def = v.tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def());
             let is_const = match def {
-                Some(def::DefStruct(..)) => true,
-                Some(def::DefVariant(..)) => {
+                Some(Def::Struct(..)) => true,
+                Some(Def::Variant(..)) => {
                     // Count the discriminator.
                     v.add_qualif(ConstQualif::NON_ZERO_SIZED);
                     true
                 }
-                Some(def::DefFn(did, _)) => {
+                Some(Def::Fn(did)) => {
                     v.handle_const_fn_call(e, did, node_ty)
                 }
-                Some(def::DefMethod(did)) => {
+                Some(Def::Method(did)) => {
                     match v.tcx.impl_or_trait_item(did).container() {
                         ty::ImplContainer(_) => {
                             v.handle_const_fn_call(e, did, node_ty)
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 8e5c5788201..d52089dbeab 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -246,7 +246,7 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
                 let pat_ty = cx.tcx.pat_ty(p);
                 if let ty::TyEnum(edef, _) = pat_ty.sty {
                     let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
-                    if let Some(DefLocal(..)) = def {
+                    if let Some(Def::Local(..)) = def {
                         if edef.variants.iter().any(|variant|
                             variant.name == ident.node.unhygienic_name
                                 && variant.kind() == VariantKind::Unit
@@ -454,8 +454,8 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
             hir::PatIdent(..) | hir::PatEnum(..) | hir::PatQPath(..) => {
                 let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
                 match def {
-                    Some(DefAssociatedConst(did)) |
-                    Some(DefConst(did)) => match lookup_const_by_id(self.tcx, did,
+                    Some(Def::AssociatedConst(did)) |
+                    Some(Def::Const(did)) => match lookup_const_by_id(self.tcx, did,
                                                                     Some(pat.id), None) {
                         Some(const_expr) => {
                             const_expr_to_pat(self.tcx, const_expr, pat.span).map(|new_pat| {
@@ -757,19 +757,19 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
     match pat.node {
         hir::PatIdent(..) =>
             match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
-                Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
+                Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
                     cx.tcx.sess.span_bug(pat.span, "const pattern should've \
                                                     been rewritten"),
-                Some(DefStruct(_)) => vec!(Single),
-                Some(DefVariant(_, id, _)) => vec!(Variant(id)),
+                Some(Def::Struct(..)) => vec!(Single),
+                Some(Def::Variant(_, id)) => vec!(Variant(id)),
                 _ => vec!()
             },
         hir::PatEnum(..) =>
             match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
-                Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
+                Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
                     cx.tcx.sess.span_bug(pat.span, "const pattern should've \
                                                     been rewritten"),
-                Some(DefVariant(_, id, _)) => vec!(Variant(id)),
+                Some(Def::Variant(_, id)) => vec!(Variant(id)),
                 _ => vec!(Single)
             },
         hir::PatQPath(..) =>
@@ -777,10 +777,10 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
                                             been rewritten"),
         hir::PatStruct(..) =>
             match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
-                Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
+                Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
                     cx.tcx.sess.span_bug(pat.span, "const pattern should've \
                                                     been rewritten"),
-                Some(DefVariant(_, id, _)) => vec!(Variant(id)),
+                Some(Def::Variant(_, id)) => vec!(Variant(id)),
                 _ => vec!(Single)
             },
         hir::PatLit(ref expr) =>
@@ -869,10 +869,10 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
         hir::PatIdent(_, _, _) => {
             let opt_def = cx.tcx.def_map.borrow().get(&pat_id).map(|d| d.full_def());
             match opt_def {
-                Some(DefConst(..)) | Some(DefAssociatedConst(..)) =>
+                Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
                     cx.tcx.sess.span_bug(pat_span, "const pattern should've \
                                                     been rewritten"),
-                Some(DefVariant(_, id, _)) => if *constructor == Variant(id) {
+                Some(Def::Variant(_, id)) => if *constructor == Variant(id) {
                     Some(vec!())
                 } else {
                     None
@@ -884,11 +884,11 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
         hir::PatEnum(_, ref args) => {
             let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
             match def {
-                DefConst(..) | DefAssociatedConst(..) =>
+                Def::Const(..) | Def::AssociatedConst(..) =>
                     cx.tcx.sess.span_bug(pat_span, "const pattern should've \
                                                     been rewritten"),
-                DefVariant(_, id, _) if *constructor != Variant(id) => None,
-                DefVariant(..) | DefStruct(..) => {
+                Def::Variant(_, id) if *constructor != Variant(id) => None,
+                Def::Variant(..) | Def::Struct(..) => {
                     Some(match args {
                         &Some(ref args) => args.iter().map(|p| &**p).collect(),
                         &None => vec![DUMMY_WILD_PAT; arity],
diff --git a/src/librustc/middle/check_static_recursion.rs b/src/librustc/middle/check_static_recursion.rs
index 0882f3f1137..abea48f0bd6 100644
--- a/src/librustc/middle/check_static_recursion.rs
+++ b/src/librustc/middle/check_static_recursion.rs
@@ -13,7 +13,7 @@
 
 use front::map as ast_map;
 use session::Session;
-use middle::def::{DefStatic, DefConst, DefAssociatedConst, DefVariant, DefMap};
+use middle::def::{Def, DefMap};
 use util::nodemap::NodeMap;
 
 use syntax::{ast};
@@ -238,9 +238,9 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
         match e.node {
             hir::ExprPath(..) => {
                 match self.def_map.get(&e.id).map(|d| d.base_def) {
-                    Some(DefStatic(def_id, _)) |
-                    Some(DefAssociatedConst(def_id)) |
-                    Some(DefConst(def_id)) => {
+                    Some(Def::Static(def_id, _)) |
+                    Some(Def::AssociatedConst(def_id)) |
+                    Some(Def::Const(def_id)) => {
                         if let Some(node_id) = self.ast_map.as_local_node_id(def_id) {
                             match self.ast_map.get(node_id) {
                                 ast_map::NodeItem(item) =>
@@ -263,7 +263,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
                     // affect the specific variant used, but we need to check
                     // the whole enum definition to see what expression that
                     // might be (if any).
-                    Some(DefVariant(enum_id, variant_id, false)) => {
+                    Some(Def::Variant(enum_id, variant_id)) => {
                         if let Some(enum_node_id) = self.ast_map.as_local_node_id(enum_id) {
                             if let hir::ItemEnum(ref enum_def, ref generics) =
                                 self.ast_map.expect_item(enum_node_id).node
@@ -276,7 +276,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
                             } else {
                                 self.sess.span_bug(e.span,
                                                    "`check_static_recursion` found \
-                                                    non-enum in DefVariant");
+                                                    non-enum in Def::Variant");
                             }
                         }
                     }
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index eae2aa9cb7e..942f2d6efb1 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -17,7 +17,8 @@ use self::EvalHint::*;
 use front::map as ast_map;
 use front::map::blocks::FnLikeNode;
 use middle::cstore::{self, CrateStore, InlinedItem};
-use middle::{def, infer, subst, traits};
+use middle::{infer, subst, traits};
+use middle::def::Def;
 use middle::subst::Subst;
 use middle::def_id::DefId;
 use middle::pat_util::def_to_path;
@@ -331,9 +332,9 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<hir::Pat>
                entry.insert(def);
             }
             let path = match def.full_def() {
-                def::DefStruct(def_id) => def_to_path(tcx, def_id),
-                def::DefVariant(_, variant_did, _) => def_to_path(tcx, variant_did),
-                def::DefFn(..) => return P(hir::Pat {
+                Def::Struct(def_id) => def_to_path(tcx, def_id),
+                Def::Variant(_, variant_did) => def_to_path(tcx, variant_did),
+                Def::Fn(..) => return P(hir::Pat {
                     id: expr.id,
                     node: hir::PatLit(P(expr.clone())),
                     span: span,
@@ -364,12 +365,12 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<hir::Pat>
         hir::ExprPath(_, ref path) => {
             let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def());
             match opt_def {
-                Some(def::DefStruct(..)) =>
+                Some(Def::Struct(..)) =>
                     hir::PatStruct(path.clone(), hir::HirVec::new(), false),
-                Some(def::DefVariant(..)) =>
+                Some(Def::Variant(..)) =>
                     hir::PatEnum(path.clone(), None),
-                Some(def::DefConst(def_id)) |
-                Some(def::DefAssociatedConst(def_id)) => {
+                Some(Def::Const(def_id)) |
+                Some(Def::AssociatedConst(def_id)) => {
                     let expr = lookup_const_by_id(tcx, def_id, Some(expr.id), None).unwrap();
                     return const_expr_to_pat(tcx, expr, span);
                 },
@@ -1002,7 +1003,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
               None
           };
           let (const_expr, const_ty) = match opt_def {
-              Some(def::DefConst(def_id)) => {
+              Some(Def::Const(def_id)) => {
                   if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
                       match tcx.map.find(node_id) {
                           Some(ast_map::NodeItem(it)) => match it.node {
@@ -1017,7 +1018,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
                       (lookup_const_by_id(tcx, def_id, Some(e.id), None), None)
                   }
               }
-              Some(def::DefAssociatedConst(def_id)) => {
+              Some(Def::AssociatedConst(def_id)) => {
                   if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
                       match tcx.impl_or_trait_item(def_id).container() {
                           ty::TraitContainer(trait_id) => match tcx.map.find(node_id) {
@@ -1052,21 +1053,21 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
                       (lookup_const_by_id(tcx, def_id, Some(e.id), None), None)
                   }
               }
-              Some(def::DefVariant(enum_def, variant_def, _)) => {
+              Some(Def::Variant(enum_def, variant_def)) => {
                   (lookup_variant_by_id(tcx, enum_def, variant_def), None)
               }
-              Some(def::DefStruct(_)) => {
+              Some(Def::Struct(..)) => {
                   return Ok(ConstVal::Struct(e.id))
               }
-              Some(def::DefLocal(_, id)) => {
-                  debug!("DefLocal({:?}): {:?}", id, fn_args);
+              Some(Def::Local(_, id)) => {
+                  debug!("Def::Local({:?}): {:?}", id, fn_args);
                   if let Some(val) = fn_args.and_then(|args| args.get(&id)) {
                       return Ok(val.clone());
                   } else {
                       (None, None)
                   }
               },
-              Some(def::DefMethod(id)) | Some(def::DefFn(id, _)) => return Ok(Function(id)),
+              Some(Def::Method(id)) | Some(Def::Fn(id)) => return Ok(Function(id)),
               _ => (None, None)
           };
           let const_expr = match const_expr {
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 380f543f969..27745a85935 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -24,9 +24,9 @@
 
 use back::svh::Svh;
 use front::map as hir_map;
-use middle::def;
+use middle::def::{self, Def};
 use middle::lang_items;
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, VariantKind};
 use middle::def_id::{DefId, DefIndex};
 use mir::repr::Mir;
 use session::Session;
@@ -84,7 +84,7 @@ enum_from_u32! {
 // Something that a name can resolve to.
 #[derive(Copy, Clone, Debug)]
 pub enum DefLike {
-    DlDef(def::Def),
+    DlDef(Def),
     DlImpl(DefId),
     DlField
 }
@@ -211,6 +211,8 @@ pub trait CrateStore<'tcx> : Any {
 
     // resolve
     fn def_path(&self, def: DefId) -> hir_map::DefPath;
+    fn variant_kind(&self, def_id: DefId) -> Option<VariantKind>;
+    fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>;
     fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>;
     fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
     fn item_children(&self, did: DefId) -> Vec<ChildItem>;
@@ -380,6 +382,9 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
 
     // resolve
     fn def_path(&self, def: DefId) -> hir_map::DefPath { unimplemented!() }
+    fn variant_kind(&self, def_id: DefId) -> Option<VariantKind> { unimplemented!() }
+    fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>
+        { unimplemented!() }
     fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>
         { unimplemented!() }
     fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { unimplemented!() }
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 1386ef91c70..1fa4093853b 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -17,7 +17,8 @@ use front::map as ast_map;
 use rustc_front::hir;
 use rustc_front::intravisit::{self, Visitor};
 
-use middle::{def, pat_util, privacy, ty};
+use middle::{pat_util, privacy, ty};
+use middle::def::Def;
 use middle::def_id::{DefId};
 use lint;
 
@@ -94,13 +95,13 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
 
         self.tcx.def_map.borrow().get(id).map(|def| {
             match def.full_def() {
-                def::DefConst(_) | def::DefAssociatedConst(..) => {
+                Def::Const(_) | Def::AssociatedConst(..) => {
                     self.check_def_id(def.def_id());
                 }
                 _ if self.ignore_non_const_paths => (),
-                def::DefPrimTy(_) => (),
-                def::DefSelfTy(..) => (),
-                def::DefVariant(enum_id, variant_id, _) => {
+                Def::PrimTy(_) => (),
+                Def::SelfTy(..) => (),
+                Def::Variant(enum_id, variant_id) => {
                     self.check_def_id(enum_id);
                     if !self.ignore_variant_stack.contains(&variant_id) {
                         self.check_def_id(variant_id);
diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs
index 9ef2828c947..be967da2713 100644
--- a/src/librustc/middle/def.rs
+++ b/src/librustc/middle/def.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub use self::Def::*;
-
 use middle::def_id::DefId;
 use middle::privacy::LastPrivate;
 use middle::subst::ParamSpace;
@@ -19,39 +17,36 @@ use rustc_front::hir;
 
 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Def {
-    DefFn(DefId, bool /* is_ctor */),
-    DefSelfTy(Option<DefId>,                    // trait id
+    Fn(DefId),
+    SelfTy(Option<DefId>,                    // trait id
               Option<(ast::NodeId, ast::NodeId)>),   // (impl id, self type id)
-    DefMod(DefId),
-    DefForeignMod(DefId),
-    DefStatic(DefId, bool /* is_mutbl */),
-    DefConst(DefId),
-    DefAssociatedConst(DefId),
-    DefLocal(DefId, // def id of variable
+    Mod(DefId),
+    ForeignMod(DefId),
+    Static(DefId, bool /* is_mutbl */),
+    Const(DefId),
+    AssociatedConst(DefId),
+    Local(DefId, // def id of variable
              ast::NodeId), // node id of variable
-    DefVariant(DefId /* enum */, DefId /* variant */, bool /* is_structure */),
-    DefTy(DefId, bool /* is_enum */),
-    DefAssociatedTy(DefId /* trait */, DefId),
-    DefTrait(DefId),
-    DefPrimTy(hir::PrimTy),
-    DefTyParam(ParamSpace, u32, DefId, ast::Name),
-    DefUpvar(DefId,        // def id of closed over local
+    Variant(DefId /* enum */, DefId /* variant */),
+    Enum(DefId),
+    TyAlias(DefId),
+    AssociatedTy(DefId /* trait */, DefId),
+    Trait(DefId),
+    PrimTy(hir::PrimTy),
+    TyParam(ParamSpace, u32, DefId, ast::Name),
+    Upvar(DefId,        // def id of closed over local
              ast::NodeId,  // node id of closed over local
              usize,        // index in the freevars list of the closure
              ast::NodeId), // expr node that creates the closure
 
-    /// Note that if it's a tuple struct's definition, the node id of the DefId
-    /// may either refer to the item definition's id or the VariantData.ctor_id.
-    ///
-    /// The cases that I have encountered so far are (this is not exhaustive):
-    /// - If it's a ty_path referring to some tuple struct, then DefMap maps
-    ///   it to a def whose id is the item definition's id.
-    /// - If it's an ExprPath referring to some tuple struct, then DefMap maps
-    ///   it to a def whose id is the VariantData.ctor_id.
-    DefStruct(DefId),
-    DefLabel(ast::NodeId),
-    DefMethod(DefId),
-    DefErr,
+    // If Def::Struct lives in type namespace it denotes a struct item and its DefId refers
+    // to NodeId of the struct itself.
+    // If Def::Struct lives in value namespace (e.g. tuple struct, unit struct expressions)
+    // it denotes a constructor and its DefId refers to NodeId of the struct's constructor.
+    Struct(DefId),
+    Label(ast::NodeId),
+    Method(DefId),
+    Err,
 }
 
 /// The result of resolving a path.
@@ -115,16 +110,16 @@ pub struct Export {
 impl Def {
     pub fn var_id(&self) -> ast::NodeId {
         match *self {
-            DefLocal(_, id) |
-            DefUpvar(_, id, _, _) => {
+            Def::Local(_, id) |
+            Def::Upvar(_, id, _, _) => {
                 id
             }
 
-            DefFn(..) | DefMod(..) | DefForeignMod(..) | DefStatic(..) |
-            DefVariant(..) | DefTy(..) | DefAssociatedTy(..) |
-            DefTyParam(..) | DefStruct(..) | DefTrait(..) |
-            DefMethod(..) | DefConst(..) | DefAssociatedConst(..) |
-            DefPrimTy(..) | DefLabel(..) | DefSelfTy(..) | DefErr => {
+            Def::Fn(..) | Def::Mod(..) | Def::ForeignMod(..) | Def::Static(..) |
+            Def::Variant(..) | Def::Enum(..) | Def::TyAlias(..) | Def::AssociatedTy(..) |
+            Def::TyParam(..) | Def::Struct(..) | Def::Trait(..) |
+            Def::Method(..) | Def::Const(..) | Def::AssociatedConst(..) |
+            Def::PrimTy(..) | Def::Label(..) | Def::SelfTy(..) | Def::Err => {
                 panic!("attempted .def_id() on invalid {:?}", self)
             }
         }
@@ -132,18 +127,18 @@ impl Def {
 
     pub fn def_id(&self) -> DefId {
         match *self {
-            DefFn(id, _) | DefMod(id) | DefForeignMod(id) | DefStatic(id, _) |
-            DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(_, id) |
-            DefTyParam(_, _, id, _) | DefStruct(id) | DefTrait(id) |
-            DefMethod(id) | DefConst(id) | DefAssociatedConst(id) |
-            DefLocal(id, _) | DefUpvar(id, _, _, _) => {
+            Def::Fn(id) | Def::Mod(id) | Def::ForeignMod(id) | Def::Static(id, _) |
+            Def::Variant(_, id) | Def::Enum(id) | Def::TyAlias(id) | Def::AssociatedTy(_, id) |
+            Def::TyParam(_, _, id, _) | Def::Struct(id) | Def::Trait(id) |
+            Def::Method(id) | Def::Const(id) | Def::AssociatedConst(id) |
+            Def::Local(id, _) | Def::Upvar(id, _, _, _) => {
                 id
             }
 
-            DefLabel(..)  |
-            DefPrimTy(..) |
-            DefSelfTy(..) |
-            DefErr => {
+            Def::Label(..)  |
+            Def::PrimTy(..) |
+            Def::SelfTy(..) |
+            Def::Err => {
                 panic!("attempted .def_id() on invalid def: {:?}", self)
             }
         }
@@ -151,7 +146,7 @@ impl Def {
 
     pub fn variant_def_ids(&self) -> Option<(DefId, DefId)> {
         match *self {
-            DefVariant(enum_id, var_id, _) => {
+            Def::Variant(enum_id, var_id) => {
                 Some((enum_id, var_id))
             }
             _ => None
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs
index 822faae7726..055beac5428 100644
--- a/src/librustc/middle/effect.rs
+++ b/src/librustc/middle/effect.rs
@@ -12,7 +12,7 @@
 //! `unsafe`.
 use self::RootUnsafeContext::*;
 
-use middle::def;
+use middle::def::Def;
 use middle::ty::{self, Ty};
 use middle::ty::MethodCall;
 
@@ -170,7 +170,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
                 self.require_unsafe(expr.span, "use of inline assembly");
             }
             hir::ExprPath(..) => {
-                if let def::DefStatic(_, true) = self.tcx.resolve_expr(expr) {
+                if let Def::Static(_, true) = self.tcx.resolve_expr(expr) {
                     self.require_unsafe(expr.span, "use of mutable static");
                 }
             }
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index e746f3ac579..b5baf84eef2 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -19,7 +19,8 @@ pub use self::MatchMode::*;
 use self::TrackMatchMode::*;
 use self::OverloadedCallType::*;
 
-use middle::{def, pat_util};
+use middle::pat_util;
+use middle::def::Def;
 use middle::def_id::{DefId};
 use middle::infer;
 use middle::mem_categorization as mc;
@@ -1077,7 +1078,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
                             // struct or enum pattern.
                         }
 
-                        Some(def::DefVariant(enum_did, variant_did, _is_struct)) => {
+                        Some(Def::Variant(enum_did, variant_did)) => {
                             let downcast_cmt =
                                 if tcx.lookup_adt_def(enum_did).is_univariant() {
                                     cmt_pat
@@ -1093,7 +1094,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
                             delegate.matched_pat(pat, downcast_cmt, match_mode);
                         }
 
-                        Some(def::DefStruct(..)) | Some(def::DefTy(_, false)) => {
+                        Some(Def::Struct(..)) | Some(Def::TyAlias(..)) => {
                             // A struct (in either the value or type
                             // namespace; we encounter the former on
                             // e.g. patterns for unit structs).
@@ -1105,28 +1106,17 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
                             delegate.matched_pat(pat, cmt_pat, match_mode);
                         }
 
-                        Some(def::DefConst(..)) |
-                        Some(def::DefAssociatedConst(..)) |
-                        Some(def::DefLocal(..)) => {
+                        Some(Def::Const(..)) |
+                        Some(Def::AssociatedConst(..)) |
+                        Some(Def::Local(..)) => {
                             // This is a leaf (i.e. identifier binding
                             // or constant value to match); thus no
                             // `matched_pat` call.
                         }
 
-                        Some(def @ def::DefTy(_, true)) => {
-                            // An enum's type -- should never be in a
-                            // pattern.
-
-                            if !tcx.sess.has_errors() {
-                                let msg = format!("Pattern has unexpected type: {:?} and type {:?}",
-                                                  def,
-                                                  cmt_pat.ty);
-                                tcx.sess.span_bug(pat.span, &msg)
-                            }
-                        }
-
                         Some(def) => {
-                            // Remaining cases are e.g. DefFn, to
+                            // An enum type should never be in a pattern.
+                            // Remaining cases are e.g. Def::Fn, to
                             // which identifiers within patterns
                             // should not resolve. However, we do
                             // encouter this when using the
@@ -1195,7 +1185,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
     fn cat_captured_var(&mut self,
                         closure_id: ast::NodeId,
                         closure_span: Span,
-                        upvar_def: def::Def)
+                        upvar_def: Def)
                         -> mc::McResult<mc::cmt<'tcx>> {
         // Create the cmt for the variable being borrowed, from the
         // caller's perspective
diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs
index 5cc848d2ca3..b83cd60031d 100644
--- a/src/librustc/middle/infer/error_reporting.rs
+++ b/src/librustc/middle/infer/error_reporting.rs
@@ -77,7 +77,7 @@ use rustc_front::hir;
 use rustc_front::print::pprust;
 
 use middle::cstore::CrateStore;
-use middle::def;
+use middle::def::Def;
 use middle::def_id::DefId;
 use middle::infer::{self, TypeOrigin};
 use middle::region;
@@ -1404,7 +1404,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
                         Some(d) => d.full_def()
                     };
                     match a_def {
-                        def::DefTy(did, _) | def::DefStruct(did) => {
+                        Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) => {
                             let generics = self.tcx.lookup_item_type(did).generics;
 
                             let expected =
@@ -1452,7 +1452,6 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
                         }
                         _ => ()
                     }
-
                 }
 
                 hir::TyPtr(ref mut_ty) => {
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index 69b952ca1f3..9afc1e366ee 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use dep_graph::DepNode;
-use middle::def::DefFn;
+use middle::def::Def;
 use middle::def_id::DefId;
 use middle::subst::{Subst, Substs, EnumeratedItems};
 use middle::ty::{TransmuteRestriction, ctxt, TyBareFn};
@@ -235,7 +235,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
     fn visit_expr(&mut self, expr: &hir::Expr) {
         if let hir::ExprPath(..) = expr.node {
             match self.tcx.resolve_expr(expr) {
-                DefFn(did, _) if self.def_id_is_transmute(did) => {
+                Def::Fn(did) if self.def_id_is_transmute(did) => {
                     let typ = self.tcx.node_id_to_type(expr.id);
                     match typ.sty {
                         TyBareFn(_, ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => {
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 29299f01ed3..90fa148e008 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -448,7 +448,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
       hir::ExprPath(..) => {
         let def = ir.tcx.def_map.borrow().get(&expr.id).unwrap().full_def();
         debug!("expr {}: path that leads to {:?}", expr.id, def);
-        if let DefLocal(..) = def {
+        if let Def::Local(..) = def {
             ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
         }
         intravisit::walk_expr(ir, expr);
@@ -465,7 +465,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
         let mut call_caps = Vec::new();
         ir.tcx.with_freevars(expr.id, |freevars| {
             for fv in freevars {
-                if let DefLocal(_, rv) = fv.def {
+                if let Def::Local(_, rv) = fv.def {
                     let fv_ln = ir.add_live_node(FreeVarNode(fv.span));
                     call_caps.push(CaptureInfo {ln: fv_ln,
                                                 var_nid: rv});
@@ -697,7 +697,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                 // Refers to a labeled loop. Use the results of resolve
                 // to find with one
                 match self.ir.tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
-                    Some(DefLabel(loop_id)) => loop_id,
+                    Some(Def::Label(loop_id)) => loop_id,
                     _ => self.ir.tcx.sess.span_bug(sp, "label on break/loop \
                                                         doesn't refer to a loop")
                 }
@@ -1276,7 +1276,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
                    -> LiveNode {
         match self.ir.tcx.def_map.borrow().get(&expr.id).unwrap().full_def() {
-          DefLocal(_, nid) => {
+          Def::Local(_, nid) => {
             let ln = self.live_node(expr.id, expr.span);
             if acc != 0 {
                 self.init_from_succ(ln, succ);
@@ -1531,7 +1531,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     fn check_lvalue(&mut self, expr: &Expr) {
         match expr.node {
             hir::ExprPath(..) => {
-                if let DefLocal(_, nid) = self.ir.tcx.def_map.borrow().get(&expr.id)
+                if let Def::Local(_, nid) = self.ir.tcx.def_map.borrow().get(&expr.id)
                                                                       .unwrap()
                                                                       .full_def() {
                     // Assignment to an immutable variable or argument: only legal
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 1eb5efa0bda..55bbde21514 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -75,7 +75,7 @@ use middle::def_id::DefId;
 use front::map as ast_map;
 use middle::infer;
 use middle::check_const;
-use middle::def;
+use middle::def::Def;
 use middle::ty::adjustment;
 use middle::ty::{self, Ty};
 
@@ -542,32 +542,27 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
                    id: ast::NodeId,
                    span: Span,
                    expr_ty: Ty<'tcx>,
-                   def: def::Def)
+                   def: Def)
                    -> McResult<cmt<'tcx>> {
         debug!("cat_def: id={} expr={:?} def={:?}",
                id, expr_ty, def);
 
         match def {
-          def::DefStruct(..) | def::DefVariant(..) | def::DefConst(..) |
-          def::DefAssociatedConst(..) | def::DefFn(..) | def::DefMethod(..) => {
+          Def::Struct(..) | Def::Variant(..) | Def::Const(..) |
+          Def::AssociatedConst(..) | Def::Fn(..) | Def::Method(..) => {
                 Ok(self.cat_rvalue_node(id, span, expr_ty))
           }
-          def::DefMod(_) | def::DefForeignMod(_) |
-          def::DefTrait(_) | def::DefTy(..) | def::DefPrimTy(_) |
-          def::DefTyParam(..) |
-          def::DefLabel(_) | def::DefSelfTy(..) |
-          def::DefAssociatedTy(..) => {
-              Ok(Rc::new(cmt_ {
-                  id:id,
-                  span:span,
-                  cat:Categorization::StaticItem,
-                  mutbl: McImmutable,
-                  ty:expr_ty,
-                  note: NoteNone
-              }))
+
+          Def::Mod(_) | Def::ForeignMod(_) |
+          Def::Trait(_) | Def::Enum(..) | Def::TyAlias(..) | Def::PrimTy(_) |
+          Def::TyParam(..) |
+          Def::Label(_) | Def::SelfTy(..) |
+          Def::AssociatedTy(..) => {
+              self.tcx().sess.span_bug(span, &format!("Unexpected definition in \
+                                                       memory categorization: {:?}", def));
           }
 
-          def::DefStatic(_, mutbl) => {
+          Def::Static(_, mutbl) => {
               Ok(Rc::new(cmt_ {
                   id:id,
                   span:span,
@@ -578,7 +573,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
               }))
           }
 
-          def::DefUpvar(_, var_id, _, fn_node_id) => {
+          Def::Upvar(_, var_id, _, fn_node_id) => {
               let ty = try!(self.node_ty(fn_node_id));
               match ty.sty {
                   ty::TyClosure(closure_id, _) => {
@@ -603,7 +598,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
               }
           }
 
-          def::DefLocal(_, vid) => {
+          Def::Local(_, vid) => {
             Ok(Rc::new(cmt_ {
                 id: id,
                 span: span,
@@ -614,7 +609,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
             }))
           }
 
-          def::DefErr => panic!("DefErr in memory categorization")
+          Def::Err => panic!("Def::Err in memory categorization")
         }
     }
 
@@ -1202,7 +1197,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
         (*op)(self, cmt.clone(), pat);
 
         let opt_def = if let Some(path_res) = self.tcx().def_map.borrow().get(&pat.id) {
-            if path_res.depth != 0 || path_res.base_def == def::DefErr {
+            if path_res.depth != 0 || path_res.base_def == Def::Err {
                 // Since patterns can be associated constants
                 // which are resolved during typeck, we might have
                 // some unresolved patterns reaching this stage
@@ -1218,7 +1213,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
         // alone) because struct patterns can refer to struct types or
         // to struct variants within enums.
         let cmt = match opt_def {
-            Some(def::DefVariant(enum_did, variant_did, _))
+            Some(Def::Variant(enum_did, variant_did))
                 // univariant enums do not need downcasts
                 if !self.tcx().lookup_adt_def(enum_did).is_univariant() => {
                     self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did)
@@ -1236,7 +1231,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
           }
           hir::PatEnum(_, Some(ref subpats)) => {
             match opt_def {
-                Some(def::DefVariant(..)) => {
+                Some(Def::Variant(..)) => {
                     // variant(x, y, z)
                     for (i, subpat) in subpats.iter().enumerate() {
                         let subpat_ty = try!(self.pat_ty(&**subpat)); // see (*2)
@@ -1249,7 +1244,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
                         try!(self.cat_pattern_(subcmt, &**subpat, op));
                     }
                 }
-                Some(def::DefStruct(..)) => {
+                Some(Def::Struct(..)) => {
                     for (i, subpat) in subpats.iter().enumerate() {
                         let subpat_ty = try!(self.pat_ty(&**subpat)); // see (*2)
                         let cmt_field =
@@ -1259,7 +1254,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
                         try!(self.cat_pattern_(cmt_field, &**subpat, op));
                     }
                 }
-                Some(def::DefConst(..)) | Some(def::DefAssociatedConst(..)) => {
+                Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => {
                     for subpat in subpats {
                         try!(self.cat_pattern_(cmt.clone(), &**subpat, op));
                     }
diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs
index 1284e9fd145..41367b9361f 100644
--- a/src/librustc/middle/pat_util.rs
+++ b/src/librustc/middle/pat_util.rs
@@ -39,7 +39,7 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
         hir::PatIdent(_, _, None) |
         hir::PatStruct(..) => {
             match dm.get(&pat.id).map(|d| d.full_def()) {
-                Some(DefVariant(..)) => true,
+                Some(Def::Variant(..)) => true,
                 _ => false
             }
         }
@@ -54,7 +54,7 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool {
         hir::PatIdent(_, _, None) |
         hir::PatStruct(..) => {
             match dm.get(&pat.id).map(|d| d.full_def()) {
-                Some(DefVariant(..)) | Some(DefStruct(..)) => true,
+                Some(Def::Variant(..)) | Some(Def::Struct(..)) => true,
                 _ => false
             }
         }
@@ -66,7 +66,7 @@ pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool {
     match pat.node {
         hir::PatIdent(_, _, None) | hir::PatEnum(..) | hir::PatQPath(..) => {
             match dm.get(&pat.id).map(|d| d.full_def()) {
-                Some(DefConst(..)) | Some(DefAssociatedConst(..)) => true,
+                Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true,
                 _ => false
             }
         }
@@ -82,7 +82,7 @@ pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool {
             match dm.get(&pat.id)
                     .and_then(|d| if d.depth == 0 { Some(d.base_def) }
                                   else { None } ) {
-                Some(DefConst(..)) | Some(DefAssociatedConst(..)) => true,
+                Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true,
                 _ => false
             }
         }
@@ -228,7 +228,7 @@ pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<DefId> {
             hir::PatIdent(_, _, None) |
             hir::PatStruct(..) => {
                 match dm.get(&p.id) {
-                    Some(&PathResolution { base_def: DefVariant(_, id, _), .. }) => {
+                    Some(&PathResolution { base_def: Def::Variant(_, id), .. }) => {
                         variants.push(id);
                     }
                     _ => ()
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 738440adf41..6373bfbc55e 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -17,7 +17,7 @@
 
 use dep_graph::DepNode;
 use front::map as ast_map;
-use middle::def;
+use middle::def::Def;
 use middle::def_id::DefId;
 use middle::ty;
 use middle::privacy;
@@ -108,7 +108,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> 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::DefConst(..) | def::DefAssociatedConst(..) => {
+                            Def::Const(..) | Def::AssociatedConst(..) => {
                                 self.worklist.push(node_id);
                             }
 
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 2c74f3a82e4..af9d0987ff0 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -19,7 +19,7 @@ pub use self::DefRegion::*;
 use self::ScopeChain::*;
 
 use session::Session;
-use middle::def::{self, DefMap};
+use middle::def::{Def, DefMap};
 use middle::region;
 use middle::subst;
 use middle::ty;
@@ -205,7 +205,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
                 // if this path references a trait, then this will resolve to
                 // a trait ref, which introduces a binding scope.
                 match self.def_map.get(&ty.id).map(|d| (d.base_def, d.depth)) {
-                    Some((def::DefTrait(..), 0)) => {
+                    Some((Def::Trait(..), 0)) => {
                         self.with(LateScope(&[], self.scope), |_, this| {
                             this.visit_path(path, ty.id);
                         });
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 87bc8bb8855..e0d38f1c76f 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -17,7 +17,7 @@ use dep_graph::DepNode;
 use session::Session;
 use lint;
 use middle::cstore::{CrateStore, LOCAL_CRATE};
-use middle::def;
+use middle::def::Def;
 use middle::def_id::{CRATE_DEF_INDEX, DefId};
 use middle::ty;
 use middle::privacy::AccessLevels;
@@ -561,8 +561,8 @@ pub fn check_expr(tcx: &ty::ctxt, e: &hir::Expr,
 pub fn check_path(tcx: &ty::ctxt, path: &hir::Path, id: ast::NodeId,
                   cb: &mut FnMut(DefId, Span, &Option<&Stability>, &Option<Deprecation>)) {
     match tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
-        Some(def::DefPrimTy(..)) => {}
-        Some(def::DefSelfTy(..)) => {}
+        Some(Def::PrimTy(..)) => {}
+        Some(Def::SelfTy(..)) => {}
         Some(def) => {
             maybe_do_stability_check(tcx, def.def_id(), path.span, cb);
         }
@@ -573,7 +573,7 @@ pub fn check_path(tcx: &ty::ctxt, path: &hir::Path, id: ast::NodeId,
 pub fn check_path_list_item(tcx: &ty::ctxt, item: &hir::PathListItem,
                   cb: &mut FnMut(DefId, Span, &Option<&Stability>, &Option<Deprecation>)) {
     match tcx.def_map.borrow().get(&item.node.id()).map(|d| d.full_def()) {
-        Some(def::DefPrimTy(..)) => {}
+        Some(Def::PrimTy(..)) => {}
         Some(def) => {
             maybe_do_stability_check(tcx, def.def_id(), item.span, cb);
         }
diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs
index b902a46fea3..a56752db137 100644
--- a/src/librustc/middle/ty/mod.rs
+++ b/src/librustc/middle/ty/mod.rs
@@ -24,7 +24,7 @@ use front::map as ast_map;
 use front::map::LinkedPath;
 use middle;
 use middle::cstore::{self, CrateStore, LOCAL_CRATE};
-use middle::def::{self, ExportMap};
+use middle::def::{self, Def, ExportMap};
 use middle::def_id::DefId;
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
 use middle::region::{CodeExtent};
@@ -587,7 +587,7 @@ pub type UpvarCaptureMap = FnvHashMap<UpvarId, UpvarCapture>;
 
 #[derive(Copy, Clone)]
 pub struct ClosureUpvar<'tcx> {
-    pub def: def::Def,
+    pub def: Def,
     pub span: Span,
     pub ty: Ty<'tcx>,
 }
@@ -1429,9 +1429,19 @@ impl<'tcx> Decodable for AdtDef<'tcx> {
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum AdtKind { Struct, Enum }
 
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub enum VariantKind { Struct, Tuple, Unit }
 
+impl VariantKind {
+    pub fn from_variant_data(vdata: &hir::VariantData) -> Self {
+        match *vdata {
+            hir::VariantData::Struct(..) => VariantKind::Struct,
+            hir::VariantData::Tuple(..) => VariantKind::Tuple,
+            hir::VariantData::Unit(..) => VariantKind::Unit,
+        }
+    }
+}
+
 impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
     fn new(tcx: &ctxt<'tcx>,
            did: DefId,
@@ -1575,10 +1585,10 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> {
             .expect("variant_index_with_id: unknown variant")
     }
 
-    pub fn variant_of_def(&self, def: def::Def) -> &VariantDefData<'tcx, 'container> {
+    pub fn variant_of_def(&self, def: Def) -> &VariantDefData<'tcx, 'container> {
         match def {
-            def::DefVariant(_, vid, _) => self.variant_with_id(vid),
-            def::DefStruct(..) | def::DefTy(..) => self.struct_variant(),
+            Def::Variant(_, vid) => self.variant_with_id(vid),
+            Def::Struct(..) | Def::TyAlias(..) => self.struct_variant(),
             _ => panic!("unexpected def {:?} in variant_of_def", def)
         }
     }
@@ -1924,7 +1934,7 @@ impl<'tcx> ctxt<'tcx> {
         }
     }
 
-    pub fn resolve_expr(&self, expr: &hir::Expr) -> def::Def {
+    pub fn resolve_expr(&self, expr: &hir::Expr) -> Def {
         match self.def_map.borrow().get(&expr.id) {
             Some(def) => def.full_def(),
             None => {
@@ -1942,15 +1952,15 @@ impl<'tcx> ctxt<'tcx> {
                 // rvalues.
                 match self.def_map.borrow().get(&expr.id) {
                     Some(&def::PathResolution {
-                        base_def: def::DefStatic(..), ..
+                        base_def: Def::Static(..), ..
                     }) | Some(&def::PathResolution {
-                        base_def: def::DefUpvar(..), ..
+                        base_def: Def::Upvar(..), ..
                     }) | Some(&def::PathResolution {
-                        base_def: def::DefLocal(..), ..
+                        base_def: Def::Local(..), ..
                     }) => {
                         true
                     }
-                    Some(&def::PathResolution { base_def: def::DefErr, .. })=> true,
+                    Some(&def::PathResolution { base_def: Def::Err, .. })=> true,
                     Some(..) => false,
                     None => self.sess.span_bug(expr.span, &format!(
                         "no def for path {}", expr.id))
@@ -2612,7 +2622,7 @@ pub enum ExplicitSelfCategory {
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
 pub struct Freevar {
     /// The variable being accessed free.
-    pub def: def::Def,
+    pub def: Def,
 
     // First span where it is accessed (there can be multiple).
     pub span: Span
diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs
index b5f8be496fb..367475a14a2 100644
--- a/src/librustc_lint/bad_style.rs
+++ b/src/librustc_lint/bad_style.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use middle::def;
+use middle::def::Def;
 use middle::ty;
 use lint::{LateContext, LintContext, LintArray};
 use lint::{LintPass, LateLintPass};
@@ -274,7 +274,7 @@ impl LateLintPass for NonSnakeCase {
     fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
         if let &hir::PatIdent(_, ref path1, _) = &p.node {
             let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
-            if let Some(def::DefLocal(..)) = def {
+            if let Some(Def::Local(..)) = def {
                 self.check_snake_case(cx, "variable", &path1.node.name.as_str(), Some(p.span));
             }
         }
@@ -362,7 +362,7 @@ impl LateLintPass for NonUpperCaseGlobals {
     fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
         // Lint for constants that look like binding identifiers (#7526)
         match (&p.node, cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def())) {
-            (&hir::PatIdent(_, ref path1, _), Some(def::DefConst(..))) => {
+            (&hir::PatIdent(_, ref path1, _), Some(Def::Const(..))) => {
                 NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
                                                       path1.node.name, p.span);
             }
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 8985b1e56bc..8621743668b 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -28,7 +28,8 @@
 //! Use the former for unit-like structs and the latter for structs with
 //! a `pub fn new()`.
 
-use middle::{cfg, def, infer, stability, traits};
+use middle::{cfg, infer, stability, traits};
+use middle::def::Def;
 use middle::cstore::CrateStore;
 use middle::def_id::DefId;
 use middle::subst::Substs;
@@ -163,7 +164,7 @@ impl LateLintPass for NonShorthandFieldPatterns {
                 }
                 let def = def_map.get(&fieldpat.node.pat.id).map(|d| d.full_def());
                 if let Some(def_id) = cx.tcx.map.opt_local_def_id(fieldpat.node.pat.id) {
-                    def == Some(def::DefLocal(def_id, fieldpat.node.pat.id))
+                    def == Some(Def::Local(def_id, fieldpat.node.pat.id))
                 } else {
                     false
                 }
@@ -819,7 +820,7 @@ impl LateLintPass for UnconditionalRecursion {
             match tcx.map.get(id) {
                 hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => {
                     match tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def()) {
-                        Some(def::DefMethod(def_id)) => {
+                        Some(Def::Method(def_id)) => {
                             let item_substs =
                                 tcx.tables.borrow().item_substs
                                                    .get(&callee.id)
@@ -1060,7 +1061,7 @@ impl LateLintPass for MutableTransmutes {
                 hir::ExprPath(..) => (),
                 _ => return None
             }
-            if let def::DefFn(did, _) = cx.tcx.resolve_expr(expr) {
+            if let Def::Fn(did) = cx.tcx.resolve_expr(expr) {
                 if !def_id_is_transmute(cx, did) {
                     return None;
                 }
diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs
index 8c3bd3c4f8a..f0cd75ba958 100644
--- a/src/librustc_metadata/astencode.rs
+++ b/src/librustc_metadata/astencode.rs
@@ -30,7 +30,7 @@ use middle::cstore::{InlinedItem, InlinedItemRef};
 use middle::ty::adjustment;
 use middle::ty::cast;
 use middle::check_const::ConstQualif;
-use middle::def;
+use middle::def::{self, Def};
 use middle::def_id::DefId;
 use middle::privacy::{AllPublic, LastMod};
 use middle::region;
@@ -368,49 +368,48 @@ fn decode_ast(par_doc: rbml::Doc) -> InlinedItem {
 // ______________________________________________________________________
 // Encoding and decoding of ast::def
 
-fn decode_def(dcx: &DecodeContext, dsr: &mut reader::Decoder) -> def::Def {
-    let def: def::Def = Decodable::decode(dsr).unwrap();
+fn decode_def(dcx: &DecodeContext, dsr: &mut reader::Decoder) -> Def {
+    let def: Def = Decodable::decode(dsr).unwrap();
     def.tr(dcx)
 }
 
-impl tr for def::Def {
-    fn tr(&self, dcx: &DecodeContext) -> def::Def {
+impl tr for Def {
+    fn tr(&self, dcx: &DecodeContext) -> Def {
         match *self {
-          def::DefFn(did, is_ctor) => def::DefFn(did.tr(dcx), is_ctor),
-          def::DefMethod(did) => def::DefMethod(did.tr(dcx)),
-          def::DefSelfTy(opt_did, impl_ids) => { def::DefSelfTy(opt_did.map(|did| did.tr(dcx)),
+          Def::Fn(did) => Def::Fn(did.tr(dcx)),
+          Def::Method(did) => Def::Method(did.tr(dcx)),
+          Def::SelfTy(opt_did, impl_ids) => { Def::SelfTy(opt_did.map(|did| did.tr(dcx)),
                                                                 impl_ids.map(|(nid1, nid2)| {
                                                                     (dcx.tr_id(nid1),
                                                                      dcx.tr_id(nid2))
                                                                 })) }
-          def::DefMod(did) => { def::DefMod(did.tr(dcx)) }
-          def::DefForeignMod(did) => { def::DefForeignMod(did.tr(dcx)) }
-          def::DefStatic(did, m) => { def::DefStatic(did.tr(dcx), m) }
-          def::DefConst(did) => { def::DefConst(did.tr(dcx)) }
-          def::DefAssociatedConst(did) => def::DefAssociatedConst(did.tr(dcx)),
-          def::DefLocal(_, nid) => {
+          Def::Mod(did) => { Def::Mod(did.tr(dcx)) }
+          Def::ForeignMod(did) => { Def::ForeignMod(did.tr(dcx)) }
+          Def::Static(did, m) => { Def::Static(did.tr(dcx), m) }
+          Def::Const(did) => { Def::Const(did.tr(dcx)) }
+          Def::AssociatedConst(did) => Def::AssociatedConst(did.tr(dcx)),
+          Def::Local(_, nid) => {
               let nid = dcx.tr_id(nid);
               let did = dcx.tcx.map.local_def_id(nid);
-              def::DefLocal(did, nid)
+              Def::Local(did, nid)
           }
-          def::DefVariant(e_did, v_did, is_s) => {
-            def::DefVariant(e_did.tr(dcx), v_did.tr(dcx), is_s)
-          },
-          def::DefTrait(did) => def::DefTrait(did.tr(dcx)),
-          def::DefTy(did, is_enum) => def::DefTy(did.tr(dcx), is_enum),
-          def::DefAssociatedTy(trait_did, did) =>
-              def::DefAssociatedTy(trait_did.tr(dcx), did.tr(dcx)),
-          def::DefPrimTy(p) => def::DefPrimTy(p),
-          def::DefTyParam(s, index, def_id, n) => def::DefTyParam(s, index, def_id.tr(dcx), n),
-          def::DefUpvar(_, nid1, index, nid2) => {
+          Def::Variant(e_did, v_did) => Def::Variant(e_did.tr(dcx), v_did.tr(dcx)),
+          Def::Trait(did) => Def::Trait(did.tr(dcx)),
+          Def::Enum(did) => Def::Enum(did.tr(dcx)),
+          Def::TyAlias(did) => Def::TyAlias(did.tr(dcx)),
+          Def::AssociatedTy(trait_did, did) =>
+              Def::AssociatedTy(trait_did.tr(dcx), did.tr(dcx)),
+          Def::PrimTy(p) => Def::PrimTy(p),
+          Def::TyParam(s, index, def_id, n) => Def::TyParam(s, index, def_id.tr(dcx), n),
+          Def::Upvar(_, nid1, index, nid2) => {
               let nid1 = dcx.tr_id(nid1);
               let nid2 = dcx.tr_id(nid2);
               let did1 = dcx.tcx.map.local_def_id(nid1);
-              def::DefUpvar(did1, nid1, index, nid2)
+              Def::Upvar(did1, nid1, index, nid2)
           }
-          def::DefStruct(did) => def::DefStruct(did.tr(dcx)),
-          def::DefLabel(nid) => def::DefLabel(dcx.tr_id(nid)),
-          def::DefErr => def::DefErr,
+          Def::Struct(did) => Def::Struct(did.tr(dcx)),
+          Def::Label(nid) => Def::Label(dcx.tr_id(nid)),
+          Def::Err => Def::Err,
         }
     }
 }
diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs
index ecbc8402330..802629e8f3e 100644
--- a/src/librustc_metadata/csearch.rs
+++ b/src/librustc_metadata/csearch.rs
@@ -18,7 +18,7 @@ use middle::cstore::{CrateStore, CrateSource, ChildItem, FoundAst};
 use middle::cstore::{NativeLibraryKind, LinkMeta, LinkagePreference};
 use middle::def;
 use middle::lang_items;
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, VariantKind};
 use middle::def_id::{DefId, DefIndex};
 
 use rustc::front::map as hir_map;
@@ -377,6 +377,17 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         local_path.into_iter().chain(path).collect()
     }
 
+    fn variant_kind(&self, def_id: DefId) -> Option<VariantKind> {
+        let cdata = self.get_crate_data(def_id.krate);
+        decoder::get_variant_kind(&cdata, def_id.index)
+    }
+
+    fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>
+    {
+        let cdata = self.get_crate_data(struct_def_id.krate);
+        decoder::get_struct_ctor_def_id(&cdata, struct_def_id.index)
+    }
+
     fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option<DefId>
     {
         let cdata = self.get_crate_data(did.krate);
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index def5897e92d..bca8cb3995a 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -28,12 +28,12 @@ use rustc_front::hir;
 
 use middle::cstore::{LOCAL_CRATE, FoundAst, InlinedItem, LinkagePreference};
 use middle::cstore::{DefLike, DlDef, DlField, DlImpl, tls};
-use middle::def;
+use middle::def::Def;
 use middle::def_id::{DefId, DefIndex};
 use middle::lang_items;
 use middle::subst;
 use middle::ty::{ImplContainer, TraitContainer};
-use middle::ty::{self, Ty, TypeFoldable};
+use middle::ty::{self, Ty, TypeFoldable, VariantKind};
 
 use rustc::mir;
 use rustc::mir::visit::MutVisitor;
@@ -89,27 +89,22 @@ pub fn load_xrefs(data: &[u8]) -> index::DenseIndex {
     index::DenseIndex::from_buf(index.data, index.start, index.end)
 }
 
-#[derive(Debug, PartialEq)]
+#[derive(Clone, Copy, Debug, PartialEq)]
 enum Family {
     ImmStatic,             // c
     MutStatic,             // b
     Fn,                    // f
-    CtorFn,                // o
     StaticMethod,          // F
     Method,                // h
     Type,                  // y
     Mod,                   // m
     ForeignMod,            // n
     Enum,                  // t
-    StructVariant,         // V
-    TupleVariant,          // v
-    UnitVariant,           // w
+    Variant(VariantKind),  // V, v, w
     Impl,                  // i
     DefaultImpl,           // d
     Trait,                 // I
-    Struct,                // S
-    TupleStruct,           // s
-    UnitStruct,            // u
+    Struct(VariantKind),   // S, s, u
     PublicField,           // g
     InheritedField,        // N
     Constant,              // C
@@ -122,22 +117,21 @@ fn item_family(item: rbml::Doc) -> Family {
       'c' => ImmStatic,
       'b' => MutStatic,
       'f' => Fn,
-      'o' => CtorFn,
       'F' => StaticMethod,
       'h' => Method,
       'y' => Type,
       'm' => Mod,
       'n' => ForeignMod,
       't' => Enum,
-      'V' => StructVariant,
-      'v' => TupleVariant,
-      'w' => UnitVariant,
+      'V' => Variant(VariantKind::Struct),
+      'v' => Variant(VariantKind::Tuple),
+      'w' => Variant(VariantKind::Unit),
       'i' => Impl,
       'd' => DefaultImpl,
       'I' => Trait,
-      'S' => Struct,
-      's' => TupleStruct,
-      'u' => UnitStruct,
+      'S' => Struct(VariantKind::Struct),
+      's' => Struct(VariantKind::Tuple),
+      'u' => Struct(VariantKind::Unit),
       'g' => PublicField,
       'N' => InheritedField,
        c => panic!("unexpected family char: {}", c)
@@ -271,6 +265,18 @@ fn item_name(intr: &IdentInterner, item: rbml::Doc) -> ast::Name {
     }
 }
 
+fn family_to_variant_kind<'tcx>(family: Family) -> Option<ty::VariantKind> {
+    match family {
+        Struct(VariantKind::Struct) | Variant(VariantKind::Struct) =>
+            Some(ty::VariantKind::Struct),
+        Struct(VariantKind::Tuple) | Variant(VariantKind::Tuple) =>
+            Some(ty::VariantKind::Tuple),
+        Struct(VariantKind::Unit) | Variant(VariantKind::Unit) =>
+            Some(ty::VariantKind::Unit),
+        _ => None,
+    }
+}
+
 fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: DefId) -> DefLike {
     let fam = item_family(item);
     match fam {
@@ -278,42 +284,37 @@ fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: DefId) -> DefLike {
             // Check whether we have an associated const item.
             match item_sort(item) {
                 Some('C') | Some('c') => {
-                    DlDef(def::DefAssociatedConst(did))
+                    DlDef(Def::AssociatedConst(did))
                 }
                 _ => {
                     // Regular const item.
-                    DlDef(def::DefConst(did))
+                    DlDef(Def::Const(did))
                 }
             }
         }
-        ImmStatic => DlDef(def::DefStatic(did, false)),
-        MutStatic => DlDef(def::DefStatic(did, true)),
-        Struct | TupleStruct | UnitStruct => DlDef(def::DefStruct(did)),
-        Fn        => DlDef(def::DefFn(did, false)),
-        CtorFn    => DlDef(def::DefFn(did, true)),
+        ImmStatic => DlDef(Def::Static(did, false)),
+        MutStatic => DlDef(Def::Static(did, true)),
+        Struct(..) => DlDef(Def::Struct(did)),
+        Fn        => DlDef(Def::Fn(did)),
         Method | StaticMethod => {
-            DlDef(def::DefMethod(did))
+            DlDef(Def::Method(did))
         }
         Type => {
             if item_sort(item) == Some('t') {
                 let trait_did = item_require_parent_item(cdata, item);
-                DlDef(def::DefAssociatedTy(trait_did, did))
+                DlDef(Def::AssociatedTy(trait_did, did))
             } else {
-                DlDef(def::DefTy(did, false))
+                DlDef(Def::TyAlias(did))
             }
         }
-        Mod => DlDef(def::DefMod(did)),
-        ForeignMod => DlDef(def::DefForeignMod(did)),
-        StructVariant => {
+        Mod => DlDef(Def::Mod(did)),
+        ForeignMod => DlDef(Def::ForeignMod(did)),
+        Variant(..) => {
             let enum_did = item_require_parent_item(cdata, item);
-            DlDef(def::DefVariant(enum_did, did, true))
+            DlDef(Def::Variant(enum_did, did))
         }
-        TupleVariant | UnitVariant => {
-            let enum_did = item_require_parent_item(cdata, item);
-            DlDef(def::DefVariant(enum_did, did, false))
-        }
-        Trait => DlDef(def::DefTrait(did)),
-        Enum => DlDef(def::DefTy(did, true)),
+        Trait => DlDef(Def::Trait(did)),
+        Enum => DlDef(Def::Enum(did)),
         Impl | DefaultImpl => DlImpl(did),
         PublicField | InheritedField => DlField,
     }
@@ -371,11 +372,9 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
                          item_id: DefIndex,
                          tcx: &ty::ctxt<'tcx>) -> ty::AdtDefMaster<'tcx>
 {
-    fn family_to_variant_kind<'tcx>(family: Family, tcx: &ty::ctxt<'tcx>) -> ty::VariantKind {
-        match family {
-            Struct | StructVariant => ty::VariantKind::Struct,
-            TupleStruct | TupleVariant => ty::VariantKind::Tuple,
-            UnitStruct | UnitVariant => ty::VariantKind::Unit,
+    fn expect_variant_kind<'tcx>(family: Family, tcx: &ty::ctxt<'tcx>) -> ty::VariantKind {
+        match family_to_variant_kind(family) {
+            Some(kind) => kind,
             _ => tcx.sess.bug(&format!("unexpected family: {:?}", family)),
         }
     }
@@ -399,7 +398,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
                 name: item_name(intr, item),
                 fields: get_variant_fields(intr, cdata, item, tcx),
                 disr_val: disr,
-                kind: family_to_variant_kind(item_family(item), tcx),
+                kind: expect_variant_kind(item_family(item), tcx),
             }
         }).collect()
     }
@@ -433,7 +432,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
             name: item_name(intr, doc),
             fields: get_variant_fields(intr, cdata, doc, tcx),
             disr_val: 0,
-            kind: family_to_variant_kind(item_family(doc), tcx),
+            kind: expect_variant_kind(item_family(doc), tcx),
         }
     }
 
@@ -444,7 +443,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
             (ty::AdtKind::Enum,
              get_enum_variants(intr, cdata, doc, tcx))
         }
-        Struct | TupleStruct | UnitStruct => {
+        Struct(..) => {
             let ctor_did =
                 reader::maybe_get_doc(doc, tag_items_data_item_struct_ctor).
                 map_or(did, |ctor_doc| translated_def_id(cdata, ctor_doc));
@@ -1086,6 +1085,19 @@ pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
     }).collect()
 }
 
+pub fn get_variant_kind(cdata: Cmd, node_id: DefIndex) -> Option<VariantKind>
+{
+    let item = cdata.lookup_item(node_id);
+    family_to_variant_kind(item_family(item))
+}
+
+pub fn get_struct_ctor_def_id(cdata: Cmd, node_id: DefIndex) -> Option<DefId>
+{
+    let item = cdata.lookup_item(node_id);
+    reader::maybe_get_doc(item, tag_items_data_item_struct_ctor).
+        map(|ctor_doc| translated_def_id(cdata, ctor_doc))
+}
+
 /// If node_id is the constructor of a tuple struct, retrieve the NodeId of
 /// the actual type definition, otherwise, return None
 pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index ec70a610e0b..45cbb22e6c9 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -508,15 +508,20 @@ fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
 fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                          rbml_w: &mut Encoder,
                                          name: Name,
-                                         ctor_id: NodeId,
+                                         struct_def: &hir::VariantData,
                                          index: &mut CrateIndex<'tcx>,
                                          struct_id: NodeId) {
+    let ctor_id = struct_def.id();
     let ctor_def_id = ecx.tcx.map.local_def_id(ctor_id);
 
     index.record(ctor_def_id, rbml_w);
     rbml_w.start_tag(tag_items_data_item);
     encode_def_id_and_key(ecx, rbml_w, ctor_def_id);
-    encode_family(rbml_w, 'o');
+    encode_family(rbml_w, match *struct_def {
+        hir::VariantData::Struct(..) => 'S',
+        hir::VariantData::Tuple(..) => 's',
+        hir::VariantData::Unit(..) => 'u',
+    });
     encode_bounds_and_type_for_item(rbml_w, ecx, index, ctor_id);
     encode_name(rbml_w, name);
     ecx.tcx.map.with_path(ctor_id, |path| encode_path(rbml_w, path));
@@ -1084,7 +1089,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
 
         // If this is a tuple-like struct, encode the type of the constructor.
         if !struct_def.is_struct() {
-            encode_info_for_struct_ctor(ecx, rbml_w, item.name, struct_def.id(), index, item.id);
+            encode_info_for_struct_ctor(ecx, rbml_w, item.name, struct_def, index, item.id);
         }
       }
       hir::ItemDefaultImpl(unsafety, _) => {
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 8090fca66bb..57a43c3a180 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -14,7 +14,7 @@ use hair::cx::Cx;
 use hair::cx::block;
 use hair::cx::to_ref::ToRef;
 use rustc::front::map;
-use rustc::middle::def;
+use rustc::middle::def::Def;
 use rustc::middle::region::CodeExtent;
 use rustc::middle::pat_util;
 use rustc::middle::ty::{self, VariantDef, Ty};
@@ -67,10 +67,10 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
                         // Tuple-like ADTs are represented as ExprCall. We convert them here.
                         expr_ty.ty_adt_def().and_then(|adt_def|{
                             match cx.tcx.def_map.borrow()[&fun.id].full_def() {
-                                def::DefVariant(_, variant_id, false) => {
+                                Def::Variant(_, variant_id) => {
                                     Some((adt_def, adt_def.variant_index_with_id(variant_id)))
                                 },
-                                def::DefStruct(_) => {
+                                Def::Struct(..) => {
                                     Some((adt_def, 0))
                                 },
                                 _ => None
@@ -231,7 +231,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
                     }
                     ty::TyEnum(adt, substs) => {
                         match cx.tcx.def_map.borrow()[&self.id].full_def() {
-                            def::DefVariant(enum_id, variant_id, _) => {
+                            Def::Variant(enum_id, variant_id) => {
                                 debug_assert!(adt.did == enum_id);
                                 let index = adt.variant_index_with_id(variant_id);
                                 let field_refs = field_refs(&adt.variants[index], fields);
@@ -573,9 +573,9 @@ fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr)
     let def = cx.tcx.def_map.borrow()[&expr.id].full_def();
     let (def_id, kind) = match def {
         // A regular function.
-        def::DefFn(def_id, _) => (def_id, ItemKind::Function),
-        def::DefMethod(def_id) => (def_id, ItemKind::Method),
-        def::DefStruct(def_id) => match cx.tcx.node_id_to_type(expr.id).sty {
+        Def::Fn(def_id) => (def_id, ItemKind::Function),
+        Def::Method(def_id) => (def_id, ItemKind::Method),
+        Def::Struct(def_id) => match cx.tcx.node_id_to_type(expr.id).sty {
             // A tuple-struct constructor. Should only be reached if not called in the same
             // expression.
             ty::TyBareFn(..) => (def_id, ItemKind::Function),
@@ -590,7 +590,7 @@ fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr)
             },
             ref sty => panic!("unexpected sty: {:?}", sty)
         },
-        def::DefVariant(enum_id, variant_id, false) => match cx.tcx.node_id_to_type(expr.id).sty {
+        Def::Variant(enum_id, variant_id) => match cx.tcx.node_id_to_type(expr.id).sty {
             // A variant constructor. Should only be reached if not called in the same
             // expression.
             ty::TyBareFn(..) => (variant_id, ItemKind::Function),
@@ -608,8 +608,8 @@ fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr)
             },
             ref sty => panic!("unexpected sty: {:?}", sty)
         },
-        def::DefConst(def_id) |
-        def::DefAssociatedConst(def_id) => {
+        Def::Const(def_id) |
+        Def::AssociatedConst(def_id) => {
             if let Some(v) = cx.try_const_eval_literal(expr) {
                 return ExprKind::Literal { literal: v };
             } else {
@@ -617,12 +617,12 @@ fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr)
             }
         }
 
-        def::DefStatic(node_id, _) => return ExprKind::StaticRef {
+        Def::Static(node_id, _) => return ExprKind::StaticRef {
             id: node_id,
         },
 
-        def @ def::DefLocal(..) |
-        def @ def::DefUpvar(..) => return convert_var(cx, expr, def),
+        def @ Def::Local(..) |
+        def @ Def::Upvar(..) => return convert_var(cx, expr, def),
 
         def =>
             cx.tcx.sess.span_bug(
@@ -636,18 +636,18 @@ fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr)
 
 fn convert_var<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>,
                              expr: &'tcx hir::Expr,
-                             def: def::Def)
+                             def: Def)
                              -> ExprKind<'tcx> {
     let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id);
 
     match def {
-        def::DefLocal(_, node_id) => {
+        Def::Local(_, node_id) => {
             ExprKind::VarRef {
                 id: node_id,
             }
         }
 
-        def::DefUpvar(_, id_var, index, closure_expr_id) => {
+        Def::Upvar(_, id_var, index, closure_expr_id) => {
             debug!("convert_var(upvar({:?}, {:?}, {:?}))", id_var, index, closure_expr_id);
             let var_ty = cx.tcx.node_id_to_type(id_var);
 
@@ -922,7 +922,7 @@ fn capture_freevar<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>,
 
 fn loop_label<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr) -> CodeExtent {
     match cx.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
-        Some(def::DefLabel(loop_id)) => cx.tcx.region_maps.node_extent(loop_id),
+        Some(Def::Label(loop_id)) => cx.tcx.region_maps.node_extent(loop_id),
         d => {
             cx.tcx.sess.span_bug(expr.span, &format!("loop scope resolved to {:?}", d));
         }
diff --git a/src/librustc_mir/hair/cx/pattern.rs b/src/librustc_mir/hair/cx/pattern.rs
index dc377ac731a..e1a533ce42c 100644
--- a/src/librustc_mir/hair/cx/pattern.rs
+++ b/src/librustc_mir/hair/cx/pattern.rs
@@ -12,7 +12,7 @@ use hair::*;
 use hair::cx::Cx;
 use rustc_data_structures::fnv::FnvHashMap;
 use rustc::middle::const_eval;
-use rustc::middle::def;
+use rustc::middle::def::Def;
 use rustc::middle::pat_util::{pat_is_resolved_const, pat_is_binding};
 use rustc::middle::ty::{self, Ty};
 use rustc::mir::repr::*;
@@ -84,7 +84,7 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
             {
                 let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
                 match def {
-                    def::DefConst(def_id) | def::DefAssociatedConst(def_id) =>
+                    Def::Const(def_id) | Def::AssociatedConst(def_id) =>
                         match const_eval::lookup_const_by_id(self.cx.tcx, def_id,
                                                              Some(pat.id), None) {
                             Some(const_expr) => {
@@ -290,7 +290,7 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
                        -> PatternKind<'tcx> {
         let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
         match def {
-            def::DefVariant(enum_id, variant_id, _) => {
+            Def::Variant(enum_id, variant_id) => {
                 let adt_def = self.cx.tcx.lookup_adt_def(enum_id);
                 if adt_def.variants.len() > 1 {
                     PatternKind::Variant {
@@ -303,9 +303,7 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
                 }
             }
 
-            // NB: resolving to DefStruct means the struct *constructor*,
-            // not the struct as a type.
-            def::DefStruct(..) | def::DefTy(..) => {
+            Def::Struct(..) | Def::TyAlias(..) => {
                 PatternKind::Leaf { subpatterns: subpatterns }
             }
 
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index d3da93a3e08..cfd0540cc60 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -37,7 +37,7 @@ use rustc_front::intravisit::{self, Visitor};
 
 use rustc::dep_graph::DepNode;
 use rustc::lint;
-use rustc::middle::def;
+use rustc::middle::def::{self, Def};
 use rustc::middle::def_id::DefId;
 use rustc::middle::privacy::{AccessLevel, AccessLevels};
 use rustc::middle::privacy::ImportUse::*;
@@ -172,7 +172,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
     fn ty_level(&self, ty: &hir::Ty) -> Option<AccessLevel> {
         if let hir::TyPath(..) = ty.node {
             match self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def() {
-                def::DefPrimTy(..) | def::DefSelfTy(..) | def::DefTyParam(..) => {
+                Def::PrimTy(..) | Def::SelfTy(..) | Def::TyParam(..) => {
                     Some(AccessLevel::Public)
                 }
                 def => {
@@ -294,7 +294,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
             hir::ItemTy(ref ty, _) if item_level.is_some() => {
                 if let hir::TyPath(..) = ty.node {
                     match self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def() {
-                        def::DefPrimTy(..) | def::DefSelfTy(..) | def::DefTyParam(..) => {},
+                        Def::PrimTy(..) | Def::SelfTy(..) | Def::TyParam(..) => {},
                         def => {
                             if let Some(node_id) = self.tcx.map.as_local_node_id(def.def_id()) {
                                 self.update(node_id, Some(AccessLevel::Reachable));
@@ -806,17 +806,17 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
         // be accurate and we can get slightly wonky error messages (but type
         // checking is always correct).
         match path_res.full_def() {
-            def::DefFn(..) => ck("function"),
-            def::DefStatic(..) => ck("static"),
-            def::DefConst(..) => ck("const"),
-            def::DefAssociatedConst(..) => ck("associated const"),
-            def::DefVariant(..) => ck("variant"),
-            def::DefTy(_, false) => ck("type"),
-            def::DefTy(_, true) => ck("enum"),
-            def::DefTrait(..) => ck("trait"),
-            def::DefStruct(..) => ck("struct"),
-            def::DefMethod(..) => ck("method"),
-            def::DefMod(..) => ck("module"),
+            Def::Fn(..) => ck("function"),
+            Def::Static(..) => ck("static"),
+            Def::Const(..) => ck("const"),
+            Def::AssociatedConst(..) => ck("associated const"),
+            Def::Variant(..) => ck("variant"),
+            Def::TyAlias(..) => ck("type"),
+            Def::Enum(..) => ck("enum"),
+            Def::Trait(..) => ck("trait"),
+            Def::Struct(..) => ck("struct"),
+            Def::Method(..) => ck("method"),
+            Def::Mod(..) => ck("module"),
             _ => {}
         }
     }
@@ -887,7 +887,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
             }
             hir::ExprPath(..) => {
 
-                if let def::DefStruct(_) = self.tcx.resolve_expr(expr) {
+                if let Def::Struct(..) = self.tcx.resolve_expr(expr) {
                     let expr_ty = self.tcx.expr_ty(expr);
                     let def = match expr_ty.sty {
                         ty::TyBareFn(_, &ty::BareFnTy { sig: ty::Binder(ty::FnSig {
@@ -1132,7 +1132,7 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
     fn path_is_private_type(&self, path_id: ast::NodeId) -> bool {
         let did = match self.tcx.def_map.borrow().get(&path_id).map(|d| d.full_def()) {
             // `int` etc. (None doesn't seem to occur.)
-            None | Some(def::DefPrimTy(..)) | Some(def::DefSelfTy(..)) => return false,
+            None | Some(Def::PrimTy(..)) | Some(Def::SelfTy(..)) => return false,
             Some(def) => def.def_id(),
         };
 
@@ -1503,10 +1503,10 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a,
         if let hir::TyPath(_, ref path) = ty.node {
             let def = self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def();
             match def {
-                def::DefPrimTy(..) | def::DefSelfTy(..) | def::DefTyParam(..) => {
+                Def::PrimTy(..) | Def::SelfTy(..) | Def::TyParam(..) => {
                     // Public
                 }
-                def::DefAssociatedTy(..) if self.is_quiet => {
+                Def::AssociatedTy(..) if self.is_quiet => {
                     // Conservatively approximate the whole type alias as public without
                     // recursing into its components when determining impl publicity.
                     // For example, `impl <Type as Trait>::Alias {...}` may be a public impl
@@ -1515,8 +1515,8 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a,
                     // free type aliases, but this isn't done yet.
                     return
                 }
-                def::DefStruct(def_id) | def::DefTy(def_id, _) |
-                def::DefTrait(def_id) | def::DefAssociatedTy(def_id, _) => {
+                Def::Struct(def_id) | Def::Enum(def_id) | Def::TyAlias(def_id) |
+                Def::Trait(def_id) | Def::AssociatedTy(def_id, _) => {
                     // Non-local means public (private items can't leave their crate, modulo bugs)
                     if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) {
                         let item = self.tcx.map.expect_item(node_id);
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 2e713a2f50e..5fb33b1ed17 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -31,6 +31,7 @@ use self::DuplicateCheckingMode::*;
 use rustc::middle::cstore::{CrateStore, ChildItem, DlDef, DlField, DlImpl};
 use rustc::middle::def::*;
 use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
+use rustc::middle::ty::VariantKind;
 
 use syntax::ast::{Name, NodeId};
 use syntax::attr::AttrMetaMethods;
@@ -315,7 +316,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                     };
                     self.external_exports.insert(def_id);
                     let parent_link = ModuleParentLink(parent, name);
-                    let def = DefMod(def_id);
+                    let def = Def::Mod(def_id);
                     let external_module = self.new_module(parent_link, Some(def), false, true);
 
                     debug!("(build reduced graph for item) found extern `{}`",
@@ -333,7 +334,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 let name_bindings = self.add_child(name, parent, ForbidDuplicateTypes, sp);
 
                 let parent_link = ModuleParentLink(parent, name);
-                let def = DefMod(self.ast_map.local_def_id(item.id));
+                let def = Def::Mod(self.ast_map.local_def_id(item.id));
                 let module = self.new_module(parent_link, Some(def), false, is_public);
                 name_bindings.define_module(module.clone(), sp);
                 module
@@ -346,20 +347,20 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 let name_bindings = self.add_child(name, parent, ForbidDuplicateValues, sp);
                 let mutbl = m == hir::MutMutable;
 
-                name_bindings.define_value(DefStatic(self.ast_map.local_def_id(item.id), mutbl),
+                name_bindings.define_value(Def::Static(self.ast_map.local_def_id(item.id), mutbl),
                                            sp,
                                            modifiers);
                 parent
             }
             ItemConst(_, _) => {
                 self.add_child(name, parent, ForbidDuplicateValues, sp)
-                    .define_value(DefConst(self.ast_map.local_def_id(item.id)), sp, modifiers);
+                    .define_value(Def::Const(self.ast_map.local_def_id(item.id)), sp, modifiers);
                 parent
             }
             ItemFn(_, _, _, _, _, _) => {
                 let name_bindings = self.add_child(name, parent, ForbidDuplicateValues, sp);
 
-                let def = DefFn(self.ast_map.local_def_id(item.id), false);
+                let def = Def::Fn(self.ast_map.local_def_id(item.id));
                 name_bindings.define_value(def, sp, modifiers);
                 parent
             }
@@ -372,7 +373,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                                    sp);
 
                 let parent_link = ModuleParentLink(parent, name);
-                let def = DefTy(self.ast_map.local_def_id(item.id), false);
+                let def = Def::TyAlias(self.ast_map.local_def_id(item.id));
                 let module = self.new_module(parent_link, Some(def), false, is_public);
                 name_bindings.define_module(module, sp);
                 parent
@@ -385,7 +386,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                                    sp);
 
                 let parent_link = ModuleParentLink(parent, name);
-                let def = DefTy(self.ast_map.local_def_id(item.id), true);
+                let def = Def::Enum(self.ast_map.local_def_id(item.id));
                 let module = self.new_module(parent_link, Some(def), false, is_public);
                 name_bindings.define_module(module.clone(), sp);
 
@@ -414,14 +415,14 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 let name_bindings = self.add_child(name, parent, forbid, sp);
 
                 // Define a name in the type namespace.
-                name_bindings.define_type(DefTy(self.ast_map.local_def_id(item.id), false),
+                name_bindings.define_type(Def::Struct(self.ast_map.local_def_id(item.id)),
                                           sp,
                                           modifiers);
 
                 // If this is a newtype or unit-like struct, define a name
                 // in the value namespace as well
                 if let Some(cid) = ctor_id {
-                    name_bindings.define_value(DefStruct(self.ast_map.local_def_id(cid)),
+                    name_bindings.define_value(Def::Struct(self.ast_map.local_def_id(cid)),
                                                sp,
                                                modifiers);
                 }
@@ -455,7 +456,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
                 // Add all the items within to a new module.
                 let parent_link = ModuleParentLink(parent, name);
-                let def = DefTrait(def_id);
+                let def = Def::Trait(def_id);
                 let module_parent = self.new_module(parent_link, Some(def), false, is_public);
                 name_bindings.define_module(module_parent.clone(), sp);
 
@@ -468,17 +469,18 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
                     match trait_item.node {
                         hir::ConstTraitItem(..) => {
-                            let def = DefAssociatedConst(self.ast_map.local_def_id(trait_item.id));
+                            let def = Def::AssociatedConst(self.ast_map.
+                                                                local_def_id(trait_item.id));
                             // NB: not DefModifiers::IMPORTABLE
                             name_bindings.define_value(def, trait_item.span, DefModifiers::PUBLIC);
                         }
                         hir::MethodTraitItem(..) => {
-                            let def = DefMethod(self.ast_map.local_def_id(trait_item.id));
+                            let def = Def::Method(self.ast_map.local_def_id(trait_item.id));
                             // NB: not DefModifiers::IMPORTABLE
                             name_bindings.define_value(def, trait_item.span, DefModifiers::PUBLIC);
                         }
                         hir::TypeTraitItem(..) => {
-                            let def = DefAssociatedTy(self.ast_map.local_def_id(item.id),
+                            let def = Def::AssociatedTy(self.ast_map.local_def_id(item.id),
                                                       self.ast_map.local_def_id(trait_item.id));
                             // NB: not DefModifiers::IMPORTABLE
                             name_bindings.define_type(def, trait_item.span, DefModifiers::PUBLIC);
@@ -502,26 +504,19 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                        parent: Module<'b>,
                                        variant_modifiers: DefModifiers) {
         let name = variant.node.name;
-        let is_exported = if variant.node.data.is_struct() {
+        if variant.node.data.is_struct() {
             // Not adding fields for variants as they are not accessed with a self receiver
             let variant_def_id = self.ast_map.local_def_id(variant.node.data.id());
             self.structs.insert(variant_def_id, Vec::new());
-            true
-        } else {
-            false
-        };
+        }
 
         let child = self.add_child(name, parent, ForbidDuplicateTypesAndValues, variant.span);
         // variants are always treated as importable to allow them to be glob
         // used
-        child.define_value(DefVariant(item_id,
-                                      self.ast_map.local_def_id(variant.node.data.id()),
-                                      is_exported),
+        child.define_value(Def::Variant(item_id, self.ast_map.local_def_id(variant.node.data.id())),
                            variant.span,
                            DefModifiers::PUBLIC | DefModifiers::IMPORTABLE | variant_modifiers);
-        child.define_type(DefVariant(item_id,
-                                     self.ast_map.local_def_id(variant.node.data.id()),
-                                     is_exported),
+        child.define_type(Def::Variant(item_id, self.ast_map.local_def_id(variant.node.data.id())),
                           variant.span,
                           DefModifiers::PUBLIC | DefModifiers::IMPORTABLE | variant_modifiers);
     }
@@ -541,10 +536,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
         let def = match foreign_item.node {
             ForeignItemFn(..) => {
-                DefFn(self.ast_map.local_def_id(foreign_item.id), false)
+                Def::Fn(self.ast_map.local_def_id(foreign_item.id))
             }
             ForeignItemStatic(_, m) => {
-                DefStatic(self.ast_map.local_def_id(foreign_item.id), m)
+                Def::Static(self.ast_map.local_def_id(foreign_item.id), m)
             }
         };
         name_bindings.define_value(def, foreign_item.span, modifiers);
@@ -591,12 +586,18 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
         if is_exported {
             self.external_exports.insert(def.def_id());
         }
+        let is_struct_ctor = if let Def::Struct(def_id) = def {
+            self.session.cstore.tuple_struct_definition_if_ctor(def_id).is_some()
+        } else {
+            false
+        };
 
         match def {
-            DefMod(_) |
-            DefForeignMod(_) |
-            DefStruct(_) |
-            DefTy(..) => {
+            Def::Mod(_) |
+            Def::ForeignMod(_) |
+            Def::Struct(..) |
+            Def::Enum(..) |
+            Def::TyAlias(..) if !is_struct_ctor => {
                 if let Some(module_def) = child_name_bindings.type_ns.module() {
                     debug!("(building reduced graph for external crate) already created module");
                     module_def.def.set(Some(def));
@@ -613,14 +614,14 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
         }
 
         match def {
-            DefMod(_) | DefForeignMod(_) => {}
-            DefVariant(_, variant_id, is_struct) => {
+            Def::Mod(_) | Def::ForeignMod(_) => {}
+            Def::Variant(_, variant_id) => {
                 debug!("(building reduced graph for external crate) building variant {}",
                        final_ident);
                 // variants are always treated as importable to allow them to be
                 // glob used
                 let modifiers = DefModifiers::PUBLIC | DefModifiers::IMPORTABLE;
-                if is_struct {
+                if self.session.cstore.variant_kind(variant_id) == Some(VariantKind::Struct) {
                     child_name_bindings.define_type(def, DUMMY_SP, modifiers);
                     // Not adding fields for variants as they are not accessed with a self receiver
                     self.structs.insert(variant_id, Vec::new());
@@ -628,16 +629,11 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                     child_name_bindings.define_value(def, DUMMY_SP, modifiers);
                 }
             }
-            DefFn(ctor_id, true) => {
-                child_name_bindings.define_value(
-                self.session.cstore.tuple_struct_definition_if_ctor(ctor_id)
-                    .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers);
-            }
-            DefFn(..) |
-            DefStatic(..) |
-            DefConst(..) |
-            DefAssociatedConst(..) |
-            DefMethod(..) => {
+            Def::Fn(..) |
+            Def::Static(..) |
+            Def::Const(..) |
+            Def::AssociatedConst(..) |
+            Def::Method(..) => {
                 debug!("(building reduced graph for external crate) building value (fn/static) {}",
                        final_ident);
                 // impl methods have already been defined with the correct importability
@@ -652,7 +648,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 }
                 child_name_bindings.define_value(def, DUMMY_SP, modifiers);
             }
-            DefTrait(def_id) => {
+            Def::Trait(def_id) => {
                 debug!("(building reduced graph for external crate) building type {}",
                        final_ident);
 
@@ -680,7 +676,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 let module = self.new_module(parent_link, Some(def), true, is_public);
                 child_name_bindings.define_module(module, DUMMY_SP);
             }
-            DefTy(..) | DefAssociatedTy(..) => {
+            Def::Enum(..) | Def::TyAlias(..) | Def::AssociatedTy(..) => {
                 debug!("(building reduced graph for external crate) building type {}",
                        final_ident);
 
@@ -689,33 +685,38 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                     _ => modifiers & !DefModifiers::IMPORTABLE,
                 };
 
-                if let DefTy(..) = def {
+                if let Def::Enum(..) = def {
+                    child_name_bindings.type_ns.set_modifiers(modifiers);
+                } else if let Def::TyAlias(..) = def {
                     child_name_bindings.type_ns.set_modifiers(modifiers);
                 } else {
                     child_name_bindings.define_type(def, DUMMY_SP, modifiers);
                 }
             }
-            DefStruct(def_id) => {
+            Def::Struct(..) if is_struct_ctor => {
+                // Do nothing
+            }
+            Def::Struct(def_id) => {
                 debug!("(building reduced graph for external crate) building type and value for \
                         {}",
                        final_ident);
-                child_name_bindings.define_type(def, DUMMY_SP, modifiers);
-                let fields = self.session.cstore.struct_field_names(def_id);
 
-                if fields.is_empty() {
-                    child_name_bindings.define_value(def, DUMMY_SP, modifiers);
+                child_name_bindings.define_type(def, DUMMY_SP, modifiers);
+                if let Some(ctor_def_id) = self.session.cstore.struct_ctor_def_id(def_id) {
+                    child_name_bindings.define_value(Def::Struct(ctor_def_id), DUMMY_SP, modifiers);
                 }
 
                 // Record the def ID and fields of this struct.
+                let fields = self.session.cstore.struct_field_names(def_id);
                 self.structs.insert(def_id, fields);
             }
-            DefLocal(..) |
-            DefPrimTy(..) |
-            DefTyParam(..) |
-            DefUpvar(..) |
-            DefLabel(..) |
-            DefSelfTy(..) |
-            DefErr => {
+            Def::Local(..) |
+            Def::PrimTy(..) |
+            Def::TyParam(..) |
+            Def::Upvar(..) |
+            Def::Label(..) |
+            Def::SelfTy(..) |
+            Def::Err => {
                 panic!("didn't expect `{:?}`", def);
             }
         }
@@ -729,7 +730,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
             DlDef(def) => {
                 // Add the new child item, if necessary.
                 match def {
-                    DefForeignMod(def_id) => {
+                    Def::ForeignMod(def_id) => {
                         // Foreign modules have no names. Recur and populate
                         // eagerly.
                         for child in self.session.cstore.item_children(def_id) {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 8464d3ef298..444c43163e3 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -737,7 +737,7 @@ enum TypeParameters<'a> {
 }
 
 // The rib kind controls the translation of local
-// definitions (`DefLocal`) to upvars (`DefUpvar`).
+// definitions (`Def::Local`) to upvars (`Def::Upvar`).
 #[derive(Copy, Clone, Debug)]
 enum RibKind {
     // No translation needs to be applied.
@@ -913,14 +913,14 @@ impl<'a> ModuleS<'a> {
 
     fn is_normal(&self) -> bool {
         match self.def.get() {
-            Some(DefMod(_)) | Some(DefForeignMod(_)) => true,
+            Some(Def::Mod(_)) | Some(Def::ForeignMod(_)) => true,
             _ => false,
         }
     }
 
     fn is_trait(&self) -> bool {
         match self.def.get() {
-            Some(DefTrait(_)) => true,
+            Some(Def::Trait(_)) => true,
             _ => false,
         }
     }
@@ -1243,7 +1243,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
            arenas: &'a ResolverArenas<'a>)
            -> Resolver<'a, 'tcx> {
         let root_def_id = ast_map.local_def_id(CRATE_NODE_ID);
-        let graph_root = ModuleS::new(NoParentLink, Some(DefMod(root_def_id)), false, true);
+        let graph_root = ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false, true);
         let graph_root = arenas.modules.alloc(graph_root);
 
         Resolver {
@@ -2020,7 +2020,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                                                ItemRibKind),
                                              |this| {
                     let local_def_id = this.ast_map.local_def_id(item.id);
-                    this.with_self_rib(DefSelfTy(Some(local_def_id), None), |this| {
+                    this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
                         this.visit_generics(generics);
                         walk_list!(this, visit_ty_param_bound, bounds);
 
@@ -2076,7 +2076,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 // check for imports shadowing primitive types
                 let check_rename = |this: &Self, id, name| {
                     match this.def_map.borrow().get(&id).map(|d| d.full_def()) {
-                        Some(DefTy(..)) | Some(DefStruct(..)) | Some(DefTrait(..)) | None => {
+                        Some(Def::Enum(..)) | Some(Def::TyAlias(..)) | Some(Def::Struct(..)) |
+                        Some(Def::Trait(..)) | None => {
                             this.check_if_primitive_type_name(name, item.span);
                         }
                         _ => {}
@@ -2142,7 +2143,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     // plain insert (no renaming)
                     function_type_rib.bindings
                                      .insert(name,
-                                             DlDef(DefTyParam(space,
+                                             DlDef(Def::TyParam(space,
                                                               index as u32,
                                                               self.ast_map
                                                                   .local_def_id(type_parameter.id),
@@ -2225,7 +2226,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                path_depth: usize)
                                -> Result<PathResolution, ()> {
         if let Some(path_res) = self.resolve_path(id, trait_path, path_depth, TypeNS, true) {
-            if let DefTrait(_) = path_res.base_def {
+            if let Def::Trait(_) = path_res.base_def {
                 debug!("(resolving trait) found trait def: {:?}", path_res);
                 Ok(path_res)
             } else {
@@ -2236,7 +2237,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                                                                       path_depth)));
 
                 // If it's a typedef, give a note
-                if let DefTy(..) = path_res.base_def {
+                if let Def::TyAlias(..) = path_res.base_def {
                     err.span_note(trait_path.span,
                                   "`type` aliases cannot be used for traits");
                 }
@@ -2262,7 +2263,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 &hir::WherePredicate::RegionPredicate(_) => {}
                 &hir::WherePredicate::EqPredicate(ref eq_pred) => {
                     let path_res = self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS, true);
-                    if let Some(PathResolution { base_def: DefTyParam(..), .. }) = path_res {
+                    if let Some(PathResolution { base_def: Def::TyParam(..), .. }) = path_res {
                         self.record_def(eq_pred.id, path_res.unwrap());
                     } else {
                         resolve_error(self,
@@ -2344,7 +2345,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 // Resolve the self type.
                 this.visit_ty(self_type);
 
-                this.with_self_rib(DefSelfTy(trait_id, Some((item_id, self_type.id))), |this| {
+                this.with_self_rib(Def::SelfTy(trait_id, Some((item_id, self_type.id))), |this| {
                     this.with_current_self_type(self_type, |this| {
                         for impl_item in impl_items {
                             match impl_item.node {
@@ -2680,7 +2681,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             debug!("(resolving pattern) binding `{}`", renamed);
 
                             let def_id = self.ast_map.local_def_id(pattern.id);
-                            let def = DefLocal(def_id, pattern.id);
+                            let def = Def::Local(def_id, pattern.id);
 
                             // Record the definition so that later passes
                             // will be able to distinguish variants from
@@ -2751,10 +2752,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     };
                     if let Some(path_res) = resolution {
                         match path_res.base_def {
-                            DefVariant(..) | DefStruct(..) | DefConst(..) => {
+                            Def::Struct(..) if path_res.depth == 0 => {
                                 self.record_def(pattern.id, path_res);
                             }
-                            DefStatic(..) => {
+                            Def::Variant(..) | Def::Const(..) => {
+                                self.record_def(pattern.id, path_res);
+                            }
+                            Def::Static(..) => {
                                 resolve_error(&self,
                                               path.span,
                                               ResolutionError::StaticVariableReference);
@@ -2829,7 +2833,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         match path_res.base_def {
                             // All `<T as Trait>::CONST` should end up here, and
                             // have the trait already selected.
-                            DefAssociatedConst(..) => {
+                            Def::AssociatedConst(..) => {
                                 self.record_def(pattern.id, path_res);
                             }
                             _ => {
@@ -2906,13 +2910,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     // For the two success cases, this lookup can be
                     // considered as not having a private component because
                     // the lookup happened only within the current module.
-                    Some(def @ DefVariant(..)) | Some(def @ DefStruct(..)) => {
+                    Some(def @ Def::Variant(..)) | Some(def @ Def::Struct(..)) => {
                         return FoundStructOrEnumVariant(def, LastMod(AllPublic));
                     }
-                    Some(def @ DefConst(..)) | Some(def @ DefAssociatedConst(..)) => {
+                    Some(def @ Def::Const(..)) | Some(def @ Def::AssociatedConst(..)) => {
                         return FoundConst(def, LastMod(AllPublic), name);
                     }
-                    Some(DefStatic(..)) => {
+                    Some(Def::Static(..)) => {
                         resolve_error(self, span, ResolutionError::StaticVariableReference);
                         return BareIdentifierPatternUnresolved;
                     }
@@ -2972,7 +2976,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 resolution = this.resolve_path(id, path, depth, TypeNS, true);
             });
         }
-        if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
+        if let Some(Def::Mod(_)) = resolution.map(|r| r.base_def) {
             // A module is not a valid type or value.
             resolution = None;
         }
@@ -3038,7 +3042,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             if let Some(&prim_ty) = self.primitive_type_table
                                         .primitive_types
                                         .get(&identifier.unhygienic_name) {
-                return Some(LocalDef::from_def(DefPrimTy(prim_ty)));
+                return Some(LocalDef::from_def(Def::PrimTy(prim_ty)));
             }
         }
 
@@ -3062,10 +3066,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         };
         let mut def = local_def.def;
         match def {
-            DefUpvar(..) => {
+            Def::Upvar(..) => {
                 self.session.span_bug(span, &format!("unexpected {:?} in bindings", def))
             }
-            DefLocal(_, node_id) => {
+            Def::Local(_, node_id) => {
                 for rib in ribs {
                     match rib.kind {
                         NormalRibKind => {
@@ -3079,7 +3083,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                            .entry(function_id)
                                            .or_insert_with(|| NodeMap());
                             if let Some(&index) = seen.get(&node_id) {
-                                def = DefUpvar(node_def_id, node_id, index, function_id);
+                                def = Def::Upvar(node_def_id, node_id, index, function_id);
                                 continue;
                             }
                             let vec = self.freevars
@@ -3091,7 +3095,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 span: span,
                             });
 
-                            def = DefUpvar(node_def_id, node_id, depth, function_id);
+                            def = Def::Upvar(node_def_id, node_id, depth, function_id);
                             seen.insert(node_id, depth);
                         }
                         ItemRibKind | MethodRibKind => {
@@ -3113,7 +3117,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     }
                 }
             }
-            DefTyParam(..) | DefSelfTy(..) => {
+            Def::TyParam(..) | Def::SelfTy(..) => {
                 for rib in ribs {
                     match rib.kind {
                         NormalRibKind | MethodRibKind | ClosureRibKind(..) => {
@@ -3425,9 +3429,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         if allowed == Everything {
             // Look for a field with the same name in the current self_type.
             match self.def_map.borrow().get(&node_id).map(|d| d.full_def()) {
-                Some(DefTy(did, _)) |
-                Some(DefStruct(did)) |
-                Some(DefVariant(_, did, _)) => match self.structs.get(&did) {
+                Some(Def::Enum(did)) |
+                Some(Def::TyAlias(did)) |
+                Some(Def::Struct(did)) |
+                Some(Def::Variant(_, did)) => match self.structs.get(&did) {
                     None => {}
                     Some(fields) => {
                         if fields.iter().any(|&field_name| name == field_name) {
@@ -3444,7 +3449,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         // Look for a method in the current self type's impl module.
         if let Some(module) = get_module(self, path.span, &name_path) {
             if let Some(binding) = module.children.borrow().get(&name) {
-                if let Some(DefMethod(did)) = binding.value_ns.def() {
+                if let Some(Def::Method(did)) = binding.value_ns.def() {
                     if is_static_method(self, did) {
                         return StaticMethod(path_names_to_string(&path, 0));
                     }
@@ -3518,7 +3523,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 // scopes looking for it.
                 if let Some(path_res) = resolution {
                     // Check if struct variant
-                    if let DefVariant(_, _, true) = path_res.base_def {
+                    let is_struct_variant = if let Def::Variant(_, variant_id) = path_res.base_def {
+                        self.structs.contains_key(&variant_id)
+                    } else {
+                        false
+                    };
+                    if is_struct_variant {
+                        let _ = self.structs.contains_key(&path_res.base_def.def_id());
                         let path_name = path_names_to_string(path, 0);
 
                         let mut err = resolve_struct_error(self,
@@ -3561,7 +3572,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
                     self.record_def(expr.id, err_path_resolution());
                     match type_res.map(|r| r.base_def) {
-                        Some(DefTy(struct_id, _)) if self.structs.contains_key(&struct_id) => {
+                        Some(Def::Struct(..)) => {
                             let mut err = resolve_struct_error(self,
                                 expr.span,
                                 ResolutionError::StructVariantUsedAsFunction(&*path_name));
@@ -3673,7 +3684,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
             ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
                 self.with_label_rib(|this| {
-                    let def_like = DlDef(DefLabel(expr.id));
+                    let def_like = DlDef(Def::Label(expr.id));
 
                     {
                         let rib = this.label_ribs.last_mut().unwrap();
@@ -3692,7 +3703,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                       label.span,
                                       ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
                     }
-                    Some(DlDef(def @ DefLabel(_))) => {
+                    Some(DlDef(def @ Def::Label(_))) => {
                         // Since this def is a label, it is never read.
                         self.record_def(expr.id,
                                         PathResolution {
@@ -3768,7 +3779,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         None => continue,
                     };
                     let trait_def_id = match def {
-                        DefTrait(trait_def_id) => trait_def_id,
+                        Def::Trait(trait_def_id) => trait_def_id,
                         _ => continue,
                     };
                     if self.trait_item_map.contains_key(&(name, trait_def_id)) {
@@ -3784,7 +3795,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     Some(ref target) => target,
                 };
                 let did = match target.binding.def() {
-                    Some(DefTrait(trait_def_id)) => trait_def_id,
+                    Some(Def::Trait(trait_def_id)) => trait_def_id,
                     Some(..) | None => continue,
                 };
                 if self.trait_item_map.contains_key(&(name, did)) {
@@ -3939,7 +3950,7 @@ fn module_to_string<'a>(module: Module<'a>) -> String {
 
 fn err_path_resolution() -> PathResolution {
     PathResolution {
-        base_def: DefErr,
+        base_def: Def::Err,
         last_private: LastMod(AllPublic),
         depth: 0,
     }
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index abaf45cb170..7df71fadd89 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -852,7 +852,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
         if let Some(did) = target_module.def_id() {
             self.resolver.def_map.borrow_mut().insert(id,
                                                       PathResolution {
-                                                          base_def: DefMod(did),
+                                                          base_def: Def::Mod(did),
                                                           last_private: lp,
                                                           depth: 0,
                                                       });
diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs
index c34013a7bbb..b109353fac0 100644
--- a/src/librustc_trans/save/dump_csv.rs
+++ b/src/librustc_trans/save/dump_csv.rs
@@ -32,7 +32,7 @@ use super::{escape, generated_code, recorder, SaveContext, PathCollector, Data};
 
 use session::Session;
 
-use middle::def;
+use middle::def::Def;
 use middle::def_id::DefId;
 use middle::ty;
 
@@ -239,8 +239,8 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         }
         let def = self.tcx.def_map.borrow().get(&ref_id).unwrap().full_def();
         match def {
-            def::DefPrimTy(..) => None,
-            def::DefSelfTy(..) => None,
+            Def::PrimTy(..) => None,
+            Def::SelfTy(..) => None,
             _ => Some(def.def_id()),
         }
     }
@@ -254,27 +254,28 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         }
         let def = def_map.get(&ref_id).unwrap().full_def();
         match def {
-            def::DefMod(_) |
-            def::DefForeignMod(_) => Some(recorder::ModRef),
-            def::DefStruct(_) => Some(recorder::TypeRef),
-            def::DefTy(..) |
-            def::DefAssociatedTy(..) |
-            def::DefTrait(_) => Some(recorder::TypeRef),
-            def::DefStatic(_, _) |
-            def::DefConst(_) |
-            def::DefAssociatedConst(..) |
-            def::DefLocal(..) |
-            def::DefVariant(_, _, _) |
-            def::DefUpvar(..) => Some(recorder::VarRef),
-
-            def::DefFn(..) => Some(recorder::FnRef),
-
-            def::DefSelfTy(..) |
-            def::DefLabel(_) |
-            def::DefTyParam(..) |
-            def::DefMethod(..) |
-            def::DefPrimTy(_) |
-            def::DefErr => {
+            Def::Mod(_) |
+            Def::ForeignMod(_) => Some(recorder::ModRef),
+            Def::Struct(..) => Some(recorder::TypeRef),
+            Def::Enum(..) |
+            Def::TyAlias(..) |
+            Def::AssociatedTy(..) |
+            Def::Trait(_) => Some(recorder::TypeRef),
+            Def::Static(_, _) |
+            Def::Const(_) |
+            Def::AssociatedConst(..) |
+            Def::Local(..) |
+            Def::Variant(..) |
+            Def::Upvar(..) => Some(recorder::VarRef),
+
+            Def::Fn(..) => Some(recorder::FnRef),
+
+            Def::SelfTy(..) |
+            Def::Label(_) |
+            Def::TyParam(..) |
+            Def::Method(..) |
+            Def::PrimTy(_) |
+            Def::Err => {
                 self.sess.span_bug(span,
                                    &format!("lookup_def_kind for unexpected item: {:?}", def));
             }
@@ -679,7 +680,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         let def_map = self.tcx.def_map.borrow();
         let def = def_map.get(&id).unwrap().full_def();
         match def {
-            def::DefMethod(did) => {
+            Def::Method(did) => {
                 let ti = self.tcx.impl_or_trait_item(did);
                 if let ty::MethodTraitItem(m) = ti {
                     if m.explicit_self == ty::ExplicitSelfCategory::Static {
@@ -687,13 +688,13 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                     }
                 }
             }
-            def::DefLocal(..) |
-            def::DefStatic(_,_) |
-            def::DefConst(..) |
-            def::DefAssociatedConst(..) |
-            def::DefStruct(_) |
-            def::DefVariant(..) |
-            def::DefFn(..) => self.write_sub_paths_truncated(path, false),
+            Def::Local(..) |
+            Def::Static(_,_) |
+            Def::Const(..) |
+            Def::AssociatedConst(..) |
+            Def::Struct(..) |
+            Def::Variant(..) |
+            Def::Fn(..) => self.write_sub_paths_truncated(path, false),
             _ => {}
         }
     }
@@ -1163,7 +1164,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
             }
             let def = def_map.get(&id).unwrap().full_def();
             match def {
-                def::DefLocal(_, id) => {
+                Def::Local(_, id) => {
                     let value = if immut == ast::MutImmutable {
                         self.span.snippet(p.span).to_string()
                     } else {
@@ -1174,13 +1175,14 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                             "qualified path for local variable def in arm");
                     self.fmt.variable_str(p.span, Some(p.span), id, &path_to_string(p), &value, "")
                 }
-                def::DefVariant(..) | def::DefTy(..) | def::DefStruct(..) => {
+                Def::Variant(..) | Def::Enum(..) |
+                Def::TyAlias(..) | Def::Struct(..) => {
                     paths_to_process.push((id, p.clone(), Some(ref_kind)))
                 }
                 // FIXME(nrc) what are these doing here?
-                def::DefStatic(_, _) |
-                def::DefConst(..) |
-                def::DefAssociatedConst(..) => {}
+                Def::Static(_, _) |
+                Def::Const(..) |
+                Def::AssociatedConst(..) => {}
                 _ => error!("unexpected definition kind when processing collected paths: {:?}",
                             def),
             }
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index e1343c73acf..00554419e64 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use middle::ty;
-use middle::def;
+use middle::def::Def;
 use middle::def_id::DefId;
 
 use std::env;
@@ -533,12 +533,12 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
         let def = def_map.get(&id).unwrap().full_def();
         let sub_span = self.span_utils.span_for_last_ident(path.span);
         match def {
-            def::DefUpvar(..) |
-            def::DefLocal(..) |
-            def::DefStatic(..) |
-            def::DefConst(..) |
-            def::DefAssociatedConst(..) |
-            def::DefVariant(..) => {
+            Def::Upvar(..) |
+            Def::Local(..) |
+            Def::Static(..) |
+            Def::Const(..) |
+            Def::AssociatedConst(..) |
+            Def::Variant(..) => {
                 Some(Data::VariableRefData(VariableRefData {
                     name: self.span_utils.snippet(sub_span.unwrap()),
                     span: sub_span.unwrap(),
@@ -546,17 +546,18 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     ref_id: def.def_id(),
                 }))
             }
-            def::DefStruct(def_id) |
-            def::DefTy(def_id, _) |
-            def::DefTrait(def_id) |
-            def::DefTyParam(_, _, def_id, _) => {
+            Def::Struct(def_id) |
+            Def::Enum(def_id) |
+            Def::TyAlias(def_id) |
+            Def::Trait(def_id) |
+            Def::TyParam(_, _, def_id, _) => {
                 Some(Data::TypeRefData(TypeRefData {
                     span: sub_span.unwrap(),
                     ref_id: def_id,
                     scope: self.enclosing_scope(id),
                 }))
             }
-            def::DefMethod(decl_id) => {
+            Def::Method(decl_id) => {
                 let sub_span = self.span_utils.sub_span_for_meth_name(path.span);
                 let def_id = if decl_id.is_local() {
                     let ti = self.tcx.impl_or_trait_item(decl_id);
@@ -591,14 +592,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     decl_id: Some(decl_id),
                 }))
             }
-            def::DefFn(def_id, _) => {
+            Def::Fn(def_id) => {
                 Some(Data::FunctionCallData(FunctionCallData {
                     ref_id: def_id,
                     span: sub_span.unwrap(),
                     scope: self.enclosing_scope(id),
                 }))
             }
-            def::DefMod(def_id) => {
+            Def::Mod(def_id) => {
                 Some(Data::ModRefData(ModRefData {
                     ref_id: def_id,
                     span: sub_span.unwrap(),
@@ -651,7 +652,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
         }
         let def = self.tcx.def_map.borrow().get(&ref_id).unwrap().full_def();
         match def {
-            def::DefPrimTy(_) | def::DefSelfTy(..) => None,
+            Def::PrimTy(_) | Def::SelfTy(..) => None,
             _ => Some(def.def_id()),
         }
     }
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index 6c1a31738af..9a05135b76e 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -192,7 +192,7 @@ use llvm::{ValueRef, BasicBlockRef};
 use middle::check_match::StaticInliner;
 use middle::check_match;
 use middle::const_eval;
-use middle::def::{self, DefMap};
+use middle::def::{Def, DefMap};
 use middle::def_id::DefId;
 use middle::expr_use_visitor as euv;
 use middle::infer;
@@ -669,7 +669,7 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 // This is either an enum variant or a variable binding.
                 let opt_def = tcx.def_map.borrow().get(&cur.id).map(|d| d.full_def());
                 match opt_def {
-                    Some(def::DefVariant(enum_id, var_id, _)) => {
+                    Some(Def::Variant(enum_id, var_id)) => {
                         let variant = tcx.lookup_adt_def(enum_id).variant_with_id(var_id);
                         Variant(Disr::from(variant.disr_val),
                                 adt::represent_node(bcx, cur.id),
@@ -800,13 +800,13 @@ fn any_irrefutable_adt_pat(tcx: &ty::ctxt, m: &[Match], col: usize) -> bool {
             hir::PatTup(_) => true,
             hir::PatStruct(..) => {
                 match tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
-                    Some(def::DefVariant(..)) => false,
+                    Some(Def::Variant(..)) => false,
                     _ => true,
                 }
             }
             hir::PatEnum(..) | hir::PatIdent(_, _, None) => {
                 match tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
-                    Some(def::DefStruct(..)) => true,
+                    Some(Def::Struct(..)) => true,
                     _ => false
                 }
             }
@@ -1452,19 +1452,19 @@ pub fn trans_match<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 fn is_discr_reassigned(bcx: Block, discr: &hir::Expr, body: &hir::Expr) -> bool {
     let (vid, field) = match discr.node {
         hir::ExprPath(..) => match bcx.def(discr.id) {
-            def::DefLocal(_, vid) | def::DefUpvar(_, vid, _, _) => (vid, None),
+            Def::Local(_, vid) | Def::Upvar(_, vid, _, _) => (vid, None),
             _ => return false
         },
         hir::ExprField(ref base, field) => {
             let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) {
-                Some(def::DefLocal(_, vid)) | Some(def::DefUpvar(_, vid, _, _)) => vid,
+                Some(Def::Local(_, vid)) | Some(Def::Upvar(_, vid, _, _)) => vid,
                 _ => return false
             };
             (vid, Some(mc::NamedField(field.node)))
         },
         hir::ExprTupField(ref base, field) => {
             let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) {
-                Some(def::DefLocal(_, vid)) | Some(def::DefUpvar(_, vid, _, _)) => vid,
+                Some(Def::Local(_, vid)) | Some(Def::Upvar(_, vid, _, _)) => vid,
                 _ => return false
             };
             (vid, Some(mc::PositionalField(field.node)))
@@ -1851,7 +1851,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         hir::PatEnum(_, ref sub_pats) => {
             let opt_def = bcx.tcx().def_map.borrow().get(&pat.id).map(|d| d.full_def());
             match opt_def {
-                Some(def::DefVariant(enum_id, var_id, _)) => {
+                Some(Def::Variant(enum_id, var_id)) => {
                     let repr = adt::represent_node(bcx, pat.id);
                     let vinfo = ccx.tcx().lookup_adt_def(enum_id).variant_with_id(var_id);
                     let args = extract_variant_args(bcx,
@@ -1868,7 +1868,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                         }
                     }
                 }
-                Some(def::DefStruct(..)) => {
+                Some(Def::Struct(..)) => {
                     match *sub_pats {
                         None => {
                             // This is a unit-like struct. Nothing to do here.
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index c7ec1c09551..2651b3576fe 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -22,7 +22,7 @@ use arena::TypedArena;
 use back::link;
 use llvm::{self, ValueRef, get_params};
 use middle::cstore::LOCAL_CRATE;
-use middle::def;
+use middle::def::Def;
 use middle::def_id::DefId;
 use middle::infer;
 use middle::subst;
@@ -133,13 +133,13 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &hir::Expr)
     }
 
     fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                             def: def::Def,
+                             def: Def,
                              ref_expr: &hir::Expr)
                              -> Callee<'blk, 'tcx> {
         debug!("trans_def(def={:?}, ref_expr={:?})", def, ref_expr);
         let expr_ty = common::node_id_type(bcx, ref_expr.id);
         match def {
-            def::DefFn(did, _) if {
+            Def::Fn(did) if {
                 let maybe_def_id = inline::get_local_instance(bcx.ccx(), did);
                 let maybe_ast_node = maybe_def_id.and_then(|def_id| {
                     let node_id = bcx.tcx().map.as_local_node_id(def_id).unwrap();
@@ -156,7 +156,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &hir::Expr)
                     ty: expr_ty
                 }
             }
-            def::DefFn(did, _) if match expr_ty.sty {
+            Def::Fn(did) if match expr_ty.sty {
                 ty::TyBareFn(_, ref f) => f.abi == synabi::RustIntrinsic ||
                                           f.abi == synabi::PlatformIntrinsic,
                 _ => false
@@ -168,11 +168,11 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &hir::Expr)
                 let node_id = bcx.tcx().map.as_local_node_id(def_id).unwrap();
                 Callee { bcx: bcx, data: Intrinsic(node_id, substs), ty: expr_ty }
             }
-            def::DefFn(did, _) => {
+            Def::Fn(did) => {
                 fn_callee(bcx, trans_fn_ref(bcx.ccx(), did, ExprId(ref_expr.id),
                                             bcx.fcx.param_substs))
             }
-            def::DefMethod(meth_did) => {
+            Def::Method(meth_did) => {
                 let method_item = bcx.tcx().impl_or_trait_item(meth_did);
                 let fn_datum = match method_item.container() {
                     ty::ImplContainer(_) => {
@@ -190,7 +190,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &hir::Expr)
                 };
                 fn_callee(bcx, fn_datum)
             }
-            def::DefVariant(tid, vid, _) => {
+            Def::Variant(tid, vid) => {
                 let vinfo = bcx.tcx().lookup_adt_def(tid).variant_with_id(vid);
                 assert_eq!(vinfo.kind(), ty::VariantKind::Tuple);
 
@@ -200,24 +200,24 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &hir::Expr)
                     ty: expr_ty
                 }
             }
-            def::DefStruct(_) => {
+            Def::Struct(..) => {
                 Callee {
                     bcx: bcx,
                     data: NamedTupleConstructor(Disr(0)),
                     ty: expr_ty
                 }
             }
-            def::DefStatic(..) |
-            def::DefConst(..) |
-            def::DefAssociatedConst(..) |
-            def::DefLocal(..) |
-            def::DefUpvar(..) => {
+            Def::Static(..) |
+            Def::Const(..) |
+            Def::AssociatedConst(..) |
+            Def::Local(..) |
+            Def::Upvar(..) => {
                 datum_callee(bcx, ref_expr)
             }
-            def::DefMod(..) | def::DefForeignMod(..) | def::DefTrait(..) |
-            def::DefTy(..) | def::DefPrimTy(..) | def::DefAssociatedTy(..) |
-            def::DefLabel(..) | def::DefTyParam(..) |
-            def::DefSelfTy(..) | def::DefErr => {
+            Def::Mod(..) | Def::ForeignMod(..) | Def::Trait(..) |
+            Def::Enum(..) | Def::TyAlias(..) | Def::PrimTy(..) |
+            Def::AssociatedTy(..) | Def::Label(..) | Def::TyParam(..) |
+            Def::SelfTy(..) | Def::Err => {
                 bcx.tcx().sess.span_bug(
                     ref_expr.span,
                     &format!("cannot translate def {:?} \
diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index b73e5ff3e03..6c03916af6c 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -19,7 +19,7 @@ use llvm;
 use llvm::{ValueRef, BasicBlockRef, BuilderRef, ContextRef, TypeKind};
 use llvm::{True, False, Bool};
 use middle::cfg;
-use middle::def;
+use middle::def::Def;
 use middle::def_id::DefId;
 use middle::infer;
 use middle::lang_items::LangItem;
@@ -184,7 +184,7 @@ pub struct VariantInfo<'tcx> {
 impl<'tcx> VariantInfo<'tcx> {
     pub fn from_ty(tcx: &ty::ctxt<'tcx>,
                    ty: Ty<'tcx>,
-                   opt_def: Option<def::Def>)
+                   opt_def: Option<Def>)
                    -> Self
     {
         match ty.sty {
@@ -627,7 +627,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
         self.tcx().map.node_to_string(id).to_string()
     }
 
-    pub fn def(&self, nid: ast::NodeId) -> def::Def {
+    pub fn def(&self, nid: ast::NodeId) -> Def {
         match self.tcx().def_map.borrow().get(&nid) {
             Some(v) => v.full_def(),
             None => {
diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs
index 0fc87970733..2011f1b5352 100644
--- a/src/librustc_trans/trans/consts.rs
+++ b/src/librustc_trans/trans/consts.rs
@@ -13,7 +13,7 @@ use back::abi;
 use llvm;
 use llvm::{ConstFCmp, ConstICmp, SetLinkage, SetUnnamedAddr};
 use llvm::{InternalLinkage, ValueRef, Bool, True};
-use middle::{check_const, def};
+use middle::check_const;
 use middle::cstore::LOCAL_CRATE;
 use middle::const_eval::{self, ConstVal, ConstEvalErr};
 use middle::const_eval::{const_int_checked_neg, const_uint_checked_neg};
@@ -26,6 +26,7 @@ use middle::const_eval::{const_int_checked_shl, const_uint_checked_shl};
 use middle::const_eval::{const_int_checked_shr, const_uint_checked_shr};
 use middle::const_eval::EvalHint::ExprTypeChecked;
 use middle::const_eval::eval_const_expr_partial;
+use middle::def::Def;
 use middle::def_id::DefId;
 use trans::{adt, closure, debuginfo, expr, inline, machine};
 use trans::base::{self, push_ctxt};
@@ -297,7 +298,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         // of just to get the `def` value
         let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
         match def {
-            def::DefConst(def_id) | def::DefAssociatedConst(def_id) => {
+            Def::Const(def_id) | Def::AssociatedConst(def_id) => {
                 if !ccx.tcx().tables.borrow().adjustments.contains_key(&expr.id) {
                     debug!("get_const_expr_as_global ({:?}): found const {:?}",
                            expr.id, def_id);
@@ -792,7 +793,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 }
             }
             let opt_def = cx.tcx().def_map.borrow().get(&cur.id).map(|d| d.full_def());
-            if let Some(def::DefStatic(def_id, _)) = opt_def {
+            if let Some(Def::Static(def_id, _)) = opt_def {
                 common::get_static_val(cx, def_id, ety)
             } else {
                 // If this isn't the address of a static, then keep going through
@@ -881,20 +882,20 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         hir::ExprPath(..) => {
             let def = cx.tcx().def_map.borrow().get(&e.id).unwrap().full_def();
             match def {
-                def::DefLocal(_, id) => {
+                Def::Local(_, id) => {
                     if let Some(val) = fn_args.and_then(|args| args.get(&id).cloned()) {
                         val
                     } else {
                         cx.sess().span_bug(e.span, "const fn argument not found")
                     }
                 }
-                def::DefFn(..) | def::DefMethod(..) => {
+                Def::Fn(..) | Def::Method(..) => {
                     expr::trans_def_fn_unadjusted(cx, e, def, param_substs).val
                 }
-                def::DefConst(def_id) | def::DefAssociatedConst(def_id) => {
+                Def::Const(def_id) | Def::AssociatedConst(def_id) => {
                     const_deref_ptr(cx, try!(get_const_val(cx, def_id, e, param_substs)))
                 }
-                def::DefVariant(enum_did, variant_did, _) => {
+                Def::Variant(enum_did, variant_did) => {
                     let vinfo = cx.tcx().lookup_adt_def(enum_did).variant_with_id(variant_did);
                     match vinfo.kind() {
                         ty::VariantKind::Unit => {
@@ -909,7 +910,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                         }
                     }
                 }
-                def::DefStruct(_) => {
+                Def::Struct(..) => {
                     if let ty::TyBareFn(..) = ety.sty {
                         // Tuple struct.
                         expr::trans_def_fn_unadjusted(cx, e, def, param_substs).val
@@ -938,7 +939,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let def = cx.tcx().def_map.borrow()[&callee.id].full_def();
             let arg_vals = try!(map_list(args));
             match def {
-                def::DefFn(did, _) | def::DefMethod(did) => {
+                Def::Fn(did) | Def::Method(did) => {
                     try!(const_fn_call(
                         cx,
                         ExprId(callee.id),
@@ -948,7 +949,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                         trueconst,
                     ))
                 }
-                def::DefStruct(_) => {
+                Def::Struct(..) => {
                     if ety.is_simd() {
                         C_vector(&arg_vals[..])
                     } else {
@@ -956,7 +957,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                         adt::trans_const(cx, &*repr, Disr(0), &arg_vals[..])
                     }
                 }
-                def::DefVariant(enum_did, variant_did, _) => {
+                Def::Variant(enum_did, variant_did) => {
                     let repr = adt::represent_type(cx, ety);
                     let vinfo = cx.tcx().lookup_adt_def(enum_did).variant_with_id(variant_did);
                     adt::trans_const(cx,
diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs
index 45f46410068..fc3bd4f4d02 100644
--- a/src/librustc_trans/trans/controlflow.rs
+++ b/src/librustc_trans/trans/controlflow.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use llvm::ValueRef;
-use middle::def;
+use middle::def::Def;
 use middle::lang_items::{PanicFnLangItem, PanicBoundsCheckFnLangItem};
 use trans::base::*;
 use trans::basic_block::BasicBlock;
@@ -322,7 +322,7 @@ pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         None => fcx.top_loop_scope(),
         Some(_) => {
             match bcx.tcx().def_map.borrow().get(&expr.id).map(|d| d.full_def())  {
-                Some(def::DefLabel(loop_id)) => loop_id,
+                Some(Def::Label(loop_id)) => loop_id,
                 r => {
                     bcx.tcx().sess.bug(&format!("{:?} in def-map for label", r))
                 }
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index ab2f4462757..60afcaa0fbf 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -54,7 +54,7 @@ use self::lazy_binop_ty::*;
 use back::abi;
 use llvm::{self, ValueRef, TypeKind};
 use middle::check_const;
-use middle::def;
+use middle::def::Def;
 use middle::lang_items::CoerceUnsizedTraitLangItem;
 use middle::subst::{Substs, VecPerParamSpace};
 use middle::traits;
@@ -165,7 +165,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             match expr.node {
                 hir::ExprPath(..) => {
                     match bcx.def(expr.id) {
-                        def::DefConst(did) => {
+                        Def::Const(did) => {
                             let empty_substs = bcx.tcx().mk_substs(Substs::trans_empty());
                             let const_expr = consts::get_const_expr(bcx.ccx(), did, expr,
                                                                     empty_substs);
@@ -903,25 +903,25 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
 fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                          ref_expr: &hir::Expr,
-                         def: def::Def)
+                         def: Def)
                          -> DatumBlock<'blk, 'tcx, Expr> {
     //! Translates a reference to a path.
 
     let _icx = push_ctxt("trans_def_lvalue");
     match def {
-        def::DefFn(..) | def::DefMethod(..) |
-        def::DefStruct(_) | def::DefVariant(..) => {
+        Def::Fn(..) | Def::Method(..) |
+        Def::Struct(..) | Def::Variant(..) => {
             let datum = trans_def_fn_unadjusted(bcx.ccx(), ref_expr, def,
                                                 bcx.fcx.param_substs);
             DatumBlock::new(bcx, datum.to_expr_datum())
         }
-        def::DefStatic(did, _) => {
+        Def::Static(did, _) => {
             let const_ty = expr_ty(bcx, ref_expr);
             let val = get_static_val(bcx.ccx(), did, const_ty);
             let lval = Lvalue::new("expr::trans_def");
             DatumBlock::new(bcx, Datum::new(val, const_ty, LvalueExpr(lval)))
         }
-        def::DefConst(_) => {
+        Def::Const(_) => {
             bcx.sess().span_bug(ref_expr.span,
                 "constant expression should not reach expr::trans_def")
         }
@@ -1272,7 +1272,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
 fn trans_def_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                         ref_expr: &hir::Expr,
-                                        def: def::Def,
+                                        def: Def,
                                         dest: Dest)
                                         -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_def_dps_unadjusted");
@@ -1283,7 +1283,7 @@ fn trans_def_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     };
 
     match def {
-        def::DefVariant(tid, vid, _) => {
+        Def::Variant(tid, vid) => {
             let variant = bcx.tcx().lookup_adt_def(tid).variant_with_id(vid);
             if let ty::VariantKind::Tuple = variant.kind() {
                 // N-ary variant.
@@ -1300,7 +1300,7 @@ fn trans_def_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 return bcx;
             }
         }
-        def::DefStruct(_) => {
+        Def::Struct(..) => {
             let ty = expr_ty(bcx, ref_expr);
             match ty.sty {
                 ty::TyStruct(def, _) if def.has_dtor() => {
@@ -1321,17 +1321,17 @@ fn trans_def_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
 pub fn trans_def_fn_unadjusted<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                          ref_expr: &hir::Expr,
-                                         def: def::Def,
+                                         def: Def,
                                          param_substs: &'tcx Substs<'tcx>)
                                          -> Datum<'tcx, Rvalue> {
     let _icx = push_ctxt("trans_def_datum_unadjusted");
 
     match def {
-        def::DefFn(did, _) |
-        def::DefStruct(did) | def::DefVariant(_, did, _) => {
+        Def::Fn(did) |
+        Def::Struct(did) | Def::Variant(_, did) => {
             callee::trans_fn_ref(ccx, did, ExprId(ref_expr.id), param_substs)
         }
-        def::DefMethod(method_did) => {
+        Def::Method(method_did) => {
             match ccx.tcx().impl_or_trait_item(method_did).container() {
                 ty::ImplContainer(_) => {
                     callee::trans_fn_ref(ccx, method_did,
@@ -1356,12 +1356,12 @@ pub fn trans_def_fn_unadjusted<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
 /// Translates a reference to a local variable or argument. This always results in an lvalue datum.
 pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                   def: def::Def)
+                                   def: Def)
                                    -> Datum<'tcx, Lvalue> {
     let _icx = push_ctxt("trans_local_var");
 
     match def {
-        def::DefUpvar(_, nid, _, _) => {
+        Def::Upvar(_, nid, _, _) => {
             // Can't move upvars, so this is never a ZeroMemLastUse.
             let local_ty = node_id_type(bcx, nid);
             let lval = Lvalue::new_with_hint("expr::trans_local_var (upvar)",
@@ -1375,7 +1375,7 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 }
             }
         }
-        def::DefLocal(_, nid) => {
+        Def::Local(_, nid) => {
             let datum = match bcx.fcx.lllocals.borrow().get(&nid) {
                 Some(&v) => v,
                 None => {
@@ -2587,7 +2587,7 @@ fn expr_kind(tcx: &ty::ctxt, expr: &hir::Expr) -> ExprKind {
     match expr.node {
         hir::ExprPath(..) => {
             match tcx.resolve_expr(expr) {
-                def::DefStruct(_) | def::DefVariant(..) => {
+                Def::Struct(..) | Def::Variant(..) => {
                     if let ty::TyBareFn(..) = tcx.node_id_to_type(expr.id).sty {
                         // ctor function
                         ExprKind::RvalueDatum
@@ -2596,24 +2596,18 @@ fn expr_kind(tcx: &ty::ctxt, expr: &hir::Expr) -> ExprKind {
                     }
                 }
 
-                // Special case: A unit like struct's constructor must be called without () at the
-                // end (like `UnitStruct`) which means this is an ExprPath to a DefFn. But in case
-                // of unit structs this is should not be interpreted as function pointer but as
-                // call to the constructor.
-                def::DefFn(_, true) => ExprKind::RvalueDps,
-
                 // Fn pointers are just scalar values.
-                def::DefFn(..) | def::DefMethod(..) => ExprKind::RvalueDatum,
+                Def::Fn(..) | Def::Method(..) => ExprKind::RvalueDatum,
 
                 // Note: there is actually a good case to be made that
                 // DefArg's, particularly those of immediate type, ought to
                 // considered rvalues.
-                def::DefStatic(..) |
-                def::DefUpvar(..) |
-                def::DefLocal(..) => ExprKind::Lvalue,
+                Def::Static(..) |
+                Def::Upvar(..) |
+                Def::Local(..) => ExprKind::Lvalue,
 
-                def::DefConst(..) |
-                def::DefAssociatedConst(..) => ExprKind::RvalueDatum,
+                Def::Const(..) |
+                Def::AssociatedConst(..) => ExprKind::RvalueDatum,
 
                 def => {
                     tcx.sess.span_bug(
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 98effeefad2..da4265dda54 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -51,7 +51,7 @@
 use middle::astconv_util::{prim_ty_to_ty, prohibit_type_params, prohibit_projection};
 use middle::const_eval::{self, ConstVal};
 use middle::const_eval::EvalHint::UncheckedExprHint;
-use middle::def;
+use middle::def::{self, Def};
 use middle::def_id::DefId;
 use middle::resolve_lifetime as rl;
 use middle::privacy::{AllPublic, LastMod};
@@ -718,8 +718,8 @@ pub fn instantiate_mono_trait_ref<'tcx>(
 fn trait_def_id<'tcx>(this: &AstConv<'tcx>, trait_ref: &hir::TraitRef) -> DefId {
     let path = &trait_ref.path;
     match ::lookup_full_def(this.tcx(), path.span, trait_ref.ref_id) {
-        def::DefTrait(trait_def_id) => trait_def_id,
-        def::DefErr => {
+        Def::Trait(trait_def_id) => trait_def_id,
+        Def::Err => {
             this.tcx().sess.fatal("cannot continue compilation due to previous error");
         }
         _ => {
@@ -1028,7 +1028,7 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>,
                 _ => None
             };
             match def {
-                Some(def::DefTrait(trait_def_id)) => {
+                Some(Def::Trait(trait_def_id)) => {
                     let mut projection_bounds = Vec::new();
                     let trait_ref = object_path_to_poly_trait_ref(this,
                                                                   rscope,
@@ -1263,9 +1263,9 @@ fn one_bound_for_assoc_type<'tcx>(tcx: &ty::ctxt<'tcx>,
 fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                                    span: Span,
                                    ty: Ty<'tcx>,
-                                   ty_path_def: def::Def,
+                                   ty_path_def: Def,
                                    item_segment: &hir::PathSegment)
-                                   -> (Ty<'tcx>, def::Def)
+                                   -> (Ty<'tcx>, Def)
 {
     let tcx = this.tcx();
     let assoc_name = item_segment.identifier.name;
@@ -1277,7 +1277,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
     // Find the type of the associated item, and the trait where the associated
     // item is declared.
     let bound = match (&ty.sty, ty_path_def) {
-        (_, def::DefSelfTy(Some(trait_did), Some((impl_id, _)))) => {
+        (_, Def::SelfTy(Some(trait_did), Some((impl_id, _)))) => {
             // `Self` in an impl of a trait - we have a concrete self type and a
             // trait reference.
             let trait_ref = tcx.impl_trait_ref(tcx.map.local_def_id(impl_id)).unwrap();
@@ -1306,7 +1306,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                 Err(ErrorReported) => return (tcx.types.err, ty_path_def),
             }
         }
-        (&ty::TyParam(_), def::DefSelfTy(Some(trait_did), None)) => {
+        (&ty::TyParam(_), Def::SelfTy(Some(trait_did), None)) => {
             let trait_node_id = tcx.map.as_local_node_id(trait_did).unwrap();
             match find_bound_for_assoc_item(this,
                                             trait_node_id,
@@ -1317,7 +1317,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                 Err(ErrorReported) => return (tcx.types.err, ty_path_def),
             }
         }
-        (&ty::TyParam(_), def::DefTyParam(_, _, param_did, param_name)) => {
+        (&ty::TyParam(_), Def::TyParam(_, _, param_did, param_name)) => {
             let param_node_id = tcx.map.as_local_node_id(param_did).unwrap();
             match find_bound_for_assoc_item(this,
                                             param_node_id,
@@ -1359,7 +1359,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
         item.expect("missing associated type").def_id()
     };
 
-    (ty, def::DefAssociatedTy(trait_did, item_did))
+    (ty, Def::AssociatedTy(trait_did, item_did))
 }
 
 fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
@@ -1443,14 +1443,14 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                         rscope: &RegionScope,
                         span: Span,
                         param_mode: PathParamMode,
-                        def: &def::Def,
+                        def: &Def,
                         opt_self_ty: Option<Ty<'tcx>>,
                         base_segments: &[hir::PathSegment])
                         -> Ty<'tcx> {
     let tcx = this.tcx();
 
     match *def {
-        def::DefTrait(trait_def_id) => {
+        Def::Trait(trait_def_id) => {
             // N.B. this case overlaps somewhat with
             // TyObjectSum, see that fn for details
             let mut projection_bounds = Vec::new();
@@ -1471,7 +1471,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                                      projection_bounds,
                                      &[])
         }
-        def::DefTy(did, _) | def::DefStruct(did) => {
+        Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) => {
             prohibit_type_params(tcx, base_segments.split_last().unwrap().1);
             ast_path_to_ty(this,
                            rscope,
@@ -1480,11 +1480,11 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                            did,
                            base_segments.last().unwrap())
         }
-        def::DefTyParam(space, index, _, name) => {
+        Def::TyParam(space, index, _, name) => {
             prohibit_type_params(tcx, base_segments);
             tcx.mk_param(space, index, name)
         }
-        def::DefSelfTy(_, Some((_, self_ty_id))) => {
+        Def::SelfTy(_, Some((_, self_ty_id))) => {
             // Self in impl (we know the concrete type).
             prohibit_type_params(tcx, base_segments);
             if let Some(&ty) = tcx.ast_ty_to_ty_cache.borrow().get(&self_ty_id) {
@@ -1497,12 +1497,12 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                 tcx.sess.span_bug(span, "self type has not been fully resolved")
             }
         }
-        def::DefSelfTy(Some(_), None) => {
+        Def::SelfTy(Some(_), None) => {
             // Self in trait.
             prohibit_type_params(tcx, base_segments);
             tcx.mk_self_type()
         }
-        def::DefAssociatedTy(trait_did, _) => {
+        Def::AssociatedTy(trait_did, _) => {
             prohibit_type_params(tcx, &base_segments[..base_segments.len()-2]);
             qpath_to_ty(this,
                         rscope,
@@ -1513,7 +1513,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                         &base_segments[base_segments.len()-2],
                         base_segments.last().unwrap())
         }
-        def::DefMod(id) => {
+        Def::Mod(id) => {
             // Used as sentinel by callers to indicate the `<T>::A::B::C` form.
             // FIXME(#22519) This part of the resolution logic should be
             // avoided entirely for that form, once we stop needed a Def
@@ -1534,10 +1534,10 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
 
             opt_self_ty.expect("missing T in <T>::a::b::c")
         }
-        def::DefPrimTy(prim_ty) => {
+        Def::PrimTy(prim_ty) => {
             prim_ty_to_ty(tcx, base_segments, prim_ty)
         }
-        def::DefErr => {
+        Def::Err => {
             return this.tcx().types.err;
         }
         _ => {
@@ -1556,7 +1556,7 @@ pub fn finish_resolving_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                                         rscope: &RegionScope,
                                         span: Span,
                                         param_mode: PathParamMode,
-                                        def: &def::Def,
+                                        def: &Def,
                                         opt_self_ty: Option<Ty<'tcx>>,
                                         base_segments: &[hir::PathSegment],
                                         assoc_segments: &[hir::PathSegment])
@@ -1658,7 +1658,7 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
             } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
                 // Create some fake resolution that can't possibly be a type.
                 def::PathResolution {
-                    base_def: def::DefMod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
+                    base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
                     last_private: LastMod(AllPublic),
                     depth: path.segments.len()
                 }
@@ -2177,7 +2177,7 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
         match *ast_bound {
             hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
                 match ::lookup_full_def(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) {
-                    def::DefTrait(trait_did) => {
+                    Def::Trait(trait_did) => {
                         if tcx.try_add_builtin_trait(trait_did,
                                                      &mut builtin_bounds) {
                             let segments = &b.trait_ref.path.segments;
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index dfa144699b2..c43349f8810 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use middle::def;
+use middle::def::{self, Def};
 use middle::infer::{self, TypeOrigin};
 use middle::pat_util::{PatIdMap, pat_id_map, pat_is_binding};
 use middle::pat_util::pat_is_resolved_const;
@@ -214,7 +214,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
         hir::PatQPath(ref qself, ref path) => {
             let self_ty = fcx.to_ty(&qself.ty);
             let path_res = if let Some(&d) = tcx.def_map.borrow().get(&pat.id) {
-                if d.base_def == def::DefErr {
+                if d.base_def == Def::Err {
                     fcx.write_error(pat.id);
                     return;
                 }
@@ -223,7 +223,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
                 // This is just a sentinel for finish_resolving_def_to_ty.
                 let sentinel = fcx.tcx().map.local_def_id(ast::CRATE_NODE_ID);
                 def::PathResolution {
-                    base_def: def::DefMod(sentinel),
+                    base_def: Def::Mod(sentinel),
                     last_private: LastMod(AllPublic),
                     depth: path.segments.len()
                 }
@@ -410,10 +410,10 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     // subtyping.
 }
 
-fn check_assoc_item_is_const(pcx: &pat_ctxt, def: def::Def, span: Span) -> bool {
+fn check_assoc_item_is_const(pcx: &pat_ctxt, def: Def, span: Span) -> bool {
     match def {
-        def::DefAssociatedConst(..) => true,
-        def::DefMethod(..) => {
+        Def::AssociatedConst(..) => true,
+        Def::Method(..) => {
             span_err!(pcx.fcx.ccx.tcx.sess, span, E0327,
                       "associated items in match patterns must be constants");
             false
@@ -616,7 +616,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     let tcx = pcx.fcx.ccx.tcx;
 
     let path_res = match tcx.def_map.borrow().get(&pat.id) {
-        Some(&path_res) if path_res.base_def != def::DefErr => path_res,
+        Some(&path_res) if path_res.base_def != Def::Err => path_res,
         _ => {
             fcx.write_error(pat.id);
 
@@ -693,10 +693,12 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
 
     let real_path_ty = fcx.node_ty(pat.id);
     let (arg_tys, kind_name): (Vec<_>, &'static str) = match real_path_ty.sty {
-        ty::TyEnum(enum_def, expected_substs)
-            if def == def::DefVariant(enum_def.did, def.def_id(), false) =>
-        {
+        ty::TyEnum(enum_def, expected_substs) => {
             let variant = enum_def.variant_of_def(def);
+            if variant.kind() == ty::VariantKind::Struct {
+                report_bad_struct_kind(false);
+                return;
+            }
             if is_tuple_struct_pat && variant.kind() != ty::VariantKind::Tuple {
                 // Matching unit variants with tuple variant patterns (`UnitVariant(..)`)
                 // is allowed for backward compatibility.
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index a1b378d84d0..84c436c59c1 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -26,7 +26,7 @@ use super::write_call;
 
 use CrateCtxt;
 use middle::cstore::LOCAL_CRATE;
-use middle::def;
+use middle::def::Def;
 use middle::def_id::DefId;
 use middle::infer;
 use middle::ty::{self, LvaluePreference, Ty};
@@ -236,7 +236,7 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
             if let hir::ExprCall(ref expr, _) = call_expr.node {
                 let tcx = fcx.tcx();
                 if let Some(pr) = tcx.def_map.borrow().get(&expr.id) {
-                    if pr.depth == 0 && pr.base_def != def::DefErr {
+                    if pr.depth == 0 && pr.base_def != Def::Err {
                         if let Some(span) = tcx.map.span_if_local(pr.def_id()) {
                             err.span_note(span, "defined here");
                         }
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index d462e2b45b2..fc2dd4475e3 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -12,7 +12,7 @@
 
 use astconv::AstConv;
 use check::FnCtxt;
-use middle::def;
+use middle::def::Def;
 use middle::def_id::DefId;
 use middle::privacy::{AllPublic, DependsOn, LastPrivate, LastMod};
 use middle::subst;
@@ -334,7 +334,7 @@ pub fn resolve_ufcs<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                               method_name: ast::Name,
                               self_ty: ty::Ty<'tcx>,
                               expr_id: ast::NodeId)
-                              -> Result<(def::Def, LastPrivate), MethodError<'tcx>>
+                              -> Result<(Def, LastPrivate), MethodError<'tcx>>
 {
     let mode = probe::Mode::Path;
     let pick = try!(probe::probe(fcx, span, mode, method_name, self_ty, expr_id));
@@ -346,8 +346,8 @@ pub fn resolve_ufcs<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         }
     }
     let def_result = match pick.item {
-        ty::ImplOrTraitItem::MethodTraitItem(..) => def::DefMethod(def_id),
-        ty::ImplOrTraitItem::ConstTraitItem(..) => def::DefAssociatedConst(def_id),
+        ty::ImplOrTraitItem::MethodTraitItem(..) => Def::Method(def_id),
+        ty::ImplOrTraitItem::ConstTraitItem(..) => Def::AssociatedConst(def_id),
         ty::ImplOrTraitItem::TypeTraitItem(..) => {
             fcx.tcx().sess.span_bug(span, "resolve_ufcs: probe picked associated type");
         }
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 560e84b52d1..21bf67d2d5c 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -18,7 +18,7 @@ use check::{self, FnCtxt};
 use front::map as hir_map;
 use middle::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TypeFoldable};
 use middle::cstore::{self, CrateStore, DefLike};
-use middle::def;
+use middle::def::Def;
 use middle::def_id::DefId;
 use middle::lang_items::FnOnceTraitLangItem;
 use middle::subst::Substs;
@@ -432,10 +432,10 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> {
                                cstore: &for<'a> cstore::CrateStore<'a>,
                                dl: cstore::DefLike) {
             match dl {
-                cstore::DlDef(def::DefTrait(did)) => {
+                cstore::DlDef(Def::Trait(did)) => {
                     traits.push(TraitInfo::new(did));
                 }
-                cstore::DlDef(def::DefMod(did)) => {
+                cstore::DlDef(Def::Mod(did)) => {
                     if !external_mods.insert(did) {
                         return;
                     }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 03508b07b7a..f49b25df66e 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -86,7 +86,7 @@ use dep_graph::DepNode;
 use fmt_macros::{Parser, Piece, Position};
 use middle::astconv_util::prohibit_type_params;
 use middle::cstore::LOCAL_CRATE;
-use middle::def;
+use middle::def::{self, Def};
 use middle::def_id::DefId;
 use middle::infer;
 use middle::infer::{TypeOrigin, type_variable};
@@ -1416,16 +1416,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Return the dict-like variant corresponding to a given `Def`.
     pub fn def_struct_variant(&self,
-                              def: def::Def,
+                              def: Def,
                               span: Span)
                               -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
     {
         let (adt, variant) = match def {
-            def::DefVariant(enum_id, variant_id, _) => {
+            Def::Variant(enum_id, variant_id) => {
                 let adt = self.tcx().lookup_adt_def(enum_id);
                 (adt, adt.variant_with_id(variant_id))
             }
-            def::DefTy(did, _) | def::DefStruct(did) => {
+            Def::Struct(did) | Def::TyAlias(did) => {
                 let typ = self.tcx().lookup_item_type(did);
                 if let ty::TyStruct(adt, _) = typ.ty.sty {
                     (adt, adt.struct_variant())
@@ -3167,7 +3167,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
 
         // Find the relevant variant
         let def = lookup_full_def(tcx, path.span, expr.id);
-        if def == def::DefErr {
+        if def == Def::Err {
             check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
             return;
         }
@@ -3337,7 +3337,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
           } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself {
                 // Create some fake resolution that can't possibly be a type.
                 def::PathResolution {
-                    base_def: def::DefMod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
+                    base_def: Def::Mod(tcx.map.local_def_id(ast::CRATE_NODE_ID)),
                     last_private: LastMod(AllPublic),
                     depth: path.segments.len()
                 }
@@ -3349,7 +3349,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
           if let Some((opt_ty, segments, def)) =
                   resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
                                           expr.span, expr.id) {
-              if def != def::DefErr {
+              if def != Def::Err {
                   let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
                                                                                 expr.span,
                                                                                 def);
@@ -3758,7 +3758,7 @@ pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
                                              node_id: ast::NodeId)
                                              -> Option<(Option<Ty<'tcx>>,
                                                         &'a [hir::PathSegment],
-                                                        def::Def)>
+                                                        Def)>
 {
 
     // If fully resolved already, we don't have to do anything.
@@ -4263,29 +4263,30 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
 // Returns the type parameter count and the type for the given definition.
 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                                 sp: Span,
-                                                defn: def::Def)
+                                                defn: Def)
                                                 -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
     match defn {
-        def::DefLocal(_, nid) | def::DefUpvar(_, nid, _, _) => {
+        Def::Local(_, nid) | Def::Upvar(_, nid, _, _) => {
             let typ = fcx.local_ty(sp, nid);
             (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
              ty::GenericPredicates::empty())
         }
-        def::DefFn(id, _) | def::DefMethod(id) |
-        def::DefStatic(id, _) | def::DefVariant(_, id, _) |
-        def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id) => {
+        Def::Fn(id) | Def::Method(id) |
+        Def::Static(id, _) | Def::Variant(_, id) |
+        Def::Struct(id) | Def::Const(id) | Def::AssociatedConst(id) => {
             (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
         }
-        def::DefTrait(_) |
-        def::DefTy(..) |
-        def::DefAssociatedTy(..) |
-        def::DefPrimTy(_) |
-        def::DefTyParam(..) |
-        def::DefMod(..) |
-        def::DefForeignMod(..) |
-        def::DefLabel(..) |
-        def::DefSelfTy(..) |
-        def::DefErr => {
+        Def::Trait(_) |
+        Def::Enum(..) |
+        Def::TyAlias(..) |
+        Def::AssociatedTy(..) |
+        Def::PrimTy(_) |
+        Def::TyParam(..) |
+        Def::Mod(..) |
+        Def::ForeignMod(..) |
+        Def::Label(..) |
+        Def::SelfTy(..) |
+        Def::Err => {
             fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
         }
     }
@@ -4298,7 +4299,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                   type_scheme: TypeScheme<'tcx>,
                                   type_predicates: &ty::GenericPredicates<'tcx>,
                                   opt_self_ty: Option<Ty<'tcx>>,
-                                  def: def::Def,
+                                  def: Def,
                                   span: Span,
                                   node_id: ast::NodeId) {
     debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
@@ -4382,14 +4383,15 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     let mut segment_spaces: Vec<_>;
     match def {
         // Case 1 and 1b. Reference to a *type* or *enum variant*.
-        def::DefSelfTy(..) |
-        def::DefStruct(..) |
-        def::DefVariant(..) |
-        def::DefTy(..) |
-        def::DefAssociatedTy(..) |
-        def::DefTrait(..) |
-        def::DefPrimTy(..) |
-        def::DefTyParam(..) => {
+        Def::SelfTy(..) |
+        Def::Struct(..) |
+        Def::Variant(..) |
+        Def::Enum(..) |
+        Def::TyAlias(..) |
+        Def::AssociatedTy(..) |
+        Def::Trait(..) |
+        Def::PrimTy(..) |
+        Def::TyParam(..) => {
             // Everything but the final segment should have no
             // parameters at all.
             segment_spaces = vec![None; segments.len() - 1];
@@ -4397,15 +4399,15 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         }
 
         // Case 2. Reference to a top-level value.
-        def::DefFn(..) |
-        def::DefConst(..) |
-        def::DefStatic(..) => {
+        Def::Fn(..) |
+        Def::Const(..) |
+        Def::Static(..) => {
             segment_spaces = vec![None; segments.len() - 1];
             segment_spaces.push(Some(subst::FnSpace));
         }
 
         // Case 3. Reference to a method.
-        def::DefMethod(def_id) => {
+        Def::Method(def_id) => {
             let container = fcx.tcx().impl_or_trait_item(def_id).container();
             match container {
                 ty::TraitContainer(trait_did) => {
@@ -4426,7 +4428,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             }
         }
 
-        def::DefAssociatedConst(def_id) => {
+        Def::AssociatedConst(def_id) => {
             let container = fcx.tcx().impl_or_trait_item(def_id).container();
             match container {
                 ty::TraitContainer(trait_did) => {
@@ -4450,12 +4452,12 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         // Other cases. Various nonsense that really shouldn't show up
         // here. If they do, an error will have been reported
         // elsewhere. (I hope)
-        def::DefMod(..) |
-        def::DefForeignMod(..) |
-        def::DefLocal(..) |
-        def::DefLabel(..) |
-        def::DefUpvar(..) |
-        def::DefErr => {
+        Def::Mod(..) |
+        Def::ForeignMod(..) |
+        Def::Local(..) |
+        Def::Label(..) |
+        Def::Upvar(..) |
+        Def::Err => {
             segment_spaces = vec![None; segments.len()];
         }
     }
@@ -4856,7 +4858,7 @@ pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &hir::Block) -> bool {
     // <id> nested anywhere inside the loop?
     (block_query(b, |e| {
         if let hir::ExprBreak(Some(_)) = e.node {
-            lookup_full_def(cx, e.span, e.id) == def::DefLabel(id)
+            lookup_full_def(cx, e.span, e.id) == Def::Label(id)
         } else {
             false
         }
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index eb204c56414..0e095ed674d 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -60,7 +60,7 @@ There are some shortcomings in this design:
 
 use astconv::{self, AstConv, ty_of_arg, ast_ty_to_ty, ast_region_to_region};
 use lint;
-use middle::def;
+use middle::def::Def;
 use middle::def_id::DefId;
 use constrained_type_params as ctp;
 use middle::lang_items::SizedTraitLangItem;
@@ -512,10 +512,10 @@ fn is_param<'tcx>(tcx: &ty::ctxt<'tcx>,
     if let hir::TyPath(None, _) = ast_ty.node {
         let path_res = *tcx.def_map.borrow().get(&ast_ty.id).unwrap();
         match path_res.base_def {
-            def::DefSelfTy(Some(def_id), None) => {
+            Def::SelfTy(Some(def_id), None) => {
                 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
             }
-            def::DefTyParam(_, _, def_id, _) => {
+            Def::TyParam(_, _, def_id, _) => {
                 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
             }
             _ => {
@@ -1007,11 +1007,7 @@ fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
         name: name,
         disr_val: disr_val,
         fields: fields,
-        kind: match *def {
-            hir::VariantData::Struct(..) => ty::VariantKind::Struct,
-            hir::VariantData::Tuple(..) => ty::VariantKind::Tuple,
-            hir::VariantData::Unit(..) => ty::VariantKind::Unit,
-        }
+        kind: VariantKind::from_variant_data(def),
     }
 }
 
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index acffbeabb24..17d71fa7be9 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -100,7 +100,7 @@ pub use rustc::session;
 pub use rustc::util;
 
 use front::map as hir_map;
-use middle::def;
+use middle::def::Def;
 use middle::infer::{self, TypeOrigin};
 use middle::subst;
 use middle::ty::{self, Ty, TypeFoldable};
@@ -162,7 +162,7 @@ fn write_substs_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>,
     }
 }
 
-fn lookup_full_def(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) -> def::Def {
+fn lookup_full_def(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) -> Def {
     match tcx.def_map.borrow().get(&id) {
         Some(x) => x.full_def(),
         None => {
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 30b478f486e..9eac2fd41fa 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -17,7 +17,7 @@ use syntax::attr::AttrMetaMethods;
 use rustc_front::hir;
 
 use rustc::middle::cstore::{self, CrateStore};
-use rustc::middle::def;
+use rustc::middle::def::Def;
 use rustc::middle::def_id::DefId;
 use rustc::middle::ty;
 use rustc::middle::subst;
@@ -68,46 +68,47 @@ pub fn try_inline(cx: &DocContext, id: ast::NodeId, into: Option<ast::Name>)
 }
 
 fn try_inline_def(cx: &DocContext, tcx: &ty::ctxt,
-                  def: def::Def) -> Option<Vec<clean::Item>> {
+                  def: Def) -> Option<Vec<clean::Item>> {
     let mut ret = Vec::new();
     let did = def.def_id();
     let inner = match def {
-        def::DefTrait(did) => {
+        Def::Trait(did) => {
             record_extern_fqn(cx, did, clean::TypeTrait);
             clean::TraitItem(build_external_trait(cx, tcx, did))
         }
-        def::DefFn(did, false) => {
-            // If this function is a tuple struct constructor, we just skip it
+        Def::Fn(did) => {
             record_extern_fqn(cx, did, clean::TypeFunction);
             clean::FunctionItem(build_external_function(cx, tcx, did))
         }
-        def::DefStruct(did) => {
+        Def::Struct(did)
+                // If this is a struct constructor, we skip it
+                if tcx.sess.cstore.tuple_struct_definition_if_ctor(did).is_none() => {
             record_extern_fqn(cx, did, clean::TypeStruct);
             ret.extend(build_impls(cx, tcx, did));
             clean::StructItem(build_struct(cx, tcx, did))
         }
-        def::DefTy(did, false) => {
+        Def::TyAlias(did) => {
             record_extern_fqn(cx, did, clean::TypeTypedef);
             ret.extend(build_impls(cx, tcx, did));
             build_type(cx, tcx, did)
         }
-        def::DefTy(did, true) => {
+        Def::Enum(did) => {
             record_extern_fqn(cx, did, clean::TypeEnum);
             ret.extend(build_impls(cx, tcx, did));
             build_type(cx, tcx, did)
         }
         // Assume that the enum type is reexported next to the variant, and
         // variants don't show up in documentation specially.
-        def::DefVariant(..) => return Some(Vec::new()),
-        def::DefMod(did) => {
+        Def::Variant(..) => return Some(Vec::new()),
+        Def::Mod(did) => {
             record_extern_fqn(cx, did, clean::TypeModule);
             clean::ModuleItem(build_module(cx, tcx, did))
         }
-        def::DefStatic(did, mtbl) => {
+        Def::Static(did, mtbl) => {
             record_extern_fqn(cx, did, clean::TypeStatic);
             clean::StaticItem(build_static(cx, tcx, did, mtbl))
         }
-        def::DefConst(did) | def::DefAssociatedConst(did) => {
+        Def::Const(did) | Def::AssociatedConst(did) => {
             record_extern_fqn(cx, did, clean::TypeConst);
             clean::ConstantItem(build_const(cx, tcx, did))
         }
@@ -258,7 +259,7 @@ pub fn build_impls(cx: &DocContext, tcx: &ty::ctxt,
                           impls: &mut Vec<clean::Item>) {
             match def {
                 cstore::DlImpl(did) => build_impl(cx, tcx, did, impls),
-                cstore::DlDef(def::DefMod(did)) => {
+                cstore::DlDef(Def::Mod(did)) => {
                     for item in tcx.sess.cstore.item_children(did) {
                         populate_impls(cx, tcx, item.def, impls)
                     }
@@ -455,7 +456,7 @@ fn build_module(cx: &DocContext, tcx: &ty::ctxt,
         let mut visited = HashSet::new();
         for item in tcx.sess.cstore.item_children(did) {
             match item.def {
-                cstore::DlDef(def::DefForeignMod(did)) => {
+                cstore::DlDef(Def::ForeignMod(did)) => {
                     fill_in(cx, tcx, did, items);
                 }
                 cstore::DlDef(def) if item.vis == hir::Public => {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index d2a5fd457d2..03e2a7139b2 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -36,7 +36,7 @@ use syntax::ptr::P;
 
 use rustc_trans::back::link;
 use rustc::middle::cstore::{self, CrateStore};
-use rustc::middle::def;
+use rustc::middle::def::Def;
 use rustc::middle::def_id::{DefId, DefIndex};
 use rustc::middle::subst::{self, ParamSpace, VecPerParamSpace};
 use rustc::middle::ty;
@@ -230,7 +230,7 @@ impl Clean<ExternalCrate> for CrateNum {
         cx.tcx_opt().map(|tcx| {
             for item in tcx.sess.cstore.crate_top_level_items(self.0) {
                 let did = match item.def {
-                    cstore::DlDef(def::DefMod(did)) => did,
+                    cstore::DlDef(Def::Mod(did)) => did,
                     _ => continue
                 };
                 let attrs = inline::load_attrs(cx, tcx, did);
@@ -2607,7 +2607,7 @@ fn resolve_type(cx: &DocContext,
     debug!("resolve_type: def={:?}", def);
 
     let is_generic = match def {
-        def::DefPrimTy(p) => match p {
+        Def::PrimTy(p) => match p {
             hir::TyStr => return Primitive(Str),
             hir::TyBool => return Primitive(Bool),
             hir::TyChar => return Primitive(Char),
@@ -2624,30 +2624,30 @@ fn resolve_type(cx: &DocContext,
             hir::TyFloat(ast::TyF32) => return Primitive(F32),
             hir::TyFloat(ast::TyF64) => return Primitive(F64),
         },
-        def::DefSelfTy(..) if path.segments.len() == 1 => {
+        Def::SelfTy(..) if path.segments.len() == 1 => {
             return Generic(special_idents::type_self.name.to_string());
         }
-        def::DefSelfTy(..) | def::DefTyParam(..) => true,
+        Def::SelfTy(..) | Def::TyParam(..) => true,
         _ => false,
     };
     let did = register_def(&*cx, def);
     ResolvedPath { path: path, typarams: None, did: did, is_generic: is_generic }
 }
 
-fn register_def(cx: &DocContext, def: def::Def) -> DefId {
+fn register_def(cx: &DocContext, def: Def) -> DefId {
     debug!("register_def({:?})", def);
 
     let (did, kind) = match def {
-        def::DefFn(i, _) => (i, TypeFunction),
-        def::DefTy(i, false) => (i, TypeTypedef),
-        def::DefTy(i, true) => (i, TypeEnum),
-        def::DefTrait(i) => (i, TypeTrait),
-        def::DefStruct(i) => (i, TypeStruct),
-        def::DefMod(i) => (i, TypeModule),
-        def::DefStatic(i, _) => (i, TypeStatic),
-        def::DefVariant(i, _, _) => (i, TypeEnum),
-        def::DefSelfTy(Some(def_id), _) => (def_id, TypeTrait),
-        def::DefSelfTy(_, Some((impl_id, _))) => return cx.map.local_def_id(impl_id),
+        Def::Fn(i) => (i, TypeFunction),
+        Def::TyAlias(i) => (i, TypeTypedef),
+        Def::Enum(i) => (i, TypeEnum),
+        Def::Trait(i) => (i, TypeTrait),
+        Def::Struct(i) => (i, TypeStruct),
+        Def::Mod(i) => (i, TypeModule),
+        Def::Static(i, _) => (i, TypeStatic),
+        Def::Variant(i, _) => (i, TypeEnum),
+        Def::SelfTy(Some(def_id), _) => (def_id, TypeTrait),
+        Def::SelfTy(_, Some((impl_id, _))) => return cx.map.local_def_id(impl_id),
         _ => return def.def_id()
     };
     if did.is_local() { return did }
diff --git a/src/test/compile-fail/empty-struct-braces-expr.rs b/src/test/compile-fail/empty-struct-braces-expr.rs
index 6ae0dad0e7b..61e4a1ea397 100644
--- a/src/test/compile-fail/empty-struct-braces-expr.rs
+++ b/src/test/compile-fail/empty-struct-braces-expr.rs
@@ -29,9 +29,8 @@ fn main() {
     let e3 = E::Empty3; //~ ERROR `E::Empty3` is the name of a struct or struct variant
     let e3 = E::Empty3(); //~ ERROR `E::Empty3` is the name of a struct or struct variant
 
-    // FIXME: non-local struct kind should be known early (e.g. kept in `DefStruct`)
-    // let xe1 = XEmpty1; // ERROR `XEmpty1` is the name of a struct or struct variant
-    let xe1 = XEmpty1(); //~ ERROR expected function, found `empty_struct::XEmpty1`
+    let xe1 = XEmpty1; //~ ERROR `XEmpty1` is the name of a struct or struct variant
+    let xe1 = XEmpty1(); //~ ERROR `XEmpty1` is the name of a struct or struct variant
     let xe3 = XE::Empty3; //~ ERROR no associated item named `Empty3` found for type
     let xe3 = XE::Empty3(); //~ ERROR no associated item named `Empty3` found for type
 }
diff --git a/src/test/compile-fail/empty-struct-braces-pat-2.rs b/src/test/compile-fail/empty-struct-braces-pat-2.rs
index 3436e2a2cd7..ac6fbc7e06d 100644
--- a/src/test/compile-fail/empty-struct-braces-pat-2.rs
+++ b/src/test/compile-fail/empty-struct-braces-pat-2.rs
@@ -34,6 +34,6 @@ fn main() {
         Empty1(..) => () //~ ERROR unresolved enum variant, struct or const `Empty1`
     }
     match xe1 {
-        XEmpty1(..) => () //~ ERROR `XEmpty1` does not name a tuple variant or a tuple struct
+        XEmpty1(..) => () //~ ERROR unresolved enum variant, struct or const `XEmpty1`
     }
 }
diff --git a/src/test/compile-fail/issue-10545.rs b/src/test/compile-fail/issue-10545.rs
index f6c62bb8557..708eea39a95 100644
--- a/src/test/compile-fail/issue-10545.rs
+++ b/src/test/compile-fail/issue-10545.rs
@@ -14,7 +14,7 @@ mod a {
     impl S { }
 }
 
-fn foo(_: a::S) { //~ ERROR: type `S` is private
+fn foo(_: a::S) { //~ ERROR: struct `S` is private
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/privacy1.rs b/src/test/compile-fail/privacy1.rs
index 7c8b91741ea..593068c2aea 100644
--- a/src/test/compile-fail/privacy1.rs
+++ b/src/test/compile-fail/privacy1.rs
@@ -164,7 +164,7 @@ pub mod mytest {
     // Even though the inner `A` struct is a publicly exported item (usable from
     // external crates through `foo::foo`, it should not be accessible through
     // its definition path (which has the private `i` module).
-    use self::foo::i::A; //~ ERROR: type `A` is inaccessible
+    use self::foo::i::A; //~ ERROR: struct `A` is inaccessible
                          //~^ NOTE: module `i` is private
 
     pub mod foo {
diff --git a/src/test/compile-fail/struct-field-privacy.rs b/src/test/compile-fail/struct-field-privacy.rs
index aae09cc0eae..2ff48b73e29 100644
--- a/src/test/compile-fail/struct-field-privacy.rs
+++ b/src/test/compile-fail/struct-field-privacy.rs
@@ -28,7 +28,7 @@ mod inner {
 }
 
 fn test(a: A, b: inner::A, c: inner::B, d: xc::A, e: xc::B) {
-    //~^ ERROR: type `A` is private
+    //~^ ERROR: struct `A` is private
     //~^^ ERROR: struct `A` is private
 
     a.a;
diff --git a/src/test/compile-fail/xcrate-unit-struct.rs b/src/test/compile-fail/xcrate-unit-struct.rs
index cccb7e50021..214a2a371ba 100644
--- a/src/test/compile-fail/xcrate-unit-struct.rs
+++ b/src/test/compile-fail/xcrate-unit-struct.rs
@@ -16,6 +16,7 @@
 extern crate xcrate_unit_struct;
 
 fn main() {
-    let _ = xcrate_unit_struct::StructWithFields; //~ ERROR: unresolved name
+    let _ = xcrate_unit_struct::StructWithFields;
+    //~^ ERROR: `xcrate_unit_struct::StructWithFields` is the name of a struct or struct variant
     let _ = xcrate_unit_struct::Struct;
 }
diff --git a/src/test/run-pass/associated-const-match-patterns.rs b/src/test/run-pass/associated-const-match-patterns.rs
index 62e90d7a6e2..605ca6b65e2 100644
--- a/src/test/run-pass/associated-const-match-patterns.rs
+++ b/src/test/run-pass/associated-const-match-patterns.rs
@@ -8,8 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// aux-build:empty-struct.rs
+
 #![feature(associated_consts)]
 
+extern crate empty_struct;
+use empty_struct::XEmpty2 as XFoo;
+
 struct Foo;
 
 enum Bar {
@@ -30,6 +35,10 @@ impl HasBar for Foo {
     const THEBAR: Bar = Bar::Var1;
 }
 
+impl HasBar for XFoo {
+    const THEBAR: Bar = Bar::Var1;
+}
+
 fn main() {
     // Inherent impl
     assert!(match Bar::Var2 {
@@ -53,4 +62,16 @@ fn main() {
         <Foo as HasBar>::THEBAR => true,
         _ => false,
     });
+    assert!(match Bar::Var1 {
+        XFoo::THEBAR => true,
+        _ => false,
+    });
+    assert!(match Bar::Var1 {
+        <XFoo>::THEBAR => true,
+        _ => false,
+    });
+    assert!(match Bar::Var1 {
+        <XFoo as HasBar>::THEBAR => true,
+        _ => false,
+    });
 }