From 216f5fba043ff787ba2dd6bbf01e0e077304adf0 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 6 Mar 2016 15:54:44 +0300 Subject: [PATCH] Separate bindings from other patterns in HIR --- src/librustc/cfg/construct.rs | 4 +- src/librustc/hir/fold.rs | 4 +- src/librustc/hir/intravisit.rs | 2 +- src/librustc/hir/lowering.rs | 20 ++-- src/librustc/hir/map/collector.rs | 2 +- src/librustc/hir/map/def_collector.rs | 2 +- src/librustc/hir/map/mod.rs | 2 +- src/librustc/hir/mod.rs | 10 +- src/librustc/hir/pat_util.rs | 25 ++-- src/librustc/hir/print.rs | 4 +- src/librustc/middle/expr_use_visitor.rs | 25 ++-- src/librustc/middle/mem_categorization.rs | 8 +- src/librustc/middle/region.rs | 12 +- src/librustc/ty/mod.rs | 2 +- .../borrowck/gather_loans/gather_moves.rs | 2 +- src/librustc_const_eval/check_match.rs | 107 +++++++---------- src/librustc_lint/bad_style.rs | 18 +-- src/librustc_lint/builtin.rs | 2 +- src/librustc_metadata/encoder.rs | 2 +- src/librustc_mir/build/mod.rs | 9 +- src/librustc_mir/hair/cx/pattern.rs | 10 +- src/librustc_trans/_match.rs | 101 +++++++--------- .../debuginfo/create_scope_map.rs | 112 ++++++++---------- src/librustc_trans/debuginfo/metadata.rs | 2 +- src/librustc_typeck/check/_match.rs | 10 +- src/librustc_typeck/check/mod.rs | 20 ++-- src/librustc_typeck/check/regionck.rs | 2 +- src/librustc_typeck/collect.rs | 9 +- src/librustdoc/clean/mod.rs | 2 +- 29 files changed, 230 insertions(+), 300 deletions(-) diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index af47617ea92f..61c0f1c1c649 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 641fe5f3b474..1e80bc3c54dd 100644 --- a/src/librustc/hir/fold.rs +++ b/src/librustc/hir/fold.rs @@ -914,8 +914,8 @@ pub fn noop_fold_pat(p: P, folder: &mut T) -> P { 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 9b1d22436677..4593f19daadb 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 ea9a76d982a3..90dd2dad7203 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 { - 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 99e5f32e263f..692f56bde28f 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 e783d84dc1b4..e3b6539b8cca 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 2f310806a742..41b72e569f47 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 ea52a393da6c..0e89dde70ee7 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, Option>), + Binding(BindingMode, Spanned, Option>), /// 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; impl Arg { pub fn to_self(&self) -> Option { - 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 1008ba7a6e6a..35a7f7174cbb 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(dm: &RefCell, pat: &hir::Pat, mut it: I) where +pub fn pat_bindings(_: &RefCell, pat: &hir::Pat, mut it: I) where I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned), { 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 { 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 { 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 a9ed83d9dc31..ceaf348117e1 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 b0add5a23dc4..12517d927de4 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 e933b22f6079..31e3db51f55d 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 6b2c2dfcd72b..3efc584ae2b6 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 dfb4ec739247..24f0671ce618 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 83322215e30c..8682661d35a8 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 16b61534ee9a..46e05d218fc6 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) -> P { 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 { 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> = 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 27a6e433c739..4c4dea406ba9 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 49b59aea46ee..3005f564ff41 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 2bc953039adb..e0c35a6fba84 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 d75cf3b7587e..9d7818a9ba4d 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 b9ba860e8d0a..acde81979f92 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 4b22e410f4c2..bdde5ce16178 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, 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, 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, m: &[Match]) -> Option { fn pat_score(def_map: &RefCell, 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 aec43e69e518..66409a4c481c 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 , scope_map: &mut NodeMap) { - - 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) => { + 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 + // } - // 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) { + // 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)); - let name = path1.node.unhygienize(); + 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; - // 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 - // } + let scope_metadata = unsafe { + llvm::LLVMDIBuilderCreateLexicalBlock( + DIB(cx), + parent_scope, + file_metadata, + loc.line as c_uint, + loc.col.to_usize() as c_uint) + }; - // 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)); + scope_stack.push(ScopeStackEntry { + scope_metadata: scope_metadata, + 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) - }); - } + } 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 ccb01789aa64..b401166cfdb4 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 9030a6f222b8..31805f14a8cd 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 264003bb62b8..85a5d5b62933 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); + 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)); + 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); - } + 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 7b79f2ec9bfe..bf34428832d2 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 5896a34b0d16..92027a56ec1b 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 4831ee9a2e04..bf503141ff64 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"),