about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2016-03-06 15:54:44 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2016-05-28 00:54:29 +0300
commit216f5fba043ff787ba2dd6bbf01e0e077304adf0 (patch)
tree9b24ca0a92fe4d0629afe3059424b0544b1dfddb
parentab7c35fa0fcd725cdc207487b760d85fd07ecdd7 (diff)
downloadrust-216f5fba043ff787ba2dd6bbf01e0e077304adf0.tar.gz
rust-216f5fba043ff787ba2dd6bbf01e0e077304adf0.zip
Separate bindings from other patterns in HIR
-rw-r--r--src/librustc/cfg/construct.rs4
-rw-r--r--src/librustc/hir/fold.rs4
-rw-r--r--src/librustc/hir/intravisit.rs2
-rw-r--r--src/librustc/hir/lowering.rs20
-rw-r--r--src/librustc/hir/map/collector.rs2
-rw-r--r--src/librustc/hir/map/def_collector.rs2
-rw-r--r--src/librustc/hir/map/mod.rs2
-rw-r--r--src/librustc/hir/mod.rs10
-rw-r--r--src/librustc/hir/pat_util.rs25
-rw-r--r--src/librustc/hir/print.rs4
-rw-r--r--src/librustc/middle/expr_use_visitor.rs25
-rw-r--r--src/librustc/middle/mem_categorization.rs8
-rw-r--r--src/librustc/middle/region.rs12
-rw-r--r--src/librustc/ty/mod.rs2
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs2
-rw-r--r--src/librustc_const_eval/check_match.rs107
-rw-r--r--src/librustc_lint/bad_style.rs18
-rw-r--r--src/librustc_lint/builtin.rs2
-rw-r--r--src/librustc_metadata/encoder.rs2
-rw-r--r--src/librustc_mir/build/mod.rs9
-rw-r--r--src/librustc_mir/hair/cx/pattern.rs10
-rw-r--r--src/librustc_trans/_match.rs101
-rw-r--r--src/librustc_trans/debuginfo/create_scope_map.rs122
-rw-r--r--src/librustc_trans/debuginfo/metadata.rs2
-rw-r--r--src/librustc_typeck/check/_match.rs10
-rw-r--r--src/librustc_typeck/check/mod.rs24
-rw-r--r--src/librustc_typeck/check/regionck.rs2
-rw-r--r--src/librustc_typeck/collect.rs9
-rw-r--r--src/librustdoc/clean/mod.rs2
29 files changed, 237 insertions, 307 deletions
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs
index af47617ea92..61c0f1c1c64 100644
--- a/src/librustc/cfg/construct.rs
+++ b/src/librustc/cfg/construct.rs
@@ -99,7 +99,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
 
     fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex {
         match pat.node {
-            PatKind::Ident(_, _, None) |
+            PatKind::Binding(_, _, None) |
             PatKind::Path(..) |
             PatKind::QPath(..) |
             PatKind::Lit(..) |
@@ -110,7 +110,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
 
             PatKind::Box(ref subpat) |
             PatKind::Ref(ref subpat, _) |
-            PatKind::Ident(_, _, Some(ref subpat)) => {
+            PatKind::Binding(_, _, Some(ref subpat)) => {
                 let subpat_exit = self.pat(&subpat, pred);
                 self.add_ast_node(pat.id, &[subpat_exit])
             }
diff --git a/src/librustc/hir/fold.rs b/src/librustc/hir/fold.rs
index 641fe5f3b47..1e80bc3c54d 100644
--- a/src/librustc/hir/fold.rs
+++ b/src/librustc/hir/fold.rs
@@ -914,8 +914,8 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
             id: folder.new_id(id),
             node: match node {
                 PatKind::Wild => PatKind::Wild,
-                PatKind::Ident(binding_mode, pth1, sub) => {
-                    PatKind::Ident(binding_mode,
+                PatKind::Binding(binding_mode, pth1, sub) => {
+                    PatKind::Binding(binding_mode,
                              Spanned {
                                  span: folder.new_span(pth1.span),
                                  node: folder.fold_name(pth1.node),
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 9b1d2243667..4593f19daad 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -485,7 +485,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
         PatKind::Ref(ref subpattern, _) => {
             visitor.visit_pat(subpattern)
         }
-        PatKind::Ident(_, ref pth1, ref optional_subpattern) => {
+        PatKind::Binding(_, ref pth1, ref optional_subpattern) => {
             visitor.visit_name(pth1.span, pth1.node);
             walk_list!(visitor, visit_pat, optional_subpattern);
         }
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index ea9a76d982a..90dd2dad720 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -866,14 +866,16 @@ impl<'a> LoweringContext<'a> {
                 PatKind::Wild => hir::PatKind::Wild,
                 PatKind::Ident(ref binding_mode, pth1, ref sub) => {
                     self.with_parent_def(p.id, |this| {
-                        let name = match this.resolver.get_resolution(p.id).map(|d| d.full_def()) {
-                            // Only pattern bindings are renamed
-                            None | Some(Def::Local(..)) => this.lower_ident(pth1.node),
-                            _ => pth1.node.name,
-                        };
-                        hir::PatKind::Ident(this.lower_binding_mode(binding_mode),
-                                            respan(pth1.span, name),
-                                            sub.as_ref().map(|x| this.lower_pat(x)))
+                        match this.resolver.get_resolution(p.id).map(|d| d.full_def()) {
+                            // `None` can occur in body-less function signatures
+                            None | Some(Def::Local(..)) => {
+                                hir::PatKind::Binding(this.lower_binding_mode(binding_mode),
+                                                      respan(pth1.span,
+                                                             this.lower_ident(pth1.node)),
+                                                      sub.as_ref().map(|x| this.lower_pat(x)))
+                            }
+                            _ => hir::PatKind::Path(hir::Path::from_name(pth1.span, pth1.node.name))
+                        }
                     })
                 }
                 PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
@@ -1868,7 +1870,7 @@ impl<'a> LoweringContext<'a> {
 
     fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingMode)
                               -> P<hir::Pat> {
-        let pat_ident = hir::PatKind::Ident(bm,
+        let pat_ident = hir::PatKind::Binding(bm,
                                             Spanned {
                                                 span: span,
                                                 node: name,
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index 99e5f32e263..692f56bde28 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -165,7 +165,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
     }
 
     fn visit_pat(&mut self, pat: &'ast Pat) {
-        let node = if let PatKind::Ident(..) = pat.node {
+        let node = if let PatKind::Binding(..) = pat.node {
             NodeLocal(pat)
         } else {
             NodePat(pat)
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index e783d84dc1b..e3b6539b8cc 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -396,7 +396,7 @@ impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> {
     fn visit_pat(&mut self, pat: &'ast hir::Pat) {
         let parent_def = self.parent_def;
 
-        if let hir::PatKind::Ident(_, name, _) = pat.node {
+        if let hir::PatKind::Binding(_, name, _) = pat.node {
             let def = self.create_def(pat.id, DefPathData::Binding(name.node));
             self.parent_def = Some(def);
         }
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 2f310806a74..41b72e569f4 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -561,7 +561,7 @@ impl<'ast> Map<'ast> {
             NodeVariant(v) => v.node.name,
             NodeLifetime(lt) => lt.name,
             NodeTyParam(tp) => tp.name,
-            NodeLocal(&Pat { node: PatKind::Ident(_,l,_), .. }) => l.node,
+            NodeLocal(&Pat { node: PatKind::Binding(_,l,_), .. }) => l.node,
             NodeStructCtor(_) => self.name(self.get_parent(id)),
             _ => bug!("no name for {}", self.node_to_string(id))
         }
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index ea52a393da6..0e89dde70ee 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -466,7 +466,7 @@ impl Pat {
         }
 
         match self.node {
-            PatKind::Ident(_, _, Some(ref p)) => p.walk_(it),
+            PatKind::Binding(_, _, Some(ref p)) => p.walk_(it),
             PatKind::Struct(_, ref fields, _) => {
                 fields.iter().all(|field| field.node.pat.walk_(it))
             }
@@ -484,7 +484,7 @@ impl Pat {
             PatKind::Wild |
             PatKind::Lit(_) |
             PatKind::Range(_, _) |
-            PatKind::Ident(_, _, _) |
+            PatKind::Binding(..) |
             PatKind::Path(..) |
             PatKind::QPath(_, _) => {
                 true
@@ -532,7 +532,7 @@ pub enum PatKind {
     /// which it is. The resolver determines this, and
     /// records this pattern's `NodeId` in an auxiliary
     /// set (of "PatIdents that refer to unit patterns or constants").
-    Ident(BindingMode, Spanned<Name>, Option<P<Pat>>),
+    Binding(BindingMode, Spanned<Name>, Option<P<Pat>>),
 
     /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
     /// The `bool` is `true` in the presence of a `..`.
@@ -1144,7 +1144,7 @@ pub type ExplicitSelf = Spanned<SelfKind>;
 
 impl Arg {
     pub fn to_self(&self) -> Option<ExplicitSelf> {
-        if let PatKind::Ident(BindByValue(mutbl), name, _) = self.pat.node {
+        if let PatKind::Binding(BindByValue(mutbl), name, _) = self.pat.node {
             if name.node.unhygienize() == keywords::SelfValue.name() {
                 return match self.ty.node {
                     TyInfer => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
@@ -1160,7 +1160,7 @@ impl Arg {
     }
 
     pub fn is_self(&self) -> bool {
-        if let PatKind::Ident(_, name, _) = self.pat.node {
+        if let PatKind::Binding(_, name, _) = self.pat.node {
             name.node.unhygienize() == keywords::SelfValue.name()
         } else {
             false
diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs
index 1008ba7a6e6..35a7f7174cb 100644
--- a/src/librustc/hir/pat_util.rs
+++ b/src/librustc/hir/pat_util.rs
@@ -70,7 +70,6 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
         PatKind::Lit(_) | PatKind::Range(_, _) | PatKind::QPath(..) => true,
         PatKind::TupleStruct(..) |
         PatKind::Path(..) |
-        PatKind::Ident(_, _, None) |
         PatKind::Struct(..) => {
             match dm.get(&pat.id).map(|d| d.full_def()) {
                 Some(Def::Variant(..)) => true,
@@ -86,7 +85,6 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool {
     match pat.node {
         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(..)) | Some(Def::TyAlias(..)) => true,
@@ -99,7 +97,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::Path(..) | PatKind::QPath(..) => {
+        PatKind::Path(..) | PatKind::QPath(..) => {
             match dm.get(&pat.id).map(|d| d.full_def()) {
                 Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true,
                 _ => false
@@ -113,7 +111,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::Path(..) | PatKind::QPath(..) => {
+        PatKind::Path(..) | PatKind::QPath(..) => {
             match dm.get(&pat.id)
                     .and_then(|d| if d.depth == 0 { Some(d.base_def) }
                                   else { None } ) {
@@ -125,32 +123,28 @@ pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool {
     }
 }
 
-pub fn pat_is_binding(dm: &DefMap, pat: &hir::Pat) -> bool {
+pub fn pat_is_binding(_: &DefMap, pat: &hir::Pat) -> bool {
     match pat.node {
-        PatKind::Ident(..) => {
-            !pat_is_variant_or_struct(dm, pat) &&
-            !pat_is_const(dm, pat)
-        }
+        PatKind::Binding(..) => true,
         _ => false
     }
 }
 
-pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool {
+pub fn pat_is_binding_or_wild(_: &DefMap, pat: &hir::Pat) -> bool {
     match pat.node {
-        PatKind::Ident(..) => pat_is_binding(dm, pat),
-        PatKind::Wild => true,
+        PatKind::Binding(..) | PatKind::Wild => true,
         _ => false
     }
 }
 
 /// Call `it` on every "binding" in a pattern, e.g., on `a` in
 /// `match foo() { Some(a) => (), None => () }`
-pub fn pat_bindings<I>(dm: &RefCell<DefMap>, pat: &hir::Pat, mut it: I) where
+pub fn pat_bindings<I>(_: &RefCell<DefMap>, pat: &hir::Pat, mut it: I) where
     I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned<ast::Name>),
 {
     pat.walk(|p| {
         match p.node {
-          PatKind::Ident(binding_mode, ref pth, _) if pat_is_binding(&dm.borrow(), p) => {
+          PatKind::Binding(binding_mode, ref pth, _) => {
             it(binding_mode, p.id, p.span, &respan(pth.span, pth.node));
           }
           _ => {}
@@ -221,7 +215,7 @@ pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool {
 
 pub fn simple_name<'a>(pat: &'a hir::Pat) -> Option<ast::Name> {
     match pat.node {
-        PatKind::Ident(hir::BindByValue(_), ref path1, None) => {
+        PatKind::Binding(hir::BindByValue(..), ref path1, None) => {
             Some(path1.node)
         }
         _ => {
@@ -241,7 +235,6 @@ pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<DefId> {
         match p.node {
             PatKind::TupleStruct(..) |
             PatKind::Path(..) |
-            PatKind::Ident(_, _, None) |
             PatKind::Struct(..) => {
                 match dm.get(&p.id) {
                     Some(&PathResolution { base_def: Def::Variant(_, id), .. }) => {
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index a9ed83d9dc3..ceaf348117e 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -1716,7 +1716,7 @@ impl<'a> State<'a> {
         // is that it doesn't matter
         match pat.node {
             PatKind::Wild => word(&mut self.s, "_")?,
-            PatKind::Ident(binding_mode, ref path1, ref sub) => {
+            PatKind::Binding(binding_mode, ref path1, ref sub) => {
                 match binding_mode {
                     hir::BindByRef(mutbl) => {
                         self.word_nbsp("ref")?;
@@ -2170,7 +2170,7 @@ impl<'a> State<'a> {
                 if let Some(eself) = input.to_self() {
                     self.print_explicit_self(&eself)?;
                 } else {
-                    let invalid = if let PatKind::Ident(_, name, _) = input.pat.node {
+                    let invalid = if let PatKind::Binding(_, name, _) = input.pat.node {
                         name.node == keywords::Invalid.name()
                     } else {
                         false
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index b0add5a23dc..12517d927de 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -935,9 +935,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
             let def_map = &self.tcx().def_map;
             if pat_util::pat_is_binding(&def_map.borrow(), pat) {
                 match pat.node {
-                    PatKind::Ident(hir::BindByRef(_), _, _) =>
+                    PatKind::Binding(hir::BindByRef(_), _, _) =>
                         mode.lub(BorrowingMatch),
-                    PatKind::Ident(hir::BindByValue(_), _, _) => {
+                    PatKind::Binding(hir::BindByValue(_), _, _) => {
                         match copy_or_move(self.mc.infcx, &cmt_pat, PatBindingMove) {
                             Copy => mode.lub(CopyingMatch),
                             Move(_) => mode.lub(MovingMatch),
@@ -989,14 +989,14 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
 
                 // It is also a borrow or copy/move of the value being matched.
                 match pat.node {
-                    PatKind::Ident(hir::BindByRef(m), _, _) => {
+                    PatKind::Binding(hir::BindByRef(m), _, _) => {
                         if let ty::TyRef(&r, _) = pat_ty.sty {
                             let bk = ty::BorrowKind::from_mutbl(m);
                             delegate.borrow(pat.id, pat.span, cmt_pat,
                                             r, bk, RefBinding);
                         }
                     }
-                    PatKind::Ident(hir::BindByValue(_), _, _) => {
+                    PatKind::Binding(hir::BindByValue(_), _, _) => {
                         let mode = copy_or_move(infcx, &cmt_pat, PatBindingMove);
                         debug!("walk_pat binding consuming pat");
                         delegate.consume_pat(pat, cmt_pat, mode);
@@ -1057,8 +1057,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
             let tcx = infcx.tcx;
 
             match pat.node {
-                PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::QPath(..) |
-                PatKind::Ident(_, _, None) | PatKind::Struct(..) => {
+                PatKind::Struct(..) | PatKind::TupleStruct(..) |
+                PatKind::Path(..) | PatKind::QPath(..) => {
                     match def_map.get(&pat.id).map(|d| d.full_def()) {
                         None => {
                             // no definition found: pat is not a
@@ -1094,8 +1094,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
                         }
 
                         Some(Def::Const(..)) |
-                        Some(Def::AssociatedConst(..)) |
-                        Some(Def::Local(..)) => {
+                        Some(Def::AssociatedConst(..)) => {
                             // This is a leaf (i.e. identifier binding
                             // or constant value to match); thus no
                             // `matched_pat` call.
@@ -1121,16 +1120,10 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
                     }
                 }
 
-                PatKind::Ident(_, _, Some(_)) => {
-                    // Do nothing; this is a binding (not an enum
-                    // variant or struct), and the cat_pattern call
-                    // will visit the substructure recursively.
-                }
-
                 PatKind::Wild | PatKind::Tuple(..) | PatKind::Box(..) |
                 PatKind::Ref(..) | PatKind::Lit(..) | PatKind::Range(..) |
-                PatKind::Vec(..) => {
-                    // Similarly, each of these cases does not
+                PatKind::Vec(..) | PatKind::Binding(..) => {
+                    // Each of these cases does not
                     // correspond to an enum variant or struct, so we
                     // do not do any `matched_pat` calls for these
                     // cases either.
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index e933b22f607..31e3db51f55 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -306,7 +306,7 @@ impl MutabilityCategory {
     fn from_local(tcx: TyCtxt, id: ast::NodeId) -> MutabilityCategory {
         let ret = match tcx.map.get(id) {
             ast_map::NodeLocal(p) => match p.node {
-                PatKind::Ident(bind_mode, _, _) => {
+                PatKind::Binding(bind_mode, _, _) => {
                     if bind_mode == hir::BindByValue(hir::MutMutable) {
                         McDeclared
                     } else {
@@ -398,7 +398,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         // *being borrowed* is.  But ideally we would put in a more
         // fundamental fix to this conflated use of the node id.
         let ret_ty = match pat.node {
-            PatKind::Ident(hir::BindByRef(_), _, _) => {
+            PatKind::Binding(hir::BindByRef(_), _, _) => {
                 // a bind-by-ref means that the base_ty will be the type of the ident itself,
                 // but what we want here is the type of the underlying value being borrowed.
                 // So peel off one-level, turning the &T into T.
@@ -1276,11 +1276,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
             }
           }
 
-          PatKind::Path(..) | PatKind::QPath(..) | PatKind::Ident(_, _, None) => {
+          PatKind::Path(..) | PatKind::QPath(..) | PatKind::Binding(_, _, None) => {
               // Lone constant, or unit variant or identifier: ignore
           }
 
-          PatKind::Ident(_, _, Some(ref subpat)) => {
+          PatKind::Binding(_, _, Some(ref subpat)) => {
               self.cat_pattern_(cmt, &subpat, op)?;
           }
 
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 6b2c2dfcd72..3efc584ae2b 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -752,13 +752,9 @@ fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &hir::Arm) {
 fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &hir::Pat) {
     visitor.new_node_extent(pat.id);
 
-    // If this is a binding (or maybe a binding, I'm too lazy to check
-    // the def map) then record the lifetime of that binding.
-    match pat.node {
-        PatKind::Ident(..) => {
-            record_var_lifetime(visitor, pat.id, pat.span);
-        }
-        _ => { }
+    // If this is a binding then record the lifetime of that binding.
+    if let PatKind::Binding(..) = pat.node {
+        record_var_lifetime(visitor, pat.id, pat.span);
     }
 
     intravisit::walk_pat(visitor, pat);
@@ -958,7 +954,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) {
     ///        | box P&
     fn is_binding_pat(pat: &hir::Pat) -> bool {
         match pat.node {
-            PatKind::Ident(hir::BindByRef(_), _, _) => true,
+            PatKind::Binding(hir::BindByRef(_), _, _) => true,
 
             PatKind::Struct(_, ref field_pats, _) => {
                 field_pats.iter().any(|fp| is_binding_pat(&fp.node.pat))
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index dfb4ec73924..24f0671ce61 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -2216,7 +2216,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         match self.map.find(id) {
             Some(ast_map::NodeLocal(pat)) => {
                 match pat.node {
-                    PatKind::Ident(_, ref path1, _) => path1.node.as_str(),
+                    PatKind::Binding(_, ref path1, _) => path1.node.as_str(),
                     _ => {
                         bug!("Variable id {} maps to {:?}, not local", id, pat);
                     },
diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
index 83322215e30..8682661d35a 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
@@ -98,7 +98,7 @@ pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                                       move_pat: &hir::Pat,
                                       cmt: mc::cmt<'tcx>) {
     let pat_span_path_opt = match move_pat.node {
-        PatKind::Ident(_, ref path1, _) => {
+        PatKind::Binding(_, ref path1, _) => {
             Some(MoveSpanAndPath{span: move_pat.span,
                                  name: path1.node})
         },
diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs
index 16b61534ee9..46e05d218fc 100644
--- a/src/librustc_const_eval/check_match.rs
+++ b/src/librustc_const_eval/check_match.rs
@@ -239,31 +239,28 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &hir::Expr) {
 
 fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) {
     pat.walk(|p| {
-        match p.node {
-            PatKind::Ident(hir::BindByValue(hir::MutImmutable), name, None) => {
-                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(Def::Local(..)) = def {
-                        if edef.variants.iter().any(|variant|
-                            variant.name == name.node.unhygienize()
-                                && variant.kind() == VariantKind::Unit
-                        ) {
-                            let ty_path = cx.tcx.item_path_str(edef.did);
-                            let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170,
-                                "pattern binding `{}` is named the same as one \
-                                 of the variants of the type `{}`",
-                                name.node, ty_path);
-                            help!(err,
-                                "if you meant to match on a variant, \
-                                 consider making the path in the pattern qualified: `{}::{}`",
-                                ty_path, name.node);
-                            err.emit();
-                        }
+        if let PatKind::Binding(hir::BindByValue(hir::MutImmutable), name, None) = p.node {
+            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(Def::Local(..)) = def {
+                    if edef.variants.iter().any(|variant|
+                        variant.name == name.node.unhygienize()
+                            && variant.kind() == VariantKind::Unit
+                    ) {
+                        let ty_path = cx.tcx.item_path_str(edef.did);
+                        let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170,
+                            "pattern binding `{}` is named the same as one \
+                             of the variants of the type `{}`",
+                            name.node, ty_path);
+                        help!(err,
+                            "if you meant to match on a variant, \
+                             consider making the path in the pattern qualified: `{}::{}`",
+                            ty_path, name.node);
+                        err.emit();
                     }
                 }
             }
-            _ => ()
         }
         true
     });
@@ -371,8 +368,8 @@ fn check_arms(cx: &MatchCheckCtxt,
 /// Checks for common cases of "catchall" patterns that may not be intended as such.
 fn pat_is_catchall(dm: &DefMap, p: &Pat) -> bool {
     match p.node {
-        PatKind::Ident(_, _, None) => pat_is_binding(dm, p),
-        PatKind::Ident(_, _, Some(ref s)) => pat_is_catchall(dm, &s),
+        PatKind::Binding(_, _, None) => true,
+        PatKind::Binding(_, _, Some(ref s)) => pat_is_catchall(dm, &s),
         PatKind::Ref(ref s, _) => pat_is_catchall(dm, &s),
         PatKind::Tuple(ref v, _) => v.iter().all(|p| pat_is_catchall(dm, &p)),
         _ => false
@@ -381,7 +378,7 @@ fn pat_is_catchall(dm: &DefMap, p: &Pat) -> bool {
 
 fn raw_pat(p: &Pat) -> &Pat {
     match p.node {
-        PatKind::Ident(_, _, Some(ref s)) => raw_pat(&s),
+        PatKind::Binding(_, _, Some(ref s)) => raw_pat(&s),
         _ => p
     }
 }
@@ -487,11 +484,10 @@ impl<'map> 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::Path(..) | PatKind::QPath(..) => {
+            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)) |
-                    Some(Def::Const(did)) => {
+                    Some(Def::AssociatedConst(did)) | Some(Def::Const(did)) => {
                         let substs = Some(self.tcx.node_id_item_substs(pat.id).substs);
                         if let Some((const_expr, _)) = lookup_const_by_id(self.tcx, did, substs) {
                             match const_expr_to_pat(self.tcx, const_expr, pat.id, pat.span) {
@@ -717,7 +713,7 @@ fn is_useful(cx: &MatchCheckCtxt,
         let left_ty = cx.tcx.pat_ty(&real_pat);
 
         match real_pat.node {
-            PatKind::Ident(hir::BindByRef(..), _, _) => {
+            PatKind::Binding(hir::BindByRef(..), _, _) => {
                 left_ty.builtin_deref(false, NoPreference).unwrap().ty
             }
             _ => left_ty,
@@ -804,38 +800,37 @@ 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::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::Ident(..) =>
+        PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) =>
             match cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def() {
                 Def::Const(..) | Def::AssociatedConst(..) =>
                     span_bug!(pat.span, "const pattern should've \
                                          been rewritten"),
                 Def::Struct(..) | Def::TyAlias(..) => vec![Single],
                 Def::Variant(_, id) => vec![Variant(id)],
-                Def::Local(..) => vec![],
                 def => span_bug!(pat.span, "pat_constructors: unexpected \
                                             definition {:?}", def),
             },
         PatKind::QPath(..) =>
             span_bug!(pat.span, "const pattern should've been rewritten"),
         PatKind::Lit(ref expr) =>
-            vec!(ConstantValue(eval_const_expr(cx.tcx, &expr))),
+            vec![ConstantValue(eval_const_expr(cx.tcx, &expr))],
         PatKind::Range(ref lo, ref hi) =>
-            vec!(ConstantRange(eval_const_expr(cx.tcx, &lo), eval_const_expr(cx.tcx, &hi))),
+            vec![ConstantRange(eval_const_expr(cx.tcx, &lo), eval_const_expr(cx.tcx, &hi))],
         PatKind::Vec(ref before, ref slice, ref after) =>
             match left_ty.sty {
-                ty::TyArray(_, _) => vec!(Single),
+                ty::TyArray(_, _) => vec![Single],
                 _                      => if slice.is_some() {
                     (before.len() + after.len()..max_slice_length+1)
                         .map(|length| Slice(length))
                         .collect()
                 } else {
-                    vec!(Slice(before.len() + after.len()))
+                    vec![Slice(before.len() + after.len())]
                 }
             },
         PatKind::Box(..) | PatKind::Tuple(..) | PatKind::Ref(..) =>
-            vec!(Single),
-        PatKind::Wild =>
-            vec!(),
+            vec![Single],
+        PatKind::Binding(..) | PatKind::Wild =>
+            vec![],
     }
 }
 
@@ -897,10 +892,10 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
         id: pat_id, ref node, span: pat_span
     } = raw_pat(r[col]);
     let head: Option<Vec<&Pat>> = match *node {
-        PatKind::Wild =>
+        PatKind::Binding(..) | PatKind::Wild =>
             Some(vec![DUMMY_WILD_PAT; arity]),
 
-        PatKind::Path(..) | PatKind::Ident(..) => {
+        PatKind::Path(..) => {
             let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
             match def {
                 Def::Const(..) | Def::AssociatedConst(..) =>
@@ -908,7 +903,6 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
                                          been rewritten"),
                 Def::Variant(_, id) if *constructor != Variant(id) => None,
                 Def::Variant(..) | Def::Struct(..) => Some(Vec::new()),
-                Def::Local(..) => Some(vec![DUMMY_WILD_PAT; arity]),
                 _ => span_bug!(pat_span, "specialize: unexpected \
                                           definition {:?}", def),
             }
@@ -1128,28 +1122,15 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
 
     for pat in pats {
         pat.walk(|p| {
-            if pat_is_binding(&def_map.borrow(), &p) {
-                match p.node {
-                    PatKind::Ident(hir::BindByValue(_), _, ref sub) => {
-                        let pat_ty = tcx.node_id_to_type(p.id);
-                        //FIXME: (@jroesch) this code should be floated up as well
-                        cx.tcx.infer_ctxt(None, Some(cx.param_env.clone()),
-                                          ProjectionMode::AnyFinal).enter(|infcx| {
-                            if infcx.type_moves_by_default(pat_ty, pat.span) {
-                                check_move(p, sub.as_ref().map(|p| &**p));
-                            }
-                        });
+            if let PatKind::Binding(hir::BindByValue(..), _, ref sub) = p.node {
+                let pat_ty = tcx.node_id_to_type(p.id);
+                //FIXME: (@jroesch) this code should be floated up as well
+                cx.tcx.infer_ctxt(None, Some(cx.param_env.clone()),
+                                  ProjectionMode::AnyFinal).enter(|infcx| {
+                    if infcx.type_moves_by_default(pat_ty, pat.span) {
+                        check_move(p, sub.as_ref().map(|p| &**p));
                     }
-                    PatKind::Ident(hir::BindByRef(_), _, _) => {
-                    }
-                    _ => {
-                        span_bug!(
-                            p.span,
-                            "binding pattern {} is not an identifier: {:?}",
-                            p.id,
-                            p.node);
-                    }
-                }
+                });
             }
             true
         });
@@ -1225,7 +1206,7 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for AtBindingPatternVisitor<'a, 'b, 'tcx> {
         }
 
         match pat.node {
-            PatKind::Ident(_, _, Some(_)) => {
+            PatKind::Binding(_, _, Some(_)) => {
                 let bindings_were_allowed = self.bindings_allowed;
                 self.bindings_allowed = false;
                 intravisit::walk_pat(self, pat);
diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs
index 27a6e433c73..4c4dea406ba 100644
--- a/src/librustc_lint/bad_style.rs
+++ b/src/librustc_lint/bad_style.rs
@@ -274,9 +274,9 @@ impl LateLintPass for NonSnakeCase {
     }
 
     fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
-        if let &PatKind::Ident(_, ref path1, _) = &p.node {
-            let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
-            if let Some(Def::Local(..)) = def {
+        if let &PatKind::Binding(_, ref path1, _) = &p.node {
+            // Exclude parameter names from foreign functions (they have no `Def`)
+            if cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def()).is_some() {
                 self.check_snake_case(cx, "variable", &path1.node.as_str(), Some(p.span));
             }
         }
@@ -360,12 +360,14 @@ 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())) {
-            (&PatKind::Ident(_, ref path1, _), Some(Def::Const(..))) => {
-                NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
-                                                      path1.node, p.span);
+        if let PatKind::Path(ref path) = p.node {
+            if !path.global && path.segments.len() == 1 && path.segments[0].parameters.is_empty() {
+                if let Some(Def::Const(..)) = cx.tcx.def_map.borrow().get(&p.id)
+                                                                     .map(|d| d.full_def()) {
+                    NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
+                                                          path.segments[0].name, path.span);
+                }
             }
-            _ => {}
         }
     }
 }
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 49b59aea46e..3005f564ff4 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -171,7 +171,7 @@ impl LateLintPass for NonShorthandFieldPatterns {
                 }
             });
             for fieldpat in field_pats {
-                if let PatKind::Ident(_, ident, None) = fieldpat.node.pat.node {
+                if let PatKind::Binding(_, ident, None) = fieldpat.node.pat.node {
                     if ident.node.unhygienize() == fieldpat.node.name {
                         cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span,
                                      &format!("the `{}:` in this pattern is redundant and can \
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 2bc953039ad..e0c35a6fba8 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -744,7 +744,7 @@ fn encode_method_argument_names(rbml_w: &mut Encoder,
     rbml_w.start_tag(tag_method_argument_names);
     for arg in &decl.inputs {
         let tag = tag_method_argument_name;
-        if let PatKind::Ident(_, ref path1, _) = arg.pat.node {
+        if let PatKind::Binding(_, ref path1, _) = arg.pat.node {
             let name = path1.node.as_str();
             rbml_w.wr_tagged_bytes(tag, name.as_bytes());
         } else {
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index d75cf3b7587..9d7818a9ba4 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -14,7 +14,6 @@ use rustc::ty::{self, Ty};
 use rustc::mir::repr::*;
 use rustc_data_structures::fnv::FnvHashMap;
 use rustc::hir;
-use rustc::hir::pat_util::pat_is_binding;
 use std::ops::{Index, IndexMut};
 use syntax::abi::Abi;
 use syntax::ast;
@@ -221,7 +220,7 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
                 by_ref: by_ref
             };
             if let Some(hir::map::NodeLocal(pat)) = tcx.map.find(fv.def.var_id()) {
-                if let hir::PatKind::Ident(_, ref ident, _) = pat.node {
+                if let hir::PatKind::Binding(_, ref ident, _) = pat.node {
                     decl.debug_name = ident.node;
                 }
             }
@@ -333,10 +332,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
 
             let mut name = keywords::Invalid.name();
             if let Some(pat) = pattern {
-                if let hir::PatKind::Ident(_, ref ident, _) = pat.node {
-                    if pat_is_binding(&self.hir.tcx().def_map.borrow(), pat) {
-                        name = ident.node;
-                    }
+                if let hir::PatKind::Binding(_, ref ident, _) = pat.node {
+                    name = ident.node;
                 }
             }
 
diff --git a/src/librustc_mir/hair/cx/pattern.rs b/src/librustc_mir/hair/cx/pattern.rs
index b9ba860e8d0..acde81979f9 100644
--- a/src/librustc_mir/hair/cx/pattern.rs
+++ b/src/librustc_mir/hair/cx/pattern.rs
@@ -13,7 +13,7 @@ use hair::cx::Cx;
 use rustc_data_structures::fnv::FnvHashMap;
 use rustc_const_eval as const_eval;
 use rustc::hir::def::Def;
-use rustc::hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const, pat_is_binding};
+use rustc::hir::pat_util::{EnumerateAndAdjustIterator, pat_is_resolved_const};
 use rustc::ty::{self, Ty};
 use rustc::mir::repr::*;
 use rustc::hir::{self, PatKind};
@@ -81,7 +81,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
                 PatternKind::Range { lo: lo, hi: hi }
             },
 
-            PatKind::Path(..) | PatKind::Ident(..) | PatKind::QPath(..)
+            PatKind::Path(..) | 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();
@@ -167,9 +167,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
                 }
             }
 
-            PatKind::Ident(bm, ref ident, ref sub)
-                if pat_is_binding(&self.cx.tcx.def_map.borrow(), pat) =>
-            {
+            PatKind::Binding(bm, ref ident, ref sub) => {
                 let id = match self.binding_map {
                     None => pat.id,
                     Some(ref map) => map[&ident.node],
@@ -210,7 +208,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
                 }
             }
 
-            PatKind::Ident(..) | PatKind::Path(..) => {
+            PatKind::Path(..) => {
                 self.variant_or_leaf(pat, vec![])
             }
 
diff --git a/src/librustc_trans/_match.rs b/src/librustc_trans/_match.rs
index 4b22e410f4c..bdde5ce1617 100644
--- a/src/librustc_trans/_match.rs
+++ b/src/librustc_trans/_match.rs
@@ -424,12 +424,11 @@ impl<'a, 'p, 'blk, 'tcx> fmt::Debug for Match<'a, 'p, 'blk, 'tcx> {
 
 fn has_nested_bindings(m: &[Match], col: usize) -> bool {
     for br in m {
-        match br.pats[col].node {
-            PatKind::Ident(_, _, Some(_)) => return true,
-            _ => ()
+        if let PatKind::Binding(_, _, Some(..)) = br.pats[col].node {
+            return true
         }
     }
-    return false;
+    false
 }
 
 // As noted in `fn match_datum`, we should eventually pass around a
@@ -481,7 +480,7 @@ fn expand_nested_bindings<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         let mut pat = br.pats[col];
         loop {
             pat = match pat.node {
-                PatKind::Ident(_, ref path, Some(ref inner)) => {
+                PatKind::Binding(_, ref path, Some(ref inner)) => {
                     bound_ptrs.push((path.node, val.val));
                     &inner
                 },
@@ -501,7 +500,6 @@ fn expand_nested_bindings<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 }
 
 fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
-                                          dm: &RefCell<DefMap>,
                                           m: &[Match<'a, 'p, 'blk, 'tcx>],
                                           col: usize,
                                           val: MatchInput,
@@ -518,13 +516,11 @@ fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
             let this = br.pats[col];
             let mut bound_ptrs = br.bound_ptrs.clone();
             match this.node {
-                PatKind::Ident(_, ref path, None) => {
-                    if pat_is_binding(&dm.borrow(), &this) {
-                        bound_ptrs.push((path.node, val.val));
-                    }
+                PatKind::Binding(_, ref path, None) => {
+                    bound_ptrs.push((path.node, val.val));
                 }
                 PatKind::Vec(ref before, Some(ref slice), ref after) => {
-                    if let PatKind::Ident(_, ref path, None) = slice.node {
+                    if let PatKind::Binding(_, ref path, None) = slice.node {
                         let subslice_val = bind_subslice_pat(
                             bcx, this.id, val,
                             before.len(), after.len());
@@ -554,7 +550,7 @@ fn enter_default<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let _indenter = indenter();
 
     // Collect all of the matches that can match against anything.
-    enter_match(bcx, dm, m, col, val, |pats| {
+    enter_match(bcx, m, col, val, |pats| {
         if pat_is_binding_or_wild(&dm.borrow(), &pats[col]) {
             let mut r = pats[..col].to_vec();
             r.extend_from_slice(&pats[col + 1..]);
@@ -596,7 +592,6 @@ fn enter_default<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 fn enter_opt<'a, 'p, 'blk, 'tcx>(
              bcx: Block<'blk, 'tcx>,
              _: ast::NodeId,
-             dm: &RefCell<DefMap>,
              m: &[Match<'a, 'p, 'blk, 'tcx>],
              opt: &Opt,
              col: usize,
@@ -628,7 +623,7 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>(
         tcx: bcx.tcx(),
         param_env: param_env,
     };
-    enter_match(bcx, dm, m, col, val, |pats|
+    enter_match(bcx, m, col, val, |pats|
         check_match::specialize(&mcx, &pats[..], &ctor, col, variant_size)
     )
 }
@@ -659,9 +654,7 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             PatKind::Lit(ref l) => {
                 ConstantValue(ConstantExpr(&l), debug_loc)
             }
-            PatKind::Ident(..) | PatKind::Path(..) |
-            PatKind::TupleStruct(..) | PatKind::Struct(..) => {
-                // This is either an enum variant or a variable binding.
+            PatKind::Path(..) | PatKind::TupleStruct(..) | PatKind::Struct(..) => {
                 let opt_def = tcx.def_map.borrow().get(&cur.id).map(|d| d.full_def());
                 match opt_def {
                     Some(Def::Variant(enum_id, var_id)) => {
@@ -793,8 +786,7 @@ fn any_irrefutable_adt_pat(tcx: TyCtxt, m: &[Match], col: usize) -> bool {
         let pat = br.pats[col];
         match pat.node {
             PatKind::Tuple(..) => true,
-            PatKind::Struct(..) | PatKind::TupleStruct(..) |
-            PatKind::Path(..) | PatKind::Ident(_, _, None) => {
+            PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) => {
                 match tcx.def_map.borrow().get(&pat.id).unwrap().full_def() {
                     Def::Struct(..) | Def::TyAlias(..) => true,
                     _ => false,
@@ -839,7 +831,7 @@ impl FailureHandler {
 fn pick_column_to_specialize(def_map: &RefCell<DefMap>, m: &[Match]) -> Option<usize> {
     fn pat_score(def_map: &RefCell<DefMap>, pat: &hir::Pat) -> usize {
         match pat.node {
-            PatKind::Ident(_, _, Some(ref inner)) => pat_score(def_map, &inner),
+            PatKind::Binding(_, _, Some(ref inner)) => pat_score(def_map, &inner),
             _ if pat_is_refutable(&def_map.borrow(), pat) => 1,
             _ => 0
         }
@@ -1226,7 +1218,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     };
     match adt_vals {
         Some(field_vals) => {
-            let pats = enter_match(bcx, dm, m, col, val, |pats|
+            let pats = enter_match(bcx, m, col, val, |pats|
                 check_match::specialize(&mcx, pats,
                                         &Constructor::Single, col,
                                         field_vals.len())
@@ -1391,7 +1383,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             }
             ConstantValue(..) | ConstantRange(..) => ()
         }
-        let opt_ms = enter_opt(opt_cx, pat_id, dm, m, opt, col, size, val);
+        let opt_ms = enter_opt(opt_cx, pat_id, m, opt, col, size, val);
         let mut opt_vals: Vec<_> = unpacked.into_iter()
             .map(|v|MatchInput::from_val(v))
             .collect();
@@ -1796,38 +1788,35 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let tcx = bcx.tcx();
     let ccx = bcx.ccx();
     match pat.node {
-        PatKind::Ident(pat_binding_mode, ref path1, ref inner) => {
-            if pat_is_binding(&tcx.def_map.borrow(), &pat) {
-                // Allocate the stack slot where the value of this
-                // binding will live and place it into the appropriate
-                // map.
-                bcx = mk_binding_alloca(
-                    bcx, pat.id, path1.node, cleanup_scope, (),
-                    "_match::bind_irrefutable_pat",
-                    |(), bcx, Datum { val: llval, ty, kind: _ }| {
-                        match pat_binding_mode {
-                            hir::BindByValue(_) => {
-                                // By value binding: move the value that `val`
-                                // points at into the binding's stack slot.
-                                let d = val.to_datum(ty);
-                                d.store_to(bcx, llval)
-                            }
+        PatKind::Binding(pat_binding_mode, ref path1, ref inner) => {
+            // Allocate the stack slot where the value of this
+            // binding will live and place it into the appropriate
+            // map.
+            bcx = mk_binding_alloca(bcx, pat.id, path1.node, cleanup_scope, (),
+                                    "_match::bind_irrefutable_pat",
+                                    |(), bcx, Datum { val: llval, ty, kind: _ }| {
+                match pat_binding_mode {
+                    hir::BindByValue(_) => {
+                        // By value binding: move the value that `val`
+                        // points at into the binding's stack slot.
+                        let d = val.to_datum(ty);
+                        d.store_to(bcx, llval)
+                    }
 
-                            hir::BindByRef(_) => {
-                                // By ref binding: the value of the variable
-                                // is the pointer `val` itself or fat pointer referenced by `val`
-                                if type_is_fat_ptr(bcx.tcx(), ty) {
-                                    expr::copy_fat_ptr(bcx, val.val, llval);
-                                }
-                                else {
-                                    Store(bcx, val.val, llval);
-                                }
-
-                                bcx
-                            }
+                    hir::BindByRef(_) => {
+                        // By ref binding: the value of the variable
+                        // is the pointer `val` itself or fat pointer referenced by `val`
+                        if type_is_fat_ptr(bcx.tcx(), ty) {
+                            expr::copy_fat_ptr(bcx, val.val, llval);
                         }
-                    });
-            }
+                        else {
+                            Store(bcx, val.val, llval);
+                        }
+
+                        bcx
+                    }
+                }
+            });
 
             if let Some(ref inner_pat) = *inner {
                 bcx = bind_irrefutable_pat(bcx, &inner_pat, val, cleanup_scope);
@@ -1941,7 +1930,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let val = if type_is_fat_ptr(tcx, pat_ty) {
                 // We need to check for this, as the pattern could be binding
                 // a fat pointer by-value.
-                if let PatKind::Ident(hir::BindByRef(_),_,_) = inner.node {
+                if let PatKind::Binding(hir::BindByRef(..),_,_) = inner.node {
                     val.val
                 } else {
                     Load(bcx, val.val)
@@ -1960,7 +1949,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let val = if type_is_fat_ptr(tcx, pat_ty) {
                 // We need to check for this, as the pattern could be binding
                 // a fat pointer by-value.
-                if let PatKind::Ident(hir::BindByRef(_),_,_) = inner.node {
+                if let PatKind::Binding(hir::BindByRef(..),_,_) = inner.node {
                     val.val
                 } else {
                     Load(bcx, val.val)
@@ -2001,8 +1990,8 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                         cleanup_scope)
                 });
         }
-        PatKind::Path(..) | PatKind::QPath(..) | PatKind::Wild | PatKind::Lit(_) |
-        PatKind::Range(_, _) => ()
+        PatKind::Path(..) | PatKind::QPath(..) | PatKind::Wild |
+        PatKind::Lit(..) | PatKind::Range(..) => ()
     }
     return bcx;
 }
diff --git a/src/librustc_trans/debuginfo/create_scope_map.rs b/src/librustc_trans/debuginfo/create_scope_map.rs
index aec43e69e51..66409a4c481 100644
--- a/src/librustc_trans/debuginfo/create_scope_map.rs
+++ b/src/librustc_trans/debuginfo/create_scope_map.rs
@@ -235,76 +235,66 @@ fn walk_pattern(cx: &CrateContext,
                 pat: &hir::Pat,
                 scope_stack: &mut Vec<ScopeStackEntry> ,
                 scope_map: &mut NodeMap<DIScope>) {
-
-    let def_map = &cx.tcx().def_map;
-
     // Unfortunately, we cannot just use pat_util::pat_bindings() or
     // ast_util::walk_pat() here because we have to visit *all* nodes in
     // order to put them into the scope map. The above functions don't do that.
     match pat.node {
-        PatKind::Ident(_, ref path1, ref sub_pat_opt) => {
-
-            // Check if this is a binding. If so we need to put it on the
-            // scope stack and maybe introduce an artificial scope
-            if pat_util::pat_is_binding(&def_map.borrow(), &pat) {
-
-                let name = path1.node.unhygienize();
-
-                // LLVM does not properly generate 'DW_AT_start_scope' fields
-                // for variable DIEs. For this reason we have to introduce
-                // an artificial scope at bindings whenever a variable with
-                // the same name is declared in *any* parent scope.
-                //
-                // Otherwise the following error occurs:
-                //
-                // let x = 10;
-                //
-                // do_something(); // 'gdb print x' correctly prints 10
-                //
-                // {
-                //     do_something(); // 'gdb print x' prints 0, because it
-                //                     // already reads the uninitialized 'x'
-                //                     // from the next line...
-                //     let x = 100;
-                //     do_something(); // 'gdb print x' correctly prints 100
-                // }
-
-                // Is there already a binding with that name?
-                // N.B.: this comparison must be UNhygienic... because
-                // gdb knows nothing about the context, so any two
-                // variables with the same name will cause the problem.
-                let need_new_scope = scope_stack
-                    .iter()
-                    .any(|entry| entry.name == Some(name));
-
-                if need_new_scope {
-                    // Create a new lexical scope and push it onto the stack
-                    let loc = span_start(cx, pat.span);
-                    let file_metadata = file_metadata(cx, &loc.file.name);
-                    let parent_scope = scope_stack.last().unwrap().scope_metadata;
-
-                    let scope_metadata = unsafe {
-                        llvm::LLVMDIBuilderCreateLexicalBlock(
-                            DIB(cx),
-                            parent_scope,
-                            file_metadata,
-                            loc.line as c_uint,
-                            loc.col.to_usize() as c_uint)
-                    };
-
-                    scope_stack.push(ScopeStackEntry {
-                        scope_metadata: scope_metadata,
-                        name: Some(name)
-                    });
-
-                } else {
-                    // Push a new entry anyway so the name can be found
-                    let prev_metadata = scope_stack.last().unwrap().scope_metadata;
-                    scope_stack.push(ScopeStackEntry {
-                        scope_metadata: prev_metadata,
-                        name: Some(name)
-                    });
-                }
+        PatKind::Binding(_, ref path1, ref sub_pat_opt) => {
+            // LLVM does not properly generate 'DW_AT_start_scope' fields
+            // for variable DIEs. For this reason we have to introduce
+            // an artificial scope at bindings whenever a variable with
+            // the same name is declared in *any* parent scope.
+            //
+            // Otherwise the following error occurs:
+            //
+            // let x = 10;
+            //
+            // do_something(); // 'gdb print x' correctly prints 10
+            //
+            // {
+            //     do_something(); // 'gdb print x' prints 0, because it
+            //                     // already reads the uninitialized 'x'
+            //                     // from the next line...
+            //     let x = 100;
+            //     do_something(); // 'gdb print x' correctly prints 100
+            // }
+
+            // Is there already a binding with that name?
+            // N.B.: this comparison must be UNhygienic... because
+            // gdb knows nothing about the context, so any two
+            // variables with the same name will cause the problem.
+            let name = path1.node.unhygienize();
+            let need_new_scope = scope_stack
+                .iter()
+                .any(|entry| entry.name == Some(name));
+
+            if need_new_scope {
+                // Create a new lexical scope and push it onto the stack
+                let loc = span_start(cx, pat.span);
+                let file_metadata = file_metadata(cx, &loc.file.name);
+                let parent_scope = scope_stack.last().unwrap().scope_metadata;
+
+                let scope_metadata = unsafe {
+                    llvm::LLVMDIBuilderCreateLexicalBlock(
+                        DIB(cx),
+                        parent_scope,
+                        file_metadata,
+                        loc.line as c_uint,
+                        loc.col.to_usize() as c_uint)
+                };
+
+                scope_stack.push(ScopeStackEntry {
+                    scope_metadata: scope_metadata,
+                    name: Some(name)
+                });
+
+            } else {
+                // Push a new entry anyway so the name can be found
+                let prev_metadata = scope_stack.last().unwrap().scope_metadata;
+                scope_stack.push(ScopeStackEntry {
+                    scope_metadata: prev_metadata,
+                    name: Some(name)
+                });
             }
 
             scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs
index ccb01789aa6..b401166cfdb 100644
--- a/src/librustc_trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/debuginfo/metadata.rs
@@ -1945,7 +1945,7 @@ pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         }
         Some(hir_map::NodeLocal(pat)) => {
             match pat.node {
-                PatKind::Ident(_, ref path1, _) => {
+                PatKind::Binding(_, ref path1, _) => {
                     path1.node
                 }
                 _ => {
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 9030a6f222b..31805f14a8c 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -149,8 +149,7 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
                 // subtyping doesn't matter here, as the value is some kind of scalar
                 self.demand_eqtype(pat.span, expected, lhs_ty);
             }
-            PatKind::Path(..) | PatKind::Ident(..)
-                    if pat_is_resolved_const(&tcx.def_map.borrow(), pat) => {
+            PatKind::Path(..) if pat_is_resolved_const(&tcx.def_map.borrow(), pat) => {
                 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);
@@ -170,8 +169,7 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
                     self.write_error(pat.id);
                 }
             }
-            PatKind::Ident(bm, ref path, ref sub)
-                    if pat_is_binding(&tcx.def_map.borrow(), pat) => {
+            PatKind::Binding(bm, ref path, ref sub) => {
                 let typ = self.local_ty(pat.span, pat.id);
                 match bm {
                     hir::BindByRef(mutbl) => {
@@ -211,10 +209,6 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> {
                     }
                 }
             }
-            PatKind::Ident(_, ref path, _) => {
-                let path = hir::Path::from_name(path.span, path.node);
-                self.check_pat_enum(pat, &path, &[], None, expected, false);
-            }
             PatKind::TupleStruct(ref path, ref subpats, ddpos) => {
                 self.check_pat_enum(pat, path, &subpats, ddpos, expected, true);
             }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 264003bb62b..85a5d5b6293 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -572,19 +572,17 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
 
     // Add pattern bindings.
     fn visit_pat(&mut self, p: &'gcx hir::Pat) {
-        if let PatKind::Ident(_, ref path1, _) = p.node {
-            if pat_util::pat_is_binding(&self.fcx.tcx.def_map.borrow(), p) {
-                let var_ty = self.assign(p.span, p.id, None);
-
-                self.fcx.require_type_is_sized(var_ty, p.span,
-                                               traits::VariableType(p.id));
-
-                debug!("Pattern binding {} is assigned to {} with type {:?}",
-                       path1.node,
-                       self.fcx.ty_to_string(
-                           self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
-                       var_ty);
-            }
+        if let PatKind::Binding(_, ref path1, _) = p.node {
+            let var_ty = self.assign(p.span, p.id, None);
+
+            self.fcx.require_type_is_sized(var_ty, p.span,
+                                           traits::VariableType(p.id));
+
+            debug!("Pattern binding {} is assigned to {} with type {:?}",
+                   path1.node,
+                   self.fcx.ty_to_string(
+                       self.fcx.locals.borrow().get(&p.id).unwrap().clone()),
+                   var_ty);
         }
         intravisit::walk_pat(self, p);
     }
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 7b79f2ec9bf..bf34428832d 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -1160,7 +1160,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
         let _ = mc.cat_pattern(discr_cmt, root_pat, |mc, sub_cmt, sub_pat| {
                 match sub_pat.node {
                     // `ref x` pattern
-                    PatKind::Ident(hir::BindByRef(mutbl), _, _) => {
+                    PatKind::Binding(hir::BindByRef(mutbl), _, _) => {
                         self.link_region_from_node_type(sub_pat.span, sub_pat.id,
                                                         mutbl, sub_cmt);
                     }
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 5896a34b0d1..92027a56ec1 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -2152,12 +2152,9 @@ fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
 {
     for i in &decl.inputs {
         match i.pat.node {
-            PatKind::Ident(_, _, _) => (),
-            PatKind::Wild => (),
-            _ => {
-                span_err!(ccx.tcx.sess, i.pat.span, E0130,
-                          "patterns aren't allowed in foreign function declarations");
-            }
+            PatKind::Binding(..) | PatKind::Wild => {}
+            _ => span_err!(ccx.tcx.sess, i.pat.span, E0130,
+                           "patterns aren't allowed in foreign function declarations")
         }
     }
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 4831ee9a2e0..bf503141ff6 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2578,7 +2578,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::Binding(_, ref p, _) => p.node.to_string(),
         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"),