diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index a7a8673d49eb1..0098113acadd8 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -268,6 +268,9 @@ pub trait Visitor<'v>: Sized { fn visit_pat(&mut self, p: &'v Pat) { walk_pat(self, p) } + fn visit_binding(&mut self, b: &'v Binding) { + walk_binding(self, b) + } fn visit_anon_const(&mut self, c: &'v AnonConst) { walk_anon_const(self, c) } @@ -709,8 +712,8 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { PatKind::Box(ref subpattern) | PatKind::Ref(ref subpattern, _) => { visitor.visit_pat(subpattern) } - PatKind::Binding(_, _hir_id, ident, ref optional_subpattern) => { - visitor.visit_ident(ident); + PatKind::Binding(ref binding, ref optional_subpattern) => { + visitor.visit_binding(binding); walk_list!(visitor, visit_pat, optional_subpattern); } PatKind::Lit(ref expression) => visitor.visit_expr(expression), @@ -727,6 +730,13 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { } } +pub fn walk_binding<'v, V: Visitor<'v>>( + visitor: &mut V, + Binding { ident, annot: _, hir_id: _ }: &'v Binding, +) { + visitor.visit_ident(*ident); +} + pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem<'v>) { visitor.visit_id(foreign_item.hir_id); visitor.visit_vis(&foreign_item.vis); diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index f6db451d57ead..c77a20dfa21a5 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2065,7 +2065,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { inputs .iter() .map(|param| match param.pat.kind { - PatKind::Ident(_, ident, _) => ident, + PatKind::Binding(Binding { ident, mode: _ }, _) => ident, _ => Ident::new(kw::Invalid, param.pat.span), }) .collect() @@ -2155,8 +2155,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { c_variadic, implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| { let is_mutable_pat = match arg.pat.kind { - PatKind::Ident(BindingMode::ByValue(mt), _, _) - | PatKind::Ident(BindingMode::ByRef(mt), _, _) => mt == Mutability::Mut, + PatKind::Binding(Binding { mode: BindingMode::ByValue(mt), ident: _ }, _) + | PatKind::Binding(Binding { mode: BindingMode::ByRef(mt), ident: _ }, _) => { + mt == Mutability::Mut + } _ => false, }; @@ -2622,9 +2624,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_pat(&mut self, p: &Pat) -> P { let node = match p.kind { PatKind::Wild => hir::PatKind::Wild, - PatKind::Ident(ref binding_mode, ident, ref sub) => { + PatKind::Binding(binding, ref sub) => { let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s)); - let node = self.lower_pat_ident(p, binding_mode, ident, lower_sub); + let node = self.lower_pat_binding(p, binding, lower_sub); node } PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))), @@ -2755,10 +2757,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } // Found a sub-slice pattern `$binding_mode $ident @ ..`. // Record, lower it to `$binding_mode $ident @ _`, and stop here. - PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => { + PatKind::Binding(binding, Some(ref sub)) if sub.is_rest() => { prev_rest_span = Some(sub.span); let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub)); - let node = self.lower_pat_ident(pat, bm, ident, lower_sub); + let node = self.lower_pat_binding(pat, binding, lower_sub); slice = Some(self.pat_with_node_id_of(pat, node)); break; } @@ -2772,7 +2774,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // There was a previous subslice pattern; make sure we don't allow more. let rest_span = match pat.kind { PatKind::Rest => Some(pat.span), - PatKind::Ident(.., Some(ref sub)) if sub.is_rest() => { + PatKind::Binding(_, Some(ref sub)) if sub.is_rest() => { // The `HirValidator` is merciless; add a `_` pattern to avoid ICEs. after.push(self.pat_wild_with_node_id_of(pat)); Some(sub.span) @@ -2791,11 +2793,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::PatKind::Slice(before.into(), slice, after.into()) } - fn lower_pat_ident( + fn lower_binding( + &mut self, + Binding { mode, ident }: Binding, + canonical_id: NodeId, + ) -> hir::Binding { + let annot = self.lower_binding_mode(&mode); + let hir_id = self.lower_node_id(canonical_id); + hir::Binding { annot, hir_id, ident } + } + + fn lower_pat_binding( &mut self, p: &Pat, - binding_mode: &BindingMode, - ident: Ident, + binding: Binding, lower_sub: impl FnOnce(&mut Self) -> Option>, ) -> hir::PatKind { match self.resolver.get_partial_res(p.id).map(|d| d.base_res()) { @@ -2805,22 +2816,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Some(Res::Local(id)) => id, _ => p.id, }; - - hir::PatKind::Binding( - self.lower_binding_mode(binding_mode), - self.lower_node_id(canonical_id), - ident, - lower_sub(self), - ) + let binding = self.lower_binding(binding, canonical_id); + hir::PatKind::Binding(binding, lower_sub(self)) } - Some(res) => hir::PatKind::Path(hir::QPath::Resolved( - None, - P(hir::Path { + Some(res) => { + let Binding { ident, mode: _ } = binding; + let path = hir::Path { span: ident.span, res: self.lower_res(res), segments: hir_vec![hir::PathSegment::from_ident(ident)], - }), - )), + }; + hir::PatKind::Path(hir::QPath::Resolved(None, P(path))) + } } } @@ -3030,18 +3037,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, span: Span, ident: Ident, - bm: hir::BindingAnnotation, + annot: hir::BindingAnnotation, ) -> (P, hir::HirId) { let hir_id = self.next_id(); - - ( - P(hir::Pat { - hir_id, - kind: hir::PatKind::Binding(bm, hir_id, ident.with_span_pos(span), None), - span, - }), - hir_id, - ) + let binding = hir::Binding { annot, hir_id, ident: ident.with_span_pos(span) }; + let kind = hir::PatKind::Binding(binding, None); + (P(hir::Pat { hir_id, kind, span }), hir_id) } fn pat_wild(&mut self, span: Span) -> P { diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs index 04ebe3e8a72ba..15ea2867fe467 100644 --- a/src/librustc/hir/lowering/item.rs +++ b/src/librustc/hir/lowering/item.rs @@ -1104,9 +1104,10 @@ impl<'hir> LoweringContext<'_, 'hir> { // Check if this is a binding pattern, if so, we can optimize and avoid adding a // `let = __argN;` statement. In this case, we do not rename the parameter. let (ident, is_simple_parameter) = match parameter.pat.kind { - hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, _) => { - (ident, true) - } + hir::PatKind::Binding( + hir::Binding { annot: hir::BindingAnnotation::Unannotated, ident, .. }, + _, + ) => (ident, true), _ => { // Replace the ident for bindings that aren't simple. let name = format!("__arg{}", index); diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index f3be7e32ceabf..41457881a4e29 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -943,7 +943,9 @@ impl<'hir> Map<'hir> { Node::Field(f) => f.ident.name, Node::Lifetime(lt) => lt.name.ident().name, Node::GenericParam(param) => param.name.ident().name, - Node::Binding(&Pat { kind: PatKind::Binding(_, _, l, _), .. }) => l.name, + Node::Binding(&Pat { kind: PatKind::Binding(Binding { ident, .. }, _), .. }) => { + ident.name + } Node::Ctor(..) => self.name(self.get_parent_item(id)), _ => return None, }) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index e955b7058e355..89be9f7c11ace 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -849,6 +849,10 @@ pub struct Block { pub targeted_by_break: bool, } +// `Pat` is used a lot. Make sure it doesn't unintentionally get bigger. +#[cfg(target_arch = "x86_64")] +static_assert_size!(Pat, 80); + #[derive(RustcEncodable, RustcDecodable, HashStable)] pub struct Pat { #[stable_hasher(ignore)] @@ -951,6 +955,20 @@ pub struct FieldPat { pub span: Span, } +/// A fresh binding `{ref mut?}? $ident`. +/// +/// The `HirId` is the canonical ID for the variable being bound, +/// (e.g., in `Ok(x) | Err(x)`, both `x` use the same canonical ID), +/// which is the pattern ID of the first `x`. +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] +pub struct Binding { + /// The optional `ref mut?` annotation on this binding. + pub annot: BindingAnnotation, + pub hir_id: HirId, + /// The introduced binding name. + pub ident: Ident, +} + /// Explicit binding annotations given in the HIR for a binding. Note /// that this is not the final binding *mode* that we infer after type /// inference. @@ -995,11 +1013,8 @@ pub enum PatKind { /// Represents a wildcard pattern (i.e., `_`). Wild, - /// A fresh binding `ref mut binding @ OPT_SUBPATTERN`. - /// The `HirId` is the canonical ID for the variable being bound, - /// (e.g., in `Ok(x) | Err(x)`, both `x` use the same canonical ID), - /// which is the pattern ID of the first `x`. - Binding(BindingAnnotation, HirId, Ident, Option>), + /// A fresh binding pattern `binding {@ PAT}?`. + Binding(Binding, Option>), /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`). /// The `bool` is `true` in the presence of a `..`. diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index 8d3b464a8ffa1..c630ed29f0c55 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -1,6 +1,6 @@ use crate::hir::def::{CtorOf, DefKind, Res}; use crate::hir::def_id::DefId; -use crate::hir::{self, HirId, PatKind}; +use crate::hir::{self, Binding, BindingAnnotation, PatKind}; use syntax::ast; use syntax_pos::Span; @@ -78,10 +78,11 @@ impl hir::Pat { /// Call `f` on every "binding" in a pattern, e.g., on `a` in /// `match foo() { Some(a) => (), None => () }` - pub fn each_binding(&self, mut f: impl FnMut(hir::BindingAnnotation, HirId, Span, ast::Ident)) { + pub fn each_binding(&self, mut f: impl FnMut(&Binding, Span)) { self.walk_always(|p| { - if let PatKind::Binding(binding_mode, _, ident, _) = p.kind { - f(binding_mode, p.hir_id, p.span, ident); + if let PatKind::Binding(binding, _) = &p.kind { + // FIXME(Centril): compute and use span of binding. + f(binding, p.span); } }); } @@ -90,17 +91,15 @@ impl hir::Pat { /// `match foo() { Some(a) => (), None => () }`. /// /// When encountering an or-pattern `p_0 | ... | p_n` only `p_0` will be visited. - pub fn each_binding_or_first( - &self, - f: &mut impl FnMut(hir::BindingAnnotation, HirId, Span, ast::Ident), - ) { + pub fn each_binding_or_first(&self, f: &mut impl FnMut(&Binding, Span)) { self.walk(|p| match &p.kind { PatKind::Or(ps) => { ps[0].each_binding_or_first(f); false } - PatKind::Binding(bm, _, ident, _) => { - f(*bm, p.hir_id, p.span, *ident); + PatKind::Binding(binding, _) => { + // FIXME(Centril): compute and use span of binding. + f(binding, p.span); true } _ => true, @@ -141,8 +140,14 @@ impl hir::Pat { pub fn simple_ident(&self) -> Option { match self.kind { - PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, None) - | PatKind::Binding(hir::BindingAnnotation::Mutable, _, ident, None) => Some(ident), + PatKind::Binding( + Binding { annot: BindingAnnotation::Unannotated, ident, hir_id: _ }, + None, + ) + | PatKind::Binding( + Binding { annot: BindingAnnotation::Mutable, ident, hir_id: _ }, + None, + ) => Some(ident), _ => None, } } @@ -176,7 +181,7 @@ impl hir::Pat { // ref bindings are be implicit after #42640 (default match binding modes). See issue #44848. pub fn contains_explicit_ref_binding(&self) -> Option { let mut result = None; - self.each_binding(|annotation, _, _, _| match annotation { + self.each_binding(|hir::Binding { annot, ident: _, hir_id: _ }, _| match annot { hir::BindingAnnotation::Ref => match result { None | Some(hir::Mutability::Not) => result = Some(hir::Mutability::Not), _ => {} diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 2f3b6f82ee5ee..37f0cb3112a74 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1599,6 +1599,22 @@ impl<'a> State<'a> { } } + fn print_binding(&mut self, hir::Binding { annot, ident, hir_id: _ }: &hir::Binding) { + match annot { + hir::BindingAnnotation::Ref => { + self.word_nbsp("ref"); + self.print_mutability(hir::Mutability::Not, false); + } + hir::BindingAnnotation::RefMut => { + self.word_nbsp("ref"); + self.print_mutability(hir::Mutability::Mut, false); + } + hir::BindingAnnotation::Unannotated => {} + hir::BindingAnnotation::Mutable => self.word_nbsp("mut"), + } + self.print_ident(*ident); + } + pub fn print_pat(&mut self, pat: &hir::Pat) { self.maybe_print_comment(pat.span.lo()); self.ann.pre(self, AnnNode::Pat(pat)); @@ -1606,22 +1622,8 @@ impl<'a> State<'a> { // is that it doesn't matter match pat.kind { PatKind::Wild => self.s.word("_"), - PatKind::Binding(binding_mode, _, ident, ref sub) => { - match binding_mode { - hir::BindingAnnotation::Ref => { - self.word_nbsp("ref"); - self.print_mutability(hir::Mutability::Not, false); - } - hir::BindingAnnotation::RefMut => { - self.word_nbsp("ref"); - self.print_mutability(hir::Mutability::Mut, false); - } - hir::BindingAnnotation::Unannotated => {} - hir::BindingAnnotation::Mutable => { - self.word_nbsp("mut"); - } - } - self.print_ident(ident); + PatKind::Binding(ref binding, ref sub) => { + self.print_binding(binding); if let Some(ref p) = *sub { self.s.word("@"); self.print_pat(&p); diff --git a/src/librustc/hir/upvars.rs b/src/librustc/hir/upvars.rs index 2df7a38693af6..11a73376bbbe8 100644 --- a/src/librustc/hir/upvars.rs +++ b/src/librustc/hir/upvars.rs @@ -46,11 +46,9 @@ impl Visitor<'tcx> for LocalCollector { NestedVisitorMap::None } - fn visit_pat(&mut self, pat: &'tcx hir::Pat) { - if let hir::PatKind::Binding(_, hir_id, ..) = pat.kind { - self.locals.insert(hir_id); - } - intravisit::walk_pat(self, pat); + fn visit_binding(&mut self, binding: &'tcx hir::Binding) { + self.locals.insert(binding.hir_id); + intravisit::walk_binding(self, binding); } } diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 3e97beb7bce23..7762604e37805 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -1222,8 +1222,10 @@ fn resolve_local<'tcx>( // & expression, and its lifetime would be extended to the end of the block (due // to a different rule, not the below code). match pat.kind { - PatKind::Binding(hir::BindingAnnotation::Ref, ..) - | PatKind::Binding(hir::BindingAnnotation::RefMut, ..) => true, + PatKind::Binding(hir::Binding { annot: hir::BindingAnnotation::Ref, .. }, _) + | PatKind::Binding(hir::Binding { annot: hir::BindingAnnotation::RefMut, .. }, _) => { + true + } PatKind::Struct(_, ref field_pats, _) => { field_pats.iter().any(|fp| is_binding_pat(&fp.pat)) @@ -1242,8 +1244,11 @@ fn resolve_local<'tcx>( PatKind::Box(ref subpat) => is_binding_pat(&subpat), PatKind::Ref(_, _) - | PatKind::Binding(hir::BindingAnnotation::Unannotated, ..) - | PatKind::Binding(hir::BindingAnnotation::Mutable, ..) + | PatKind::Binding( + hir::Binding { annot: hir::BindingAnnotation::Unannotated, .. }, + _, + ) + | PatKind::Binding(hir::Binding { annot: hir::BindingAnnotation::Mutable, .. }, _) | PatKind::Wild | PatKind::Path(_) | PatKind::Lit(_) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 42db64c791518..560f68b2cc3bf 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1335,9 +1335,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Get the local name of this closure. This can be inaccurate because // of the possibility of reassignment, but this should be good enough. match &kind { - hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, name, None) => { - Some(format!("{}", name)) - } + hir::PatKind::Binding( + hir::Binding { annot: hir::BindingAnnotation::Unannotated, ident, hir_id: _ }, + None, + ) => Some(format!("{}", ident)), _ => { err.note(&msg); None @@ -1418,7 +1419,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .params .iter() .map(|arg| match &arg.pat.kind { - hir::PatKind::Binding(_, _, ident, None) + hir::PatKind::Binding(hir::Binding { ident, annot: _, hir_id: _ }, None) // FIXME: provide a better suggestion when encountering `SelfLower`, it // should suggest a method call. if ident.name != kw::SelfLower => ident.to_string(), diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 332176e1b0cec..337a9c7f53b6e 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -175,7 +175,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns { // (Issue #49588) continue; } - if let PatKind::Binding(binding_annot, _, ident, None) = fieldpat.pat.kind { + if let PatKind::Binding(hir::Binding { annot, hir_id: _, ident }, None) = + fieldpat.pat.kind + { if cx.tcx.find_field_index(ident, &variant) == Some(cx.tcx.field_index(fieldpat.hir_id, cx.tables)) { @@ -184,7 +186,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns { fieldpat.span, &format!("the `{}:` in this pattern is redundant", ident), ); - let binding = match binding_annot { + let binding = match annot { hir::BindingAnnotation::Unannotated => None, hir::BindingAnnotation::Mutable => Some("mut"), hir::BindingAnnotation::Ref => Some("ref"), @@ -636,41 +638,36 @@ declare_lint_pass!( impl EarlyLintPass for AnonymousParameters { fn check_trait_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) { - match it.kind { - ast::AssocItemKind::Fn(ref sig, _) => { - for arg in sig.decl.inputs.iter() { - match arg.pat.kind { - ast::PatKind::Ident(_, ident, None) => { - if ident.name == kw::Invalid { - let ty_snip = cx.sess.source_map().span_to_snippet(arg.ty.span); - - let (ty_snip, appl) = if let Ok(snip) = ty_snip { - (snip, Applicability::MachineApplicable) - } else { - ("".to_owned(), Applicability::HasPlaceholders) - }; + if let ast::AssocItemKind::Fn(ref sig, _) = it.kind { + for arg in sig.decl.inputs.iter() { + if let ast::PatKind::Binding( + ast::Binding { ident: ast::Ident { name: kw::Invalid, .. }, .. }, + None, + ) = arg.pat.kind + { + let ty_snip = cx.sess.source_map().span_to_snippet(arg.ty.span); + + let (ty_snip, appl) = if let Ok(snip) = ty_snip { + (snip, Applicability::MachineApplicable) + } else { + ("".to_owned(), Applicability::HasPlaceholders) + }; - cx.struct_span_lint( - ANONYMOUS_PARAMETERS, - arg.pat.span, - "anonymous parameters are deprecated and will be \ + cx.struct_span_lint( + ANONYMOUS_PARAMETERS, + arg.pat.span, + "anonymous parameters are deprecated and will be \ removed in the next edition.", - ) - .span_suggestion( - arg.pat.span, - "Try naming the parameter or explicitly \ - ignoring it", - format!("_: {}", ty_snip), - appl, - ) - .emit(); - } - } - _ => (), - } + ) + .span_suggestion( + arg.pat.span, + "try naming the parameter or explicitly ignoring it", + format!("_: {}", ty_snip), + appl, + ) + .emit(); } } - _ => (), } } } diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index b8b4c2b39e543..fe93eeaadf439 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -345,7 +345,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { } fn check_pat(&mut self, cx: &LateContext<'_, '_>, p: &hir::Pat) { - if let &PatKind::Binding(_, _, ident, _) = &p.kind { + if let &PatKind::Binding(hir::Binding { annot: _, hir_id: _, ident }, _) = &p.kind { self.check_snake_case(cx, "variable", &ident); } } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 5f57aabe8d426..aceb9b91353b0 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -371,7 +371,7 @@ impl UnusedParens { avoid_or: bool, avoid_mut: bool, ) { - use ast::{BindingMode, Mutability, PatKind}; + use ast::{Binding, BindingMode, Mutability, PatKind}; if let PatKind::Paren(inner) = &value.kind { match inner.kind { @@ -383,7 +383,12 @@ impl UnusedParens { // Avoid `p0 | .. | pn` if we should. PatKind::Or(..) if avoid_or => return, // Avoid `mut x` and `mut x @ p` if we should: - PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ..) if avoid_mut => return, + PatKind::Binding( + Binding { mode: BindingMode::ByValue(Mutability::Mut), .. }, + _, + ) if avoid_mut => { + return; + } // Otherwise proceed with linting. _ => {} } @@ -526,7 +531,7 @@ impl EarlyLintPass for UnusedParens { // Do not lint on `(..)` as that will result in the other arms being useless. Paren(_) // The other cases do not contain sub-patterns. - | Wild | Rest | Lit(..) | Mac(..) | Range(..) | Ident(.., None) | Path(..) => return, + | Wild | Rest | Lit(..) | Mac(..) | Range(..) | Binding(.., None) | Path(..) => return, // These are list-like patterns; parens can always be removed. TupleStruct(_, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps { self.check_unused_parens_pat(cx, p, false, false); @@ -535,7 +540,7 @@ impl EarlyLintPass for UnusedParens { self.check_unused_parens_pat(cx, &f.pat, false, false); }, // Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106. - Ident(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false), + Binding(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false), // Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342. // Also avoid linting on `& mut? (p0 | .. | pn)`, #64106. Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not), diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 1e93d144f15df..ef8ea5b26e5ef 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -952,7 +952,7 @@ impl EncodeContext<'tcx> { self.tcx.dep_graph.with_ignore(|| { let body = self.tcx.hir().body(body_id); self.lazy(body.params.iter().map(|arg| match arg.pat.kind { - PatKind::Binding(_, _, ident, _) => ident.name, + PatKind::Binding(hir::Binding { annot: _, hir_id: _, ident }, _) => ident.name, _ => kw::Invalid, })) }) diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs index b46b26444f61b..8d1f105206683 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs @@ -280,16 +280,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let upvar_hir_id = self.upvars[upvar_index.index()].var_hir_id; if let Some(Node::Binding(pat)) = self.infcx.tcx.hir().find(upvar_hir_id) { if let hir::PatKind::Binding( - hir::BindingAnnotation::Unannotated, - _, - upvar_ident, + hir::Binding { + annot: hir::BindingAnnotation::Unannotated, + hir_id: _, + ident, + }, _, ) = pat.kind { err.span_suggestion( - upvar_ident.span, + ident.span, "consider changing this to be mutable", - format!("mut {}", upvar_ident.name), + format!("mut {}", ident.name), Applicability::MachineApplicable, ); } diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index e1a51e2fb35e5..5dd9b5a6d6b49 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -289,7 +289,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) -> BlockAnd<()> { match *irrefutable_pat.kind { // Optimize the case of `let x = ...` to write directly into `x` - PatKind::Binding { mode: BindingMode::ByValue, var, subpattern: None, .. } => { + PatKind::Binding { + binding: + hair::Binding { mode: BindingMode::ByValue, var, mutability: _, ty: _, name: _ }, + subpattern: None, + } => { let place = self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard); unpack!(block = self.into(&place, block, initializer)); @@ -315,10 +319,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Pat { kind: box PatKind::Binding { - mode: BindingMode::ByValue, - var, + binding: + hair::Binding { + mode: BindingMode::ByValue, + var, + mutability: _, + name: _, + ty: _, + }, subpattern: None, - .. }, .. }, @@ -522,7 +531,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) { debug!("visit_bindings: pattern={:?} pattern_user_ty={:?}", pattern, pattern_user_ty); match *pattern.kind { - PatKind::Binding { mutability, name, mode, var, ty, ref subpattern, .. } => { + PatKind::Binding { + binding: hair::Binding { mutability, name, mode, var, ty }, + ref subpattern, + } => { f(self, mutability, name, mode, var, pattern.span, ty, pattern_user_ty.clone()); if let Some(subpattern) = subpattern.as_ref() { self.visit_bindings(subpattern, pattern_user_ty, f); diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index bbb555a58e69f..3c6b91b048209 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -80,7 +80,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Ok(()) } - PatKind::Binding { name, mutability, mode, var, ty, ref subpattern } => { + PatKind::Binding { + binding: hair::Binding { name, mutability, mode, var, ty }, + ref subpattern, + } => { candidate.bindings.push(Binding { name, mutability, diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 327372beb47b7..f0ec05f8aa85d 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -1,7 +1,7 @@ use crate::build; use crate::build::scope::DropKind; use crate::hair::cx::Cx; -use crate::hair::{BindingMode, LintLevel, PatKind}; +use crate::hair::{Binding, BindingMode, LintLevel, PatKind}; use crate::transform::MirSource; use crate::util as mir_util; use rustc::hir; @@ -800,7 +800,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut mutability = Mutability::Not; let mut name = kw::Invalid; if let Some(Node::Binding(pat)) = tcx_hir.find(var_id) { - if let hir::PatKind::Binding(_, _, ident, _) = pat.kind { + if let hir::PatKind::Binding( + hir::Binding { annot: _, hir_id: _, ident }, + _, + ) = pat.kind + { name = ident.name; match hir_tables.extract_binding_mode(tcx.sess, pat.hir_id, pat.span) { Some(ty::BindByValue(hir::Mutability::Mut)) => { @@ -862,11 +866,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match *pattern.kind { // Don't introduce extra copies for simple bindings PatKind::Binding { - mutability, - var, - mode: BindingMode::ByValue, + binding: + Binding { mode: BindingMode::ByValue, mutability, var, ty: _, name: _ }, subpattern: None, - .. } => { self.local_decls[local].mutability = mutability; self.local_decls[local].source_info.scope = self.source_scope; diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 188c73e105a49..9be27ca1acd30 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -21,7 +21,7 @@ pub mod cx; pub mod pattern; pub(crate) use self::pattern::PatTyProj; -pub use self::pattern::{BindingMode, FieldPat, Pat, PatKind, PatRange}; +pub use self::pattern::{Binding, BindingMode, FieldPat, Pat, PatKind, PatRange}; mod util; diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 67c89c7293c43..244d1cc7eff92 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -270,7 +270,7 @@ fn const_not_var(err: &mut DiagnosticBuilder<'_>, tcx: TyCtxt<'_>, pat: &Pat, pa fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pat) { pat.walk_always(|p| { - if let hir::PatKind::Binding(_, _, ident, None) = p.kind { + if let hir::PatKind::Binding(hir::Binding { annot: _, hir_id: _, ident }, None) = p.kind { if let Some(ty::BindByValue(hir::Mutability::Not)) = cx.tables.extract_binding_mode(cx.tcx.sess, p.hir_id, p.span) { @@ -581,7 +581,7 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo // Find all by-ref spans. let mut by_ref_spans = Vec::new(); - pat.each_binding(|_, hir_id, span, _| { + pat.each_binding(|&hir::Binding { annot: _, hir_id, ident: _ }, span| { if let Some(ty::BindByReference(_)) = tables.extract_binding_mode(sess, hir_id, span) { by_ref_spans.push(span); } @@ -602,7 +602,7 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo } }; pat.walk_always(|p| { - if let hir::PatKind::Binding(.., sub) = &p.kind { + if let hir::PatKind::Binding(_, sub) = &p.kind { if let Some(ty::BindByValue(_)) = tables.extract_binding_mode(sess, p.hir_id, p.span) { let pat_ty = tables.node_type(p.hir_id); if !pat_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, pat.span) { @@ -649,7 +649,9 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) { pat.walk_always(|pat| { // Extract `sub` in `binding @ sub`. let (name, sub) = match &pat.kind { - hir::PatKind::Binding(.., name, Some(sub)) => (*name, sub), + hir::PatKind::Binding(hir::Binding { annot: _, hir_id: _, ident }, Some(sub)) => { + (*ident, sub) + } _ => return, }; @@ -663,7 +665,7 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) { // Recurse into each binding in `sub` and find mutability conflicts. let mut conflicts_mut_mut = Vec::new(); let mut conflicts_mut_ref = Vec::new(); - sub.each_binding(|_, hir_id, span, _| { + sub.each_binding(|&hir::Binding { annot: _, hir_id, ident: _ }, span| { if let Some(mut_inner) = extract_binding_mut(hir_id, span) { match (mut_outer, mut_inner) { (Mutability::Not, Mutability::Not) => {} diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 869aeeba418da..0250f4f9463b6 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -44,6 +44,35 @@ pub enum BindingMode { ByRef(BorrowKind), } +#[derive(Clone, Debug)] +pub struct Binding<'tcx> { + pub mutability: Mutability, + pub name: ast::Name, + pub mode: BindingMode, + pub var: hir::HirId, + pub ty: Ty<'tcx>, +} + +impl<'tcx> fmt::Display for Binding<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let is_mut = match self.mode { + BindingMode::ByValue => self.mutability == Mutability::Mut, + BindingMode::ByRef(bk) => { + write!(f, "ref ")?; + match bk { + BorrowKind::Mut { .. } => true, + _ => false, + } + } + }; + if is_mut { + write!(f, "mut ")?; + } + write!(f, "{}", self.name)?; + Ok(()) + } +} + #[derive(Clone, Debug)] pub struct FieldPat<'tcx> { pub field: Field, @@ -126,11 +155,7 @@ pub enum PatKind<'tcx> { /// `x`, `ref x`, `x @ P`, etc. Binding { - mutability: Mutability, - name: ast::Name, - mode: BindingMode, - var: hir::HirId, - ty: Ty<'tcx>, + binding: Binding<'tcx>, subpattern: Option>, }, @@ -207,21 +232,8 @@ impl<'tcx> fmt::Display for Pat<'tcx> { match *self.kind { PatKind::Wild => write!(f, "_"), PatKind::AscribeUserType { ref subpattern, .. } => write!(f, "{}: _", subpattern), - PatKind::Binding { mutability, name, mode, ref subpattern, .. } => { - let is_mut = match mode { - BindingMode::ByValue => mutability == Mutability::Mut, - BindingMode::ByRef(bk) => { - write!(f, "ref ")?; - match bk { - BorrowKind::Mut { .. } => true, - _ => false, - } - } - }; - if is_mut { - write!(f, "mut ")?; - } - write!(f, "{}", name)?; + PatKind::Binding { ref binding, ref subpattern } => { + write!(f, "{}", binding)?; if let Some(ref subpattern) = *subpattern { write!(f, " @ {}", subpattern)?; } @@ -549,7 +561,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { PatKind::Leaf { subpatterns } } - hir::PatKind::Binding(_, id, ident, ref sub) => { + hir::PatKind::Binding(hir::Binding { annot: _, hir_id: var, ident }, ref sub) => { let bm = *self.tables.pat_binding_modes().get(pat.hir_id).expect("missing binding mode"); let (mutability, mode) = match bm { @@ -574,14 +586,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } }; - PatKind::Binding { - mutability, - mode, - name: ident.name, - var: id, - ty: var_ty, - subpattern: self.lower_opt_pattern(sub), - } + let binding = Binding { mutability, mode, name: ident.name, var, ty: var_ty }; + PatKind::Binding { binding, subpattern: self.lower_opt_pattern(sub) } } hir::PatKind::TupleStruct(ref qpath, ref pats, ddpos) => { @@ -934,15 +940,18 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> { user_ty_span, }, }, - PatKind::Binding { mutability, name, mode, var, ty, ref subpattern } => { - PatKind::Binding { + PatKind::Binding { + binding: Binding { mutability, name, mode, var, ty }, + ref subpattern, + } => { + let binding = Binding { mutability: mutability.fold_with(folder), name: name.fold_with(folder), mode: mode.fold_with(folder), var: var.fold_with(folder), ty: ty.fold_with(folder), - subpattern: subpattern.fold_with(folder), - } + }; + PatKind::Binding { binding, subpattern: subpattern.fold_with(folder) } } PatKind::Variant { adt_def, substs, variant_index, ref subpatterns } => { PatKind::Variant { diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index df8cb5d692b15..b3e494ab3dcf7 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -185,7 +185,11 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M if let Some((&var_hir_id, _)) = upvars.get_index(field) { let node = self.ecx.tcx.hir().get(var_hir_id); if let hir::Node::Binding(pat) = node { - if let hir::PatKind::Binding(_, _, ident, _) = pat.kind { + if let hir::PatKind::Binding( + hir::Binding { annot: _, hir_id: _, ident }, + _, + ) = pat.kind + { name = Some(ident.name); } } diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index f58b9a4c14441..28b9f1c2ad0b0 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_error_codes::*; use rustc_errors::{self, pluralize, Applicability, DiagnosticBuilder, Handler, PResult}; use syntax::ast::{ - self, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, Param, + self, BinOpKind, Binding, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, Param, }; use syntax::ast::{AttrVec, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind}; use syntax::print::pprust; @@ -22,11 +22,9 @@ const TURBOFISH: &'static str = "use `::<...>` instead of `<...>` to specify typ /// Creates a placeholder argument. pub(super) fn dummy_arg(ident: Ident) -> Param { - let pat = P(Pat { - id: ast::DUMMY_NODE_ID, - kind: PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None), - span: ident.span, - }); + let binding = Binding { ident, mode: BindingMode::ByValue(Mutability::Not) }; + let kind = PatKind::Binding(binding, None); + let pat = P(Pat { id: ast::DUMMY_NODE_ID, kind, span: ident.span }); let ty = Ty { kind: TyKind::Err, span: ident.span, id: ast::DUMMY_NODE_ID }; Param { attrs: AttrVec::default(), @@ -1325,7 +1323,7 @@ impl<'a> Parser<'a> { Applicability::HasPlaceholders, ); return Some(ident); - } else if let PatKind::Ident(_, ident, _) = pat.kind { + } else if let PatKind::Binding(Binding { ident, mode: _ }, _) = pat.kind { if require_name && (is_trait_item || self.token == token::Comma @@ -1487,7 +1485,7 @@ impl<'a> Parser<'a> { pub(super) fn deduplicate_recovered_params_names(&self, fn_inputs: &mut Vec) { let mut seen_inputs = FxHashSet::default(); for input in fn_inputs.iter_mut() { - let opt_ident = if let (PatKind::Ident(_, ident, _), TyKind::Err) = + let opt_ident = if let (PatKind::Binding(Binding { ident, mode: _ }, _), TyKind::Err) = (&input.pat.kind, &input.ty.kind) { Some(*ident) diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 8f8e5fbb78765..d0dbf61098e5e 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -1936,7 +1936,7 @@ impl<'a> Parser<'a> { Ok(ty) => { let ident = Ident::new(kw::Invalid, self.prev_span); let bm = BindingMode::ByValue(Mutability::Not); - let pat = self.mk_pat_ident(ty.span, bm, ident); + let pat = self.mk_pat_binding(ty.span, bm, ident); (pat, ty) } // If this is a C-variadic argument and we hit an error, return the error. diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index 1540e6d7c053f..ce70ca7e31949 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -2,8 +2,8 @@ use super::{Parser, PathStyle}; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; use rustc_errors::{Applicability, DiagnosticBuilder, PResult}; use syntax::ast::{self, AttrVec, Attribute, FieldPat, Mac, Pat, PatKind, RangeEnd, RangeSyntax}; -use syntax::ast::{BindingMode, Expr, ExprKind, Ident, Mutability, Path, QSelf}; -use syntax::mut_visit::{noop_visit_mac, noop_visit_pat, MutVisitor}; +use syntax::ast::{Binding, BindingMode, Expr, ExprKind, Ident, Mutability, Path, QSelf}; +use syntax::mut_visit::{noop_visit_binding, noop_visit_mac, MutVisitor}; use syntax::print::pprust; use syntax::ptr::P; use syntax::token; @@ -403,13 +403,13 @@ impl<'a> Parser<'a> { let mut rhs = self.parse_pat(None)?; let sp = lhs.span.to(rhs.span); - if let PatKind::Ident(_, _, ref mut sub @ None) = rhs.kind { + if let PatKind::Binding(_, ref mut sub @ None) = rhs.kind { // The user inverted the order, so help them fix that. let mut applicability = Applicability::MachineApplicable; // FIXME(bindings_after_at): Remove this code when stabilizing the feature. lhs.walk(&mut |p| match p.kind { // `check_match` is unhappy if the subpattern has a binding anywhere. - PatKind::Ident(..) => { + PatKind::Binding(..) => { applicability = Applicability::MaybeIncorrect; false // Short-circuit. } @@ -528,7 +528,7 @@ impl<'a> Parser<'a> { // Unwrap; If we don't have `mut $ident`, error. let pat = pat.into_inner(); match &pat.kind { - PatKind::Ident(..) => {} + PatKind::Binding(..) => {} _ => self.ban_mut_general_pat(mut_span, &pat, changed_any_binding), } @@ -560,14 +560,12 @@ impl<'a> Parser<'a> { noop_visit_mac(mac, self); } - fn visit_pat(&mut self, pat: &mut P) { - if let PatKind::Ident(BindingMode::ByValue(ref mut m @ Mutability::Not), ..) = - pat.kind - { + fn visit_binding(&mut self, binding: &mut Binding) { + if let BindingMode::ByValue(m @ Mutability::Not) = &mut binding.mode { *m = Mutability::Mut; self.0 = true; } - noop_visit_pat(pat, self); + noop_visit_binding(binding, self); } } @@ -784,7 +782,7 @@ impl<'a> Parser<'a> { /// Parses `ident` or `ident @ pat`. /// Used by the copy foo and ref foo patterns to give a good /// error message when parsing mistakes like `ref foo(a, b)`. - fn parse_pat_ident(&mut self, binding_mode: BindingMode) -> PResult<'a, PatKind> { + fn parse_pat_ident(&mut self, mode: BindingMode) -> PResult<'a, PatKind> { let ident = self.parse_ident()?; let sub = if self.eat(&token::At) { Some(self.parse_pat(Some("binding pattern"))?) @@ -801,7 +799,7 @@ impl<'a> Parser<'a> { return Err(self.span_fatal(self.prev_span, "expected identifier, found enum pattern")); } - Ok(PatKind::Ident(binding_mode, ident, sub)) + Ok(PatKind::Binding(Binding { mode, ident }, sub)) } /// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`). @@ -997,7 +995,7 @@ impl<'a> Parser<'a> { (false, false) => BindingMode::ByValue(Mutability::Not), }; - let fieldpat = self.mk_pat_ident(boxed_span.to(hi), bind_type, fieldname); + let fieldpat = self.mk_pat_binding(boxed_span.to(hi), bind_type, fieldname); let subpat = if is_box { self.mk_pat(lo.to(hi), PatKind::Box(fieldpat)) } else { fieldpat }; (subpat, fieldname, true) @@ -1014,8 +1012,8 @@ impl<'a> Parser<'a> { }) } - pub(super) fn mk_pat_ident(&self, span: Span, bm: BindingMode, ident: Ident) -> P { - self.mk_pat(span, PatKind::Ident(bm, ident, None)) + pub(super) fn mk_pat_binding(&self, span: Span, mode: BindingMode, ident: Ident) -> P { + self.mk_pat(span, PatKind::Binding(Binding { mode, ident }, None)) } fn mk_pat(&self, span: Span, kind: PatKind) -> P { diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index c3a5175abac53..5fcdc08b980ba 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -158,10 +158,15 @@ impl<'a> AstValidator<'a> { fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, bool)) { for Param { pat, .. } in &decl.inputs { match pat.kind { - PatKind::Ident(BindingMode::ByValue(Mutability::Not), _, None) | PatKind::Wild => {} - PatKind::Ident(BindingMode::ByValue(Mutability::Mut), _, None) => { - report_err(pat.span, true) - } + PatKind::Binding( + Binding { mode: BindingMode::ByValue(Mutability::Not), .. }, + None, + ) + | PatKind::Wild => {} + PatKind::Binding( + Binding { mode: BindingMode::ByValue(Mutability::Mut), .. }, + None, + ) => report_err(pat.span, true), _ => report_err(pat.span, false), } } diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs index 1a8abeb7abcdc..14368d27ed850 100644 --- a/src/librustc_passes/liveness.rs +++ b/src/librustc_passes/liveness.rs @@ -382,7 +382,7 @@ fn visit_fn<'tcx>( rustc::hir::PatKind::Struct(..) => true, _ => false, }; - param.pat.each_binding(|_bm, hir_id, _x, ident| { + param.pat.each_binding(|&hir::Binding { annot: _, hir_id, ident }, _| { debug!("adding parameters {:?}", hir_id); let var = if is_shorthand { Local(LocalInfo { id: hir_id, name: ident.name, is_shorthand: true }) @@ -437,7 +437,7 @@ fn add_from_pat(ir: &mut IrMaps<'_>, pat: &P) { } } - pat.each_binding(|_, hir_id, _, ident| { + pat.each_binding(|&hir::Binding { annot: _, hir_id, ident }, _| { ir.add_live_node_for_node(hir_id, VarDefNode(ident.span)); ir.add_variable(Local(LocalInfo { id: hir_id, @@ -718,7 +718,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // In an or-pattern, only consider the first pattern; any later patterns // must have the same bindings, and we also consider the first pattern // to be the "authoritative" set of ids. - pat.each_binding_or_first(&mut |_, hir_id, pat_sp, ident| { + pat.each_binding_or_first(&mut |&hir::Binding { annot: _, hir_id, ident }, pat_sp| { let ln = self.live_node(hir_id, pat_sp); let var = self.variable(hir_id, ident.span); self.init_from_succ(ln, succ); @@ -1481,7 +1481,7 @@ impl<'tcx> Liveness<'_, 'tcx> { // patterns so the suggestions to prefix with underscores will apply to those too. let mut vars: FxIndexMap)> = <_>::default(); - pat.each_binding(|_, hir_id, pat_sp, ident| { + pat.each_binding(|&hir::Binding { annot: _, hir_id, ident }, pat_sp| { let ln = entry_ln.unwrap_or_else(|| self.live_node(hir_id, pat_sp)); let var = self.variable(hir_id, ident.span); vars.entry(self.ir.variable_name(var)) diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 898ab6ae32211..694e37617074a 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -44,7 +44,7 @@ type BindingMap = IdentMap; #[derive(Copy, Clone, Debug)] struct BindingInfo { span: Span, - binding_mode: BindingMode, + mode: BindingMode, } #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -1220,10 +1220,10 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { pat.walk(&mut |pat| { match pat.kind { - PatKind::Ident(binding_mode, ident, ref sub_pat) + PatKind::Binding(Binding { mode, ident }, ref sub_pat) if sub_pat.is_some() || self.is_base_res_local(pat.id) => { - binding_map.insert(ident, BindingInfo { span: ident.span, binding_mode }); + binding_map.insert(ident, BindingInfo { span: ident.span, mode }); } PatKind::Or(ref ps) => { // Check the consistency of this or-pattern and @@ -1283,7 +1283,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { binding_error.target.insert(pat_outer.span); } Some(binding_outer) => { - if binding_outer.binding_mode != binding_inner.binding_mode { + if binding_outer.mode != binding_inner.mode { // The binding modes in the outer and inner bindings differ. inconsistent_vars .entry(name) @@ -1384,12 +1384,12 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { pat.walk(&mut |pat| { debug!("resolve_pattern pat={:?} node={:?}", pat, pat.kind); match pat.kind { - PatKind::Ident(bmode, ident, ref sub) => { + PatKind::Binding(Binding { mode, ident }, ref sub) => { // First try to resolve the identifier as some existing entity, // then fall back to a fresh binding. let has_sub = sub.is_some(); let res = self - .try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub) + .try_resolve_as_non_binding(pat_src, pat, mode, ident, has_sub) .unwrap_or_else(|| self.fresh_binding(ident, pat.id, pat_src, bindings)); self.r.record_partial_res(pat.id, PartialRes::new(res)); } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 27d4eef34cb7c..37e4994faf360 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -634,8 +634,9 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { } Node::Binding(&hir::Pat { - kind: hir::PatKind::Binding(_, canonical_id, ..), .. - }) => Res::Local(canonical_id), + kind: hir::PatKind::Binding(hir::Binding { annot: _, hir_id, ident: _ }, _), + .. + }) => Res::Local(hir_id), _ => Res::Err, } @@ -882,14 +883,15 @@ fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String { // An AST visitor for collecting paths (e.g., the names of structs) and formal // variables (idents) from patterns. +#[derive(Default)] struct PathCollector<'l> { collected_paths: Vec<(NodeId, &'l ast::Path)>, collected_idents: Vec<(NodeId, ast::Ident, ast::Mutability)>, } impl<'l> PathCollector<'l> { - fn new() -> PathCollector<'l> { - PathCollector { collected_paths: vec![], collected_idents: vec![] } + fn new() -> Self { + Self::default() } } @@ -902,7 +904,7 @@ impl<'l> Visitor<'l> for PathCollector<'l> { PatKind::TupleStruct(ref path, ..) | PatKind::Path(_, ref path) => { self.collected_paths.push((p.id, path)); } - PatKind::Ident(bm, ident, _) => { + PatKind::Binding(ast::Binding { mode: bm, ident }, _) => { debug!( "PathCollector, visit ident in pat {}: {:?} {:?}", ident, p.span, ident.span diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 8e79cc1389562..a9e226b1d2879 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1175,7 +1175,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { // Add pattern bindings. fn visit_pat(&mut self, p: &'tcx hir::Pat) { - if let PatKind::Binding(_, _, ident, _) = p.kind { + if let PatKind::Binding(hir::Binding { annot: _, hir_id: _, ident }, _) = p.kind { let var_ty = self.assign(p.span, p.hir_id, None); if !self.fcx.tcx.features().unsized_locals { @@ -4659,11 +4659,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .params .iter() .map(|param| match ¶m.pat.kind { - hir::PatKind::Binding(_, _, ident, None) - if ident.name != kw::SelfLower => - { - ident.to_string() - } + hir::PatKind::Binding( + hir::Binding { annot: _, hir_id: _, ident }, + None, + ) if ident.name != kw::SelfLower => ident.to_string(), _ => "_".to_string(), }) .collect::>() @@ -4684,11 +4683,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .params .iter() .map(|param| match ¶m.pat.kind { - hir::PatKind::Binding(_, _, ident, None) - if ident.name != kw::SelfLower => - { - ident.to_string() - } + hir::PatKind::Binding( + hir::Binding { annot: _, hir_id: _, ident }, + None, + ) if ident.name != kw::SelfLower => ident.to_string(), _ => "_".to_string(), }) .collect::>() diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index d0f1ef7b4ecd7..482f857cbfad0 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -77,9 +77,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(ty) => ty, } } - PatKind::Binding(ba, var_id, _, sub) => { - let sub = sub.as_deref(); - self.check_pat_ident(pat, *ba, *var_id, sub, expected, def_bm, discrim_span) + PatKind::Binding(binding, sub) => { + self.check_pat_binding(pat, binding, sub.as_deref(), expected, def_bm, discrim_span) } PatKind::TupleStruct(qpath, subpats, ddpos) => self.check_pat_tuple_struct( pat, @@ -420,20 +419,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } - fn check_pat_ident( + fn check_pat_binding( &self, pat: &Pat, - ba: hir::BindingAnnotation, - var_id: HirId, + hir::Binding { annot, hir_id: var_id, ident: _ }: &'tcx hir::Binding, sub: Option<&'tcx Pat>, expected: Ty<'tcx>, def_bm: BindingMode, discrim_span: Option, ) -> Ty<'tcx> { // Determine the binding mode... - let bm = match ba { + let bm = match annot { hir::BindingAnnotation::Unannotated => def_bm, - _ => BindingMode::convert(ba), + _ => BindingMode::convert(*annot), }; // ...and store it in a side table: self.inh.tables.borrow_mut().pat_binding_modes_mut().insert(pat.hir_id, bm); @@ -462,8 +460,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If there are multiple arms, make sure they all agree on // what the type of the binding `x` ought to be. - if var_id != pat.hir_id { - let vt = self.local_ty(pat.span, var_id).decl_ty; + if *var_id != pat.hir_id { + let vt = self.local_ty(pat.span, *var_id).decl_ty; self.demand_eqtype_pat(pat.span, vt, local_ty, discrim_span); } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 149f27ed305fb..6a279d2d2f67d 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -369,7 +369,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { fn constrain_bindings_in_pat(&mut self, pat: &hir::Pat) { debug!("regionck::visit_pat(pat={:?})", pat); - pat.each_binding(|_, hir_id, span, _| { + pat.each_binding(|&hir::Binding { annot: _, hir_id, ident: _ }, span| { // If we have a variable that contains region'd data, that // data will be accessible from anywhere that the variable is // accessed. We must be wary of loops like this: diff --git a/src/librustc_typeck/expr_use_visitor.rs b/src/librustc_typeck/expr_use_visitor.rs index f3f5e54edd195..c787f8a5b2233 100644 --- a/src/librustc_typeck/expr_use_visitor.rs +++ b/src/librustc_typeck/expr_use_visitor.rs @@ -532,7 +532,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { let tcx = self.tcx(); let ExprUseVisitor { ref mc, ref mut delegate } = *self; return_if_err!(mc.cat_pattern(discr_place.clone(), pat, |place, pat| { - if let PatKind::Binding(_, canonical_id, ..) = pat.kind { + if let PatKind::Binding(hir::Binding { annot: _, hir_id: canonical_id, ident: _ }, _) = + pat.kind + { debug!("walk_pat: binding place={:?} pat={:?}", place, pat,); if let Some(bm) = mc.tables.extract_binding_mode(tcx.sess, pat.hir_id, pat.span) { debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm); diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index e52afe501c34f..bdff82d12a3bd 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -417,7 +417,7 @@ pub fn name_from_pat(p: &hir::Pat) -> String { match p.kind { PatKind::Wild => "_".to_string(), - PatKind::Binding(_, _, ident, _) => ident.to_string(), + PatKind::Binding(hir::Binding { annot: _, hir_id: _, ident }, _) => ident.to_string(), PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p), PatKind::Struct(ref name, ref fields, etc) => format!( "{} {{ {}{} }}", diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index c98942abaf3c2..382139077d29c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -485,6 +485,10 @@ pub struct Block { pub span: Span, } +// `Pat` is used a lot. Make sure it doesn't unintentionally get bigger. +#[cfg(target_arch = "x86_64")] +rustc_data_structures::static_assert_size!(Pat, 80); + #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Pat { pub id: NodeId, @@ -499,10 +503,11 @@ impl Pat { let kind = match &self.kind { // In a type expression `_` is an inference variable. PatKind::Wild => TyKind::Infer, - // An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`. - PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None) => { - TyKind::Path(None, Path::from_ident(*ident)) - } + // An binding pattern with no binding mode would be valid as path to a type. E.g. `u32`. + PatKind::Binding( + Binding { mode: BindingMode::ByValue(Mutability::Not), ident }, + None, + ) => TyKind::Path(None, Path::from_ident(*ident)), PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()), PatKind::Mac(mac) => TyKind::Mac(mac.clone()), // `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type. @@ -537,8 +542,8 @@ impl Pat { } match &self.kind { - // Walk into the pattern associated with `Ident` (if any). - PatKind::Ident(_, _, Some(p)) => p.walk(it), + // Walk into the `sub` part of `binding @ sub`. + PatKind::Binding(_, Some(p)) => p.walk(it), // Walk into each field of struct. PatKind::Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)), @@ -556,7 +561,7 @@ impl Pat { | PatKind::Rest | PatKind::Lit(_) | PatKind::Range(..) - | PatKind::Ident(..) + | PatKind::Binding(..) | PatKind::Path(..) | PatKind::Mac(_) => {} } @@ -595,6 +600,13 @@ pub enum BindingMode { ByValue(Mutability), } +/// The `{ref mut?}? $ident` part of a binding pattern (`PatKind::Binding`). +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)] +pub struct Binding { + pub mode: BindingMode, + pub ident: Ident, +} + #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub enum RangeEnd { Included(RangeSyntax), @@ -614,11 +626,11 @@ pub enum PatKind { /// Represents a wildcard pattern (`_`). Wild, - /// A `PatKind::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`), + /// A `PatKind::Binding` may either be a new bound variable (`ref mut binding @ OPT_SUBPAT`), /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens /// during name resolution. - Ident(BindingMode, Ident, Option>), + Binding(Binding, Option>), /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`). /// The `bool` is `true` in the presence of a `..`. @@ -2009,29 +2021,30 @@ pub type ExplicitSelf = Spanned; impl Param { /// Attempts to cast parameter to `ExplicitSelf`. pub fn to_self(&self) -> Option { - if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.kind { - if ident.name == kw::SelfLower { - return match self.ty.kind { - TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))), - TyKind::Rptr(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => { - Some(respan(self.pat.span, SelfKind::Region(lt, mutbl))) - } - _ => Some(respan( - self.pat.span.to(self.ty.span), - SelfKind::Explicit(self.ty.clone(), mutbl), - )), - }; - } + if let PatKind::Binding( + Binding { mode: BindingMode::ByValue(mutbl), ident: Ident { name: kw::SelfLower, .. } }, + _, + ) = self.pat.kind + { + return match self.ty.kind { + TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))), + TyKind::Rptr(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => { + Some(respan(self.pat.span, SelfKind::Region(lt, mutbl))) + } + _ => Some(respan( + self.pat.span.to(self.ty.span), + SelfKind::Explicit(self.ty.clone(), mutbl), + )), + }; } None } /// Returns `true` if parameter is `self`. pub fn is_self(&self) -> bool { - if let PatKind::Ident(_, ident, _) = self.pat.kind { - ident.name == kw::SelfLower - } else { - false + match self.pat.kind { + PatKind::Binding(Binding { ident: Ident { name: kw::SelfLower, .. }, .. }, _) => true, + _ => false, } } @@ -2039,17 +2052,10 @@ impl Param { pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param { let span = eself.span.to(eself_ident.span); let infer_ty = P(Ty { id: DUMMY_NODE_ID, kind: TyKind::ImplicitSelf, span }); - let param = |mutbl, ty| Param { - attrs, - pat: P(Pat { - id: DUMMY_NODE_ID, - kind: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None), - span, - }), - span, - ty, - id: DUMMY_NODE_ID, - is_placeholder: false, + let param = |mutbl, ty| { + let binding = Binding { mode: BindingMode::ByValue(mutbl), ident: eself_ident }; + let pat = P(Pat { id: DUMMY_NODE_ID, kind: PatKind::Binding(binding, None), span }); + Param { attrs, pat, span, ty, id: DUMMY_NODE_ID, is_placeholder: false } }; match eself.node { SelfKind::Explicit(ty, mutbl) => param(mutbl, ty), diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index 6fd926f2048c6..14eeba2ea274e 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -581,7 +581,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { for pat in &*pats { let span = pat.span; let inner_pat = match &pat.kind { - PatKind::Ident(.., Some(pat)) => pat, + PatKind::Binding(.., Some(pat)) => pat, _ => pat, }; if inner_pat.is_rest() { diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index f6817c713a4a6..3e2ade0b0bd97 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -134,6 +134,10 @@ pub trait MutVisitor: Sized { noop_visit_pat(p, self); } + fn visit_binding(&mut self, b: &mut Binding) { + noop_visit_binding(b, self) + } + fn visit_anon_const(&mut self, c: &mut AnonConst) { noop_visit_anon_const(c, self); } @@ -1049,13 +1053,17 @@ pub fn noop_flat_map_foreign_item( smallvec![item] } +pub fn noop_visit_binding(Binding { ident, mode: _ }: &mut Binding, vis: &mut T) { + vis.visit_ident(ident); +} + pub fn noop_visit_pat(pat: &mut P, vis: &mut T) { let Pat { id, kind, span } = pat.deref_mut(); vis.visit_id(id); match kind { PatKind::Wild | PatKind::Rest => {} - PatKind::Ident(_binding_mode, ident, sub) => { - vis.visit_ident(ident); + PatKind::Binding(binding, sub) => { + vis.visit_binding(binding); visit_opt(sub, |sub| vis.visit_pat(sub)); } PatKind::Lit(e) => vis.visit_expr(e), diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index b1b667f03bee2..e2dec30df9fb0 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1,4 +1,4 @@ -use crate::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; +use crate::ast::{self, Binding, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; use crate::ast::{Attribute, GenericArg, MacArgs}; use crate::ast::{GenericBound, SelfKind, TraitBoundModifier}; use crate::attr; @@ -2242,6 +2242,18 @@ impl<'a> State<'a> { } } + fn print_binding(&mut self, Binding { mode, ident }: Binding) { + match mode { + ast::BindingMode::ByRef(mutbl) => { + self.word_nbsp("ref"); + self.print_mutability(mutbl, false); + } + ast::BindingMode::ByValue(ast::Mutability::Not) => {} + ast::BindingMode::ByValue(ast::Mutability::Mut) => self.word_nbsp("mut"), + } + self.print_ident(ident); + } + crate fn print_pat(&mut self, pat: &ast::Pat) { self.maybe_print_comment(pat.span.lo()); self.ann.pre(self, AnnNode::Pat(pat)); @@ -2249,18 +2261,8 @@ impl<'a> State<'a> { is that it doesn't matter */ match pat.kind { PatKind::Wild => self.s.word("_"), - PatKind::Ident(binding_mode, ident, ref sub) => { - match binding_mode { - ast::BindingMode::ByRef(mutbl) => { - self.word_nbsp("ref"); - self.print_mutability(mutbl, false); - } - ast::BindingMode::ByValue(ast::Mutability::Not) => {} - ast::BindingMode::ByValue(ast::Mutability::Mut) => { - self.word_nbsp("mut"); - } - } - self.print_ident(ident); + PatKind::Binding(binding, ref sub) => { + self.print_binding(binding); if let Some(ref p) = *sub { self.s.space(); self.s.word_space("@"); @@ -2658,10 +2660,9 @@ impl<'a> State<'a> { if let Some(eself) = input.to_self() { self.print_explicit_self(&eself); } else { - let invalid = if let PatKind::Ident(_, ident, _) = input.pat.kind { - ident.name == kw::Invalid - } else { - false + let invalid = match input.pat.kind { + PatKind::Binding(Binding { ident, .. }, _) => ident.name == kw::Invalid, + _ => false, }; if !invalid { self.print_pat(&input.pat); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index fbc5d1332490f..579ca945dc752 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -84,6 +84,9 @@ pub trait Visitor<'ast>: Sized { fn visit_arm(&mut self, a: &'ast Arm) { walk_arm(self, a) } + fn visit_binding(&mut self, b: &'ast Binding) { + walk_binding(self, b) + } fn visit_pat(&mut self, p: &'ast Pat) { walk_pat(self, p) } @@ -467,6 +470,10 @@ pub fn walk_assoc_ty_constraint<'a, V: Visitor<'a>>( } } +pub fn walk_binding<'a, V: Visitor<'a>>(visitor: &mut V, Binding { ident, mode: _ }: &'a Binding) { + visitor.visit_ident(*ident); +} + pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { match pattern.kind { PatKind::TupleStruct(ref path, ref elems) => { @@ -486,9 +493,9 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { PatKind::Box(ref subpattern) | PatKind::Ref(ref subpattern, _) | PatKind::Paren(ref subpattern) => visitor.visit_pat(subpattern), - PatKind::Ident(_, ident, ref optional_subpattern) => { - visitor.visit_ident(ident); - walk_list!(visitor, visit_pat, optional_subpattern); + PatKind::Binding(ref binding, ref subpat) => { + visitor.visit_binding(binding); + walk_list!(visitor, visit_pat, subpat); } PatKind::Lit(ref expression) => visitor.visit_expr(expression), PatKind::Range(ref lower_bound, ref upper_bound, _) => { diff --git a/src/libsyntax_expand/build.rs b/src/libsyntax_expand/build.rs index 96020acb3b4eb..43179e4d28f39 100644 --- a/src/libsyntax_expand/build.rs +++ b/src/libsyntax_expand/build.rs @@ -1,6 +1,6 @@ use crate::base::ExtCtxt; -use syntax::ast::{self, AttrVec, BlockCheckMode, Expr, Ident, PatKind, UnOp}; +use syntax::ast::{self, AttrVec, Binding, BlockCheckMode, Expr, Ident, PatKind, UnOp}; use syntax::attr; use syntax::ptr::P; use syntax::source_map::{respan, Spanned}; @@ -419,9 +419,9 @@ impl<'a> ExtCtxt<'a> { &self, span: Span, ident: ast::Ident, - bm: ast::BindingMode, + mode: ast::BindingMode, ) -> P { - let pat = PatKind::Ident(bm, ident.with_span_pos(span), None); + let pat = PatKind::Binding(Binding { mode, ident: ident.with_span_pos(span) }, None); self.pat(span, pat) } pub fn pat_path(&self, span: Span, path: ast::Path) -> P { diff --git a/src/libsyntax_expand/parse/tests.rs b/src/libsyntax_expand/parse/tests.rs index 154ccb256216c..0c9f37f35195a 100644 --- a/src/libsyntax_expand/parse/tests.rs +++ b/src/libsyntax_expand/parse/tests.rs @@ -166,20 +166,13 @@ fn get_spans_of_pat_idents(src: &str) -> Vec { spans: Vec, } impl<'a> visit::Visitor<'a> for PatIdentVisitor { - fn visit_pat(&mut self, p: &'a ast::Pat) { - match p.kind { - PatKind::Ident(_, ref ident, _) => { - self.spans.push(ident.span.clone()); - } - _ => { - visit::walk_pat(self, p); - } - } + fn visit_binding(&mut self, ast::Binding(_, ast::Ident { span, .. }): &'a ast::Binding) { + self.spans.push(*span); } } let mut v = PatIdentVisitor { spans: Vec::new() }; visit::walk_item(&mut v, &item); - return v.spans; + v.spans } #[test] diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 454f197220c54..18fda52788b92 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -181,7 +181,7 @@ use std::cell::RefCell; use std::iter; use std::vec; -use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind}; +use syntax::ast::{self, BinOpKind, Binding, EnumDef, Expr, Generics, Ident, PatKind}; use syntax::ast::{GenericArg, GenericParamKind, VariantData}; use syntax::attr; use syntax::ptr::P; @@ -1601,12 +1601,12 @@ impl<'a> TraitDef<'a> { field_paths .iter() .map(|path| { - let binding_mode = if use_temporaries { + let mode = if use_temporaries { ast::BindingMode::ByValue(ast::Mutability::Not) } else { ast::BindingMode::ByRef(mutbl) }; - cx.pat(path.span, PatKind::Ident(binding_mode, (*path).clone(), None)) + cx.pat(path.span, PatKind::Binding(Binding { mode, ident: (*path).clone() }, None)) }) .collect() } diff --git a/src/test/ui/anon-params-deprecated.stderr b/src/test/ui/anon-params-deprecated.stderr index e97dbc15f9cde..8e4fa70d342f2 100644 --- a/src/test/ui/anon-params-deprecated.stderr +++ b/src/test/ui/anon-params-deprecated.stderr @@ -2,7 +2,7 @@ warning: anonymous parameters are deprecated and will be removed in the next edi --> $DIR/anon-params-deprecated.rs:9:12 | LL | fn foo(i32); - | ^^^ help: Try naming the parameter or explicitly ignoring it: `_: i32` + | ^^^ help: try naming the parameter or explicitly ignoring it: `_: i32` | note: lint level defined here --> $DIR/anon-params-deprecated.rs:1:9 @@ -16,7 +16,7 @@ warning: anonymous parameters are deprecated and will be removed in the next edi --> $DIR/anon-params-deprecated.rs:12:30 | LL | fn bar_with_default_impl(String, String) {} - | ^^^^^^ help: Try naming the parameter or explicitly ignoring it: `_: String` + | ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #41686 @@ -25,7 +25,7 @@ warning: anonymous parameters are deprecated and will be removed in the next edi --> $DIR/anon-params-deprecated.rs:12:38 | LL | fn bar_with_default_impl(String, String) {} - | ^^^^^^ help: Try naming the parameter or explicitly ignoring it: `_: String` + | ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #41686 diff --git a/src/test/ui/future-incompatible-lint-group.stderr b/src/test/ui/future-incompatible-lint-group.stderr index 24e3a077ae6e3..1d958e5bfeb40 100644 --- a/src/test/ui/future-incompatible-lint-group.stderr +++ b/src/test/ui/future-incompatible-lint-group.stderr @@ -2,7 +2,7 @@ error: anonymous parameters are deprecated and will be removed in the next editi --> $DIR/future-incompatible-lint-group.rs:4:10 | LL | fn f(u8) {} - | ^^ help: Try naming the parameter or explicitly ignoring it: `_: u8` + | ^^ help: try naming the parameter or explicitly ignoring it: `_: u8` | note: lint level defined here --> $DIR/future-incompatible-lint-group.rs:1:9