about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2016-02-16 00:40:38 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2016-02-16 00:40:38 +0300
commit06755d90ce3bf9694060e579439ee4e8345e4512 (patch)
tree325bb8ae969f1b147a0e725b570fba0b0b7a8098 /src
parent9b40e1e5b3d75c101b1ad78a1e2160962e955174 (diff)
downloadrust-06755d90ce3bf9694060e579439ee4e8345e4512.tar.gz
rust-06755d90ce3bf9694060e579439ee4e8345e4512.zip
Split PatKind::Enum into PatKind::TupleStruct and PatKind::Path
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/cfg/construct.rs5
-rw-r--r--src/librustc/middle/check_match.rs93
-rw-r--r--src/librustc/middle/const_eval.rs8
-rw-r--r--src/librustc/middle/expr_use_visitor.rs2
-rw-r--r--src/librustc/middle/mem_categorization.rs14
-rw-r--r--src/librustc/middle/pat_util.rs15
-rw-r--r--src/librustc/middle/region.rs2
-rw-r--r--src/librustc/middle/stability.rs4
-rw-r--r--src/librustc_front/fold.rs7
-rw-r--r--src/librustc_front/hir.rs28
-rw-r--r--src/librustc_front/intravisit.rs5
-rw-r--r--src/librustc_front/lowering.rs10
-rw-r--r--src/librustc_front/print/pprust.rs13
-rw-r--r--src/librustc_front/util.rs5
-rw-r--r--src/librustc_mir/hair/cx/pattern.rs6
-rw-r--r--src/librustc_privacy/lib.rs2
-rw-r--r--src/librustc_resolve/lib.rs13
-rw-r--r--src/librustc_trans/trans/_match.rs22
-rw-r--r--src/librustc_trans/trans/debuginfo/create_scope_map.rs4
-rw-r--r--src/librustc_typeck/check/_match.rs17
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/libsyntax/ast.rs2
22 files changed, 137 insertions, 142 deletions
diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs
index feefda74143..701a4596908 100644
--- a/src/librustc/middle/cfg/construct.rs
+++ b/src/librustc/middle/cfg/construct.rs
@@ -100,7 +100,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
     fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex {
         match pat.node {
             PatKind::Ident(_, _, None) |
-            PatKind::Enum(_, None) |
+            PatKind::TupleStruct(_, None) |
+            PatKind::Path(..) |
             PatKind::QPath(..) |
             PatKind::Lit(..) |
             PatKind::Range(..) |
@@ -115,7 +116,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 self.add_ast_node(pat.id, &[subpat_exit])
             }
 
-            PatKind::Enum(_, Some(ref subpats)) |
+            PatKind::TupleStruct(_, Some(ref subpats)) |
             PatKind::Tup(ref subpats) => {
                 let pats_exit = self.pats_all(subpats.iter(), pred);
                 self.add_ast_node(pat.id, &[pats_exit])
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 3a269e9946f..246a4e9f28f 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -377,7 +377,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix, source: hir:
                 hir::MatchSource::ForLoopDesugar => {
                     // `witnesses[0]` has the form `Some(<head>)`, peel off the `Some`
                     let witness = match witnesses[0].node {
-                        PatKind::Enum(_, Some(ref pats)) => match &pats[..] {
+                        PatKind::TupleStruct(_, Some(ref pats)) => match &pats[..] {
                             [ref pat] => &**pat,
                             _ => unreachable!(),
                         },
@@ -466,7 +466,7 @@ impl<'map> ast_util::IdVisitingOperation for RenamingRecorder<'map> {
 impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
     fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
         return match pat.node {
-            PatKind::Ident(..) | PatKind::Enum(..) | PatKind::QPath(..) => {
+            PatKind::Ident(..) | PatKind::Path(..) | PatKind::QPath(..) => {
                 let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
                 match def {
                     Some(Def::AssociatedConst(did)) |
@@ -534,22 +534,28 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
 
         ty::TyEnum(adt, _) | ty::TyStruct(adt, _)  => {
             let v = adt.variant_of_ctor(ctor);
-            if let VariantKind::Struct = v.kind() {
-                let field_pats: hir::HirVec<_> = v.fields.iter()
-                    .zip(pats)
-                    .filter(|&(_, ref pat)| pat.node != PatKind::Wild)
-                    .map(|(field, pat)| Spanned {
-                        span: DUMMY_SP,
-                        node: hir::FieldPat {
-                            name: field.name,
-                            pat: pat,
-                            is_shorthand: false,
-                        }
-                    }).collect();
-                let has_more_fields = field_pats.len() < pats_len;
-                PatKind::Struct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields)
-            } else {
-                PatKind::Enum(def_to_path(cx.tcx, v.did), Some(pats.collect()))
+            match v.kind() {
+                VariantKind::Struct => {
+                    let field_pats: hir::HirVec<_> = v.fields.iter()
+                        .zip(pats)
+                        .filter(|&(_, ref pat)| pat.node != PatKind::Wild)
+                        .map(|(field, pat)| Spanned {
+                            span: DUMMY_SP,
+                            node: hir::FieldPat {
+                                name: field.name,
+                                pat: pat,
+                                is_shorthand: false,
+                            }
+                        }).collect();
+                    let has_more_fields = field_pats.len() < pats_len;
+                    PatKind::Struct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields)
+                }
+                VariantKind::Tuple => {
+                    PatKind::TupleStruct(def_to_path(cx.tcx, v.did), Some(pats.collect()))
+                }
+                VariantKind::Unit => {
+                    PatKind::Path(def_to_path(cx.tcx, v.did))
+                }
             }
         }
 
@@ -769,34 +775,20 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
                     left_ty: Ty, max_slice_length: usize) -> Vec<Constructor> {
     let pat = raw_pat(p);
     match pat.node {
-        PatKind::Ident(..) =>
-            match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
-                Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
-                    cx.tcx.sess.span_bug(pat.span, "const pattern should've \
-                                                    been rewritten"),
-                Some(Def::Struct(..)) => vec!(Single),
-                Some(Def::Variant(_, id)) => vec!(Variant(id)),
-                _ => vec!()
-            },
-        PatKind::Enum(..) =>
-            match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
-                Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
+        PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::Ident(..) =>
+            match cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def() {
+                Def::Const(..) | Def::AssociatedConst(..) =>
                     cx.tcx.sess.span_bug(pat.span, "const pattern should've \
                                                     been rewritten"),
-                Some(Def::Variant(_, id)) => vec!(Variant(id)),
-                _ => vec!(Single)
+                Def::Struct(..) | Def::TyAlias(..) => vec![Single],
+                Def::Variant(_, id) => vec![Variant(id)],
+                Def::Local(..) => vec![],
+                def => cx.tcx.sess.span_bug(pat.span, &format!("pat_constructors: unexpected \
+                                                                definition {:?}", def)),
             },
         PatKind::QPath(..) =>
             cx.tcx.sess.span_bug(pat.span, "const pattern should've \
                                             been rewritten"),
-        PatKind::Struct(..) =>
-            match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
-                Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
-                    cx.tcx.sess.span_bug(pat.span, "const pattern should've \
-                                                    been rewritten"),
-                Some(Def::Variant(_, id)) => vec!(Variant(id)),
-                _ => vec!(Single)
-            },
         PatKind::Lit(ref expr) =>
             vec!(ConstantValue(eval_const_expr(cx.tcx, &expr))),
         PatKind::Range(ref lo, ref hi) =>
@@ -880,22 +872,21 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
         PatKind::Wild =>
             Some(vec![DUMMY_WILD_PAT; arity]),
 
-        PatKind::Ident(_, _, _) => {
-            let opt_def = cx.tcx.def_map.borrow().get(&pat_id).map(|d| d.full_def());
-            match opt_def {
-                Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) =>
+        PatKind::Path(..) | PatKind::Ident(..) => {
+            let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
+            match def {
+                Def::Const(..) | Def::AssociatedConst(..) =>
                     cx.tcx.sess.span_bug(pat_span, "const pattern should've \
                                                     been rewritten"),
-                Some(Def::Variant(_, id)) => if *constructor == Variant(id) {
-                    Some(vec!())
-                } else {
-                    None
-                },
-                _ => Some(vec![DUMMY_WILD_PAT; arity])
+                Def::Variant(_, id) if *constructor != Variant(id) => None,
+                Def::Variant(..) | Def::Struct(..) => Some(Vec::new()),
+                Def::Local(..) => Some(vec![DUMMY_WILD_PAT; arity]),
+                _ => cx.tcx.sess.span_bug(pat_span, &format!("specialize: unexpected \
+                                                              definition {:?}", def)),
             }
         }
 
-        PatKind::Enum(_, ref args) => {
+        PatKind::TupleStruct(_, ref args) => {
             let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
             match def {
                 Def::Const(..) | Def::AssociatedConst(..) =>
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index a347bfc9b48..9ec79c84afb 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -343,7 +343,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<hir::Pat>
                 _ => unreachable!()
             };
             let pats = args.iter().map(|expr| const_expr_to_pat(tcx, &expr, span)).collect();
-            PatKind::Enum(path, Some(pats))
+            PatKind::TupleStruct(path, Some(pats))
         }
 
         hir::ExprStruct(ref path, ref fields, None) => {
@@ -366,10 +366,8 @@ 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::Struct(..)) =>
-                    PatKind::Struct(path.clone(), hir::HirVec::new(), false),
-                Some(Def::Variant(..)) =>
-                    PatKind::Enum(path.clone(), None),
+                Some(Def::Struct(..)) | Some(Def::Variant(..)) =>
+                    PatKind::Path(path.clone()),
                 Some(Def::Const(def_id)) |
                 Some(Def::AssociatedConst(def_id)) => {
                     let expr = lookup_const_by_id(tcx, def_id, Some(expr.id), None).unwrap();
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 491cfa65a1e..9b315aa46e5 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -1070,7 +1070,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
             let tcx = typer.tcx;
 
             match pat.node {
-                PatKind::Enum(_, _) | PatKind::QPath(..) |
+                PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::QPath(..) |
                 PatKind::Ident(_, _, None) | PatKind::Struct(..) => {
                     match def_map.get(&pat.id).map(|d| d.full_def()) {
                         None => {
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index a18d4dbee7d..c16997157bd 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -1209,7 +1209,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
             None
         };
 
-        // Note: This goes up here (rather than within the PatKind::Enum arm
+        // Note: This goes up here (rather than within the PatKind::TupleStruct arm
         // alone) because struct patterns can refer to struct types or
         // to struct variants within enums.
         let cmt = match opt_def {
@@ -1226,10 +1226,10 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
             // _
           }
 
-          PatKind::Enum(_, None) => {
+          PatKind::TupleStruct(_, None) => {
             // variant(..)
           }
-          PatKind::Enum(_, Some(ref subpats)) => {
+          PatKind::TupleStruct(_, Some(ref subpats)) => {
             match opt_def {
                 Some(Def::Variant(..)) => {
                     // variant(x, y, z)
@@ -1267,18 +1267,14 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
             }
           }
 
-          PatKind::QPath(..) => {
-              // Lone constant: ignore
+          PatKind::Path(..) | PatKind::QPath(..) | PatKind::Ident(_, _, None) => {
+              // Lone constant, or unit variant or identifier: ignore
           }
 
           PatKind::Ident(_, _, Some(ref subpat)) => {
               try!(self.cat_pattern_(cmt, &subpat, op));
           }
 
-          PatKind::Ident(_, _, None) => {
-              // nullary variant or identifier: ignore
-          }
-
           PatKind::Struct(_, ref field_pats, _) => {
             // {f1: p1, ..., fN: pN}
             for fp in field_pats {
diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs
index 55fad3e3595..a1a3c194efe 100644
--- a/src/librustc/middle/pat_util.rs
+++ b/src/librustc/middle/pat_util.rs
@@ -35,7 +35,8 @@ pub fn pat_id_map(dm: &RefCell<DefMap>, pat: &hir::Pat) -> PatIdMap {
 pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
     match pat.node {
         PatKind::Lit(_) | PatKind::Range(_, _) | PatKind::QPath(..) => true,
-        PatKind::Enum(_, _) |
+        PatKind::TupleStruct(..) |
+        PatKind::Path(..) |
         PatKind::Ident(_, _, None) |
         PatKind::Struct(..) => {
             match dm.get(&pat.id).map(|d| d.full_def()) {
@@ -50,11 +51,12 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
 
 pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool {
     match pat.node {
-        PatKind::Enum(_, _) |
+        PatKind::TupleStruct(..) |
+        PatKind::Path(..) |
         PatKind::Ident(_, _, None) |
         PatKind::Struct(..) => {
             match dm.get(&pat.id).map(|d| d.full_def()) {
-                Some(Def::Variant(..)) | Some(Def::Struct(..)) => true,
+                Some(Def::Variant(..)) | Some(Def::Struct(..)) | Some(Def::TyAlias(..)) => true,
                 _ => false
             }
         }
@@ -64,7 +66,7 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool {
 
 pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool {
     match pat.node {
-        PatKind::Ident(_, _, None) | PatKind::Enum(..) | PatKind::QPath(..) => {
+        PatKind::Ident(_, _, None) | PatKind::Path(..) | PatKind::QPath(..) => {
             match dm.get(&pat.id).map(|d| d.full_def()) {
                 Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true,
                 _ => false
@@ -78,7 +80,7 @@ pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool {
 // returned instead of a panic.
 pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool {
     match pat.node {
-        PatKind::Ident(_, _, None) | PatKind::Enum(..) | PatKind::QPath(..) => {
+        PatKind::Ident(_, _, None) | PatKind::Path(..) | PatKind::QPath(..) => {
             match dm.get(&pat.id)
                     .and_then(|d| if d.depth == 0 { Some(d.base_def) }
                                   else { None } ) {
@@ -224,7 +226,8 @@ pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<DefId> {
     let mut variants = vec![];
     walk_pat(pat, |p| {
         match p.node {
-            PatKind::Enum(_, _) |
+            PatKind::TupleStruct(..) |
+            PatKind::Path(..) |
             PatKind::Ident(_, _, None) |
             PatKind::Struct(..) => {
                 match dm.get(&p.id) {
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 21df46990dd..b39964e2861 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -970,7 +970,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) {
                 pats3.iter().any(|p| is_binding_pat(&p))
             }
 
-            PatKind::Enum(_, Some(ref subpats)) |
+            PatKind::TupleStruct(_, Some(ref subpats)) |
             PatKind::Tup(ref subpats) => {
                 subpats.iter().any(|p| is_binding_pat(&p))
             }
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index eeb9d673361..fbb84c3cd7e 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -598,8 +598,8 @@ pub fn check_pat(tcx: &ty::ctxt, pat: &hir::Pat,
     };
     match pat.node {
         // Foo(a, b, c)
-        // A Variant(..) pattern `PatKind::Enum(_, None)` doesn't have to be recursed into.
-        PatKind::Enum(_, Some(ref pat_fields)) => {
+        // A Variant(..) pattern `PatKind::TupleStruct(_, None)` doesn't have to be recursed into.
+        PatKind::TupleStruct(_, Some(ref pat_fields)) => {
             for (field, struct_field) in pat_fields.iter().zip(&v.fields) {
                 maybe_do_stability_check(tcx, struct_field.did, field.span, cb)
             }
diff --git a/src/librustc_front/fold.rs b/src/librustc_front/fold.rs
index c2c776a7443..b5e56edb6e4 100644
--- a/src/librustc_front/fold.rs
+++ b/src/librustc_front/fold.rs
@@ -972,10 +972,13 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
                              sub.map(|x| folder.fold_pat(x)))
                 }
                 PatKind::Lit(e) => PatKind::Lit(folder.fold_expr(e)),
-                PatKind::Enum(pth, pats) => {
-                    PatKind::Enum(folder.fold_path(pth),
+                PatKind::TupleStruct(pth, pats) => {
+                    PatKind::TupleStruct(folder.fold_path(pth),
                             pats.map(|pats| pats.move_map(|x| folder.fold_pat(x))))
                 }
+                PatKind::Path(pth) => {
+                    PatKind::Path(folder.fold_path(pth))
+                }
                 PatKind::QPath(qself, pth) => {
                     let qself = QSelf { ty: folder.fold_ty(qself.ty), ..qself };
                     PatKind::QPath(qself, folder.fold_path(pth))
diff --git a/src/librustc_front/hir.rs b/src/librustc_front/hir.rs
index 395bd0ef3e4..dbc1d71517b 100644
--- a/src/librustc_front/hir.rs
+++ b/src/librustc_front/hir.rs
@@ -509,28 +509,34 @@ pub enum PatKind {
     /// Represents a wildcard pattern (`_`)
     Wild,
 
-    /// A PatKind::Ident may either be a new bound variable,
-    /// or a nullary enum (in which case the third field
-    /// is None).
+    /// A `PatKind::Ident` may either be a new bound variable,
+    /// or a unit struct/variant pattern, or a const pattern (in the last two cases
+    /// the third field must be `None`).
     ///
-    /// In the nullary enum case, the parser can't determine
+    /// In the unit or const pattern case, the parser can't determine
     /// which it is. The resolver determines this, and
-    /// records this pattern's NodeId in an auxiliary
-    /// set (of "PatIdents that refer to nullary enums")
+    /// records this pattern's `NodeId` in an auxiliary
+    /// set (of "PatIdents that refer to unit patterns or constants").
     Ident(BindingMode, Spanned<Ident>, Option<P<Pat>>),
 
+    /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
+    /// The `bool` is `true` in the presence of a `..`.
+    Struct(Path, HirVec<Spanned<FieldPat>>, bool),
+
+    /// A tuple struct/variant pattern `Variant(x, y, z)`.
     /// "None" means a `Variant(..)` pattern where we don't bind the fields to names.
-    Enum(Path, Option<HirVec<P<Pat>>>),
+    TupleStruct(Path, Option<HirVec<P<Pat>>>),
+
+    /// A path pattern.
+    /// Such pattern can be resolved to a unit struct/variant or a constant.
+    Path(Path),
 
     /// An associated const named using the qualified path `<T>::CONST` or
     /// `<T as Trait>::CONST`. Associated consts from inherent impls can be
     /// referred to as simply `T::CONST`, in which case they will end up as
-    /// PatKind::Enum, and the resolver will have to sort that out.
+    /// PatKind::Path, and the resolver will have to sort that out.
     QPath(QSelf, Path),
 
-    /// Destructuring of a struct, e.g. `Foo {x, y, ..}`
-    /// The `bool` is `true` in the presence of a `..`
-    Struct(Path, HirVec<Spanned<FieldPat>>, bool),
     /// A tuple pattern `(a, b)`
     Tup(HirVec<P<Pat>>),
     /// A `box` pattern
diff --git a/src/librustc_front/intravisit.rs b/src/librustc_front/intravisit.rs
index f235a7b8234..c1bcaab9d68 100644
--- a/src/librustc_front/intravisit.rs
+++ b/src/librustc_front/intravisit.rs
@@ -468,12 +468,15 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V,
 
 pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
     match pattern.node {
-        PatKind::Enum(ref path, ref opt_children) => {
+        PatKind::TupleStruct(ref path, ref opt_children) => {
             visitor.visit_path(path, pattern.id);
             if let Some(ref children) = *opt_children {
                 walk_list!(visitor, visit_pat, children);
             }
         }
+        PatKind::Path(ref path) => {
+            visitor.visit_path(path, pattern.id);
+        }
         PatKind::QPath(ref qself, ref path) => {
             visitor.visit_ty(&qself.ty);
             visitor.visit_path(path, pattern.id)
diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs
index 5935594b67f..0e7d9db37fd 100644
--- a/src/librustc_front/lowering.rs
+++ b/src/librustc_front/lowering.rs
@@ -921,12 +921,12 @@ pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P<hir::Pat> {
             }
             PatKind::Lit(ref e) => hir::PatKind::Lit(lower_expr(lctx, e)),
             PatKind::TupleStruct(ref pth, ref pats) => {
-                hir::PatKind::Enum(lower_path(lctx, pth),
+                hir::PatKind::TupleStruct(lower_path(lctx, pth),
                              pats.as_ref()
                                  .map(|pats| pats.iter().map(|x| lower_pat(lctx, x)).collect()))
             }
             PatKind::Path(ref pth) => {
-                hir::PatKind::Enum(lower_path(lctx, pth), Some(hir::HirVec::new()))
+                hir::PatKind::Path(lower_path(lctx, pth))
             }
             PatKind::QPath(ref qself, ref pth) => {
                 let qself = hir::QSelf {
@@ -1750,7 +1750,11 @@ fn pat_enum(lctx: &LoweringContext,
             path: hir::Path,
             subpats: hir::HirVec<P<hir::Pat>>)
             -> P<hir::Pat> {
-    let pt = hir::PatKind::Enum(path, Some(subpats));
+    let pt = if subpats.is_empty() {
+        hir::PatKind::Path(path)
+    } else {
+        hir::PatKind::TupleStruct(path, Some(subpats))
+    };
     pat(lctx, span, pt)
 }
 
diff --git a/src/librustc_front/print/pprust.rs b/src/librustc_front/print/pprust.rs
index dc4bd8ba474..d837ab0f8f6 100644
--- a/src/librustc_front/print/pprust.rs
+++ b/src/librustc_front/print/pprust.rs
@@ -1748,19 +1748,20 @@ impl<'a> State<'a> {
                     None => (),
                 }
             }
-            PatKind::Enum(ref path, ref args_) => {
+            PatKind::TupleStruct(ref path, ref args_) => {
                 try!(self.print_path(path, true, 0));
                 match *args_ {
                     None => try!(word(&mut self.s, "(..)")),
                     Some(ref args) => {
-                        if !args.is_empty() {
-                            try!(self.popen());
-                            try!(self.commasep(Inconsistent, &args[..], |s, p| s.print_pat(&p)));
-                            try!(self.pclose());
-                        }
+                        try!(self.popen());
+                        try!(self.commasep(Inconsistent, &args[..], |s, p| s.print_pat(&p)));
+                        try!(self.pclose());
                     }
                 }
             }
+            PatKind::Path(ref path) => {
+                try!(self.print_path(path, true, 0));
+            }
             PatKind::QPath(ref qself, ref path) => {
                 try!(self.print_qpath(path, qself, false));
             }
diff --git a/src/librustc_front/util.rs b/src/librustc_front/util.rs
index 12654b2b3d7..8140ea1f167 100644
--- a/src/librustc_front/util.rs
+++ b/src/librustc_front/util.rs
@@ -32,7 +32,7 @@ pub fn walk_pat<F>(pat: &Pat, mut it: F) -> bool
             PatKind::Struct(_, ref fields, _) => {
                 fields.iter().all(|field| walk_pat_(&field.node.pat, it))
             }
-            PatKind::Enum(_, Some(ref s)) | PatKind::Tup(ref s) => {
+            PatKind::TupleStruct(_, Some(ref s)) | PatKind::Tup(ref s) => {
                 s.iter().all(|p| walk_pat_(&p, it))
             }
             PatKind::Box(ref s) | PatKind::Ref(ref s, _) => {
@@ -47,7 +47,8 @@ pub fn walk_pat<F>(pat: &Pat, mut it: F) -> bool
             PatKind::Lit(_) |
             PatKind::Range(_, _) |
             PatKind::Ident(_, _, _) |
-            PatKind::Enum(_, _) |
+            PatKind::TupleStruct(..) |
+            PatKind::Path(..) |
             PatKind::QPath(_, _) => {
                 true
             }
diff --git a/src/librustc_mir/hair/cx/pattern.rs b/src/librustc_mir/hair/cx/pattern.rs
index fc1af0e7af1..c5b34d92466 100644
--- a/src/librustc_mir/hair/cx/pattern.rs
+++ b/src/librustc_mir/hair/cx/pattern.rs
@@ -79,7 +79,7 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
                 PatternKind::Range { lo: lo, hi: hi }
             },
 
-            PatKind::Enum(..) | PatKind::Ident(..) | PatKind::QPath(..)
+            PatKind::Path(..) | PatKind::Ident(..) | PatKind::QPath(..)
                 if pat_is_resolved_const(&self.cx.tcx.def_map.borrow(), pat) =>
             {
                 let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
@@ -179,11 +179,11 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
                 }
             }
 
-            PatKind::Ident(..) => {
+            PatKind::Ident(..) | PatKind::Path(..) => {
                 self.variant_or_leaf(pat, vec![])
             }
 
-            PatKind::Enum(_, ref opt_subpatterns) => {
+            PatKind::TupleStruct(_, ref opt_subpatterns) => {
                 let subpatterns =
                     opt_subpatterns.iter()
                                    .flat_map(|v| v.iter())
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 862ab02ee95..1424616e792 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -932,7 +932,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
 
             // Patterns which bind no fields are allowable (the path is check
             // elsewhere).
-            PatKind::Enum(_, Some(ref fields)) => {
+            PatKind::TupleStruct(_, Some(ref fields)) => {
                 match self.tcx.pat_ty(pattern).sty {
                     ty::TyStruct(def, _) => {
                         for (i, field) in fields.iter().enumerate() {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 2ee62e71fab..22b28865eff 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -2473,7 +2473,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     }
                 }
 
-                PatKind::Enum(ref path, _) => {
+                PatKind::TupleStruct(ref path, _) | PatKind::Path(ref path) => {
                     // This must be an enum variant, struct or const.
                     let resolution = match self.resolve_possibly_assoc_item(pat_id,
                                                                             None,
@@ -2484,13 +2484,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         // qualified paths should be in PatKind::QPath.
                         TypecheckRequired =>
                             self.session.span_bug(path.span,
-                                                  "resolve_possibly_assoc_item claimed
-                                     \
-                                                   that a path in PatKind::Enum requires typecheck
-                                     \
-                                                   to resolve, but qualified paths should be
-                                     \
-                                                   PatKind::QPath"),
+                                                  "resolve_possibly_assoc_item claimed that a path \
+                                                   in PatKind::Path or PatKind::TupleStruct \
+                                                   requires typecheck to resolve, but qualified \
+                                                   paths should be PatKind::QPath"),
                         ResolveAttempt(resolution) => resolution,
                     };
                     if let Some(path_res) = resolution {
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index e81fe08e7b1..c5efc9b7e22 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -665,7 +665,8 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             PatKind::Lit(ref l) => {
                 ConstantValue(ConstantExpr(&l), debug_loc)
             }
-            PatKind::Ident(..) | PatKind::Enum(..) | PatKind::Struct(..) => {
+            PatKind::Ident(..) | PatKind::Path(..) |
+            PatKind::TupleStruct(..) | PatKind::Struct(..) => {
                 // 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 {
@@ -798,16 +799,11 @@ fn any_irrefutable_adt_pat(tcx: &ty::ctxt, m: &[Match], col: usize) -> bool {
         let pat = br.pats[col];
         match pat.node {
             PatKind::Tup(_) => true,
-            PatKind::Struct(..) => {
-                match tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
-                    Some(Def::Variant(..)) => false,
-                    _ => true,
-                }
-            }
-            PatKind::Enum(..) | PatKind::Ident(_, _, None) => {
-                match tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
-                    Some(Def::Struct(..)) => true,
-                    _ => false
+            PatKind::Struct(..) | PatKind::TupleStruct(..) |
+            PatKind::Path(..) | PatKind::Ident(_, _, None) => {
+                match tcx.def_map.borrow().get(&pat.id).unwrap().full_def() {
+                    Def::Struct(..) | Def::TyAlias(..) => true,
+                    _ => false,
                 }
             }
             _ => false
@@ -1849,7 +1845,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 bcx = bind_irrefutable_pat(bcx, &inner_pat, val, cleanup_scope);
             }
         }
-        PatKind::Enum(_, ref sub_pats) => {
+        PatKind::TupleStruct(_, ref sub_pats) => {
             let opt_def = bcx.tcx().def_map.borrow().get(&pat.id).map(|d| d.full_def());
             match opt_def {
                 Some(Def::Variant(enum_id, var_id)) => {
@@ -2013,7 +2009,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                         cleanup_scope)
                 });
         }
-        PatKind::QPath(..) | PatKind::Wild | PatKind::Lit(_) |
+        PatKind::Path(..) | PatKind::QPath(..) | PatKind::Wild | PatKind::Lit(_) |
         PatKind::Range(_, _) => ()
     }
     return bcx;
diff --git a/src/librustc_trans/trans/debuginfo/create_scope_map.rs b/src/librustc_trans/trans/debuginfo/create_scope_map.rs
index 1589cf64865..73fdbd54b29 100644
--- a/src/librustc_trans/trans/debuginfo/create_scope_map.rs
+++ b/src/librustc_trans/trans/debuginfo/create_scope_map.rs
@@ -239,7 +239,7 @@ fn walk_pattern(cx: &CrateContext,
             scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
         }
 
-        PatKind::Enum(_, ref sub_pats_opt) => {
+        PatKind::TupleStruct(_, ref sub_pats_opt) => {
             scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
 
             if let Some(ref sub_pats) = *sub_pats_opt {
@@ -249,7 +249,7 @@ fn walk_pattern(cx: &CrateContext,
             }
         }
 
-        PatKind::QPath(..) => {
+        PatKind::Path(..) | PatKind::QPath(..) => {
             scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
         }
 
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 2803cbe4dd9..bd2c7b39153 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -135,14 +135,8 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
             // subtyping doesn't matter here, as the value is some kind of scalar
             demand::eqtype(fcx, pat.span, expected, lhs_ty);
         }
-        PatKind::Enum(..) | PatKind::Ident(..)
+        PatKind::Path(..) | PatKind::Ident(..)
                 if pat_is_resolved_const(&tcx.def_map.borrow(), pat) => {
-            if let PatKind::Enum(ref path, ref subpats) = pat.node {
-                if !(subpats.is_some() && subpats.as_ref().unwrap().is_empty()) {
-                    bad_struct_kind_err(tcx.sess, pat, path, false);
-                    return;
-                }
-            }
             if let Some(pat_def) = tcx.def_map.borrow().get(&pat.id) {
                 let const_did = pat_def.def_id();
                 let const_scheme = tcx.lookup_item_type(const_did);
@@ -206,10 +200,11 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
             let path = hir_util::ident_to_path(path.span, path.node);
             check_pat_enum(pcx, pat, &path, Some(&[]), expected, false);
         }
-        PatKind::Enum(ref path, ref subpats) => {
-            let subpats = subpats.as_ref().map(|v| &v[..]);
-            let is_tuple_struct_pat = !(subpats.is_some() && subpats.unwrap().is_empty());
-            check_pat_enum(pcx, pat, path, subpats, expected, is_tuple_struct_pat);
+        PatKind::TupleStruct(ref path, ref subpats) => {
+            check_pat_enum(pcx, pat, path, subpats.as_ref().map(|v| &v[..]), expected, true);
+        }
+        PatKind::Path(ref path) => {
+            check_pat_enum(pcx, pat, path, None, expected, false);
         }
         PatKind::QPath(ref qself, ref path) => {
             let self_ty = fcx.to_ty(&qself.ty);
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 772652eace5..7072f1b498b 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2554,7 +2554,7 @@ fn name_from_pat(p: &hir::Pat) -> String {
     match p.node {
         PatKind::Wild => "_".to_string(),
         PatKind::Ident(_, ref p, _) => p.node.to_string(),
-        PatKind::Enum(ref p, _) => path_to_string(p),
+        PatKind::TupleStruct(ref p, _) | PatKind::Path(ref p) => path_to_string(p),
         PatKind::QPath(..) => panic!("tried to get argument name from PatKind::QPath, \
                                 which is not allowed in function arguments"),
         PatKind::Struct(ref name, ref fields, etc) => {
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index cb79c609c1b..23bb6fd141a 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -580,7 +580,7 @@ pub enum PatKind {
     /// An associated const named using the qualified path `<T>::CONST` or
     /// `<T as Trait>::CONST`. Associated consts from inherent impls can be
     /// referred to as simply `T::CONST`, in which case they will end up as
-    /// PatKind::Enum, and the resolver will have to sort that out.
+    /// PatKind::Path, and the resolver will have to sort that out.
     QPath(QSelf, Path),
 
     /// A tuple pattern `(a, b)`