1
Fork 0

Refactor and re-use BindingAnnotation

This commit is contained in:
Cameron Steffen 2022-08-30 17:34:35 -05:00
parent 9353538c7b
commit 02ba216e3c
25 changed files with 176 additions and 225 deletions

View file

@ -594,7 +594,7 @@ impl Pat {
// In a type expression `_` is an inference variable. // In a type expression `_` is an inference variable.
PatKind::Wild => TyKind::Infer, PatKind::Wild => TyKind::Infer,
// An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`. // 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) => { PatKind::Ident(BindingAnnotation::NONE, ident, None) => {
TyKind::Path(None, Path::from_ident(*ident)) TyKind::Path(None, Path::from_ident(*ident))
} }
PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()), PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
@ -681,10 +681,43 @@ pub struct PatField {
pub is_placeholder: bool, pub is_placeholder: bool,
} }
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum BindingMode { #[derive(Encodable, Decodable, HashStable_Generic)]
ByRef(Mutability), pub enum ByRef {
ByValue(Mutability), Yes,
No,
}
impl From<bool> for ByRef {
fn from(b: bool) -> ByRef {
match b {
false => ByRef::No,
true => ByRef::Yes,
}
}
}
/// 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.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[derive(Encodable, Decodable, HashStable_Generic)]
pub struct BindingAnnotation(pub ByRef, pub Mutability);
impl BindingAnnotation {
pub const NONE: Self = Self(ByRef::No, Mutability::Not);
pub const REF: Self = Self(ByRef::Yes, Mutability::Not);
pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
pub const REF_MUT: Self = Self(ByRef::Yes, Mutability::Mut);
pub fn prefix_str(self) -> &'static str {
match self {
Self::NONE => "",
Self::REF => "ref ",
Self::MUT => "mut ",
Self::REF_MUT => "ref mut ",
}
}
} }
#[derive(Clone, Encodable, Decodable, Debug)] #[derive(Clone, Encodable, Decodable, Debug)]
@ -713,7 +746,7 @@ pub enum PatKind {
/// or a unit struct/variant pattern, or a const pattern (in the last two cases the third /// 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 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
/// during name resolution. /// during name resolution.
Ident(BindingMode, Ident, Option<P<Pat>>), Ident(BindingAnnotation, Ident, Option<P<Pat>>),
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`). /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
/// The `bool` is `true` in the presence of a `..`. /// The `bool` is `true` in the presence of a `..`.
@ -2228,7 +2261,7 @@ pub type ExplicitSelf = Spanned<SelfKind>;
impl Param { impl Param {
/// Attempts to cast parameter to `ExplicitSelf`. /// Attempts to cast parameter to `ExplicitSelf`.
pub fn to_self(&self) -> Option<ExplicitSelf> { pub fn to_self(&self) -> Option<ExplicitSelf> {
if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.kind { if let PatKind::Ident(BindingAnnotation(ByRef::No, mutbl), ident, _) = self.pat.kind {
if ident.name == kw::SelfLower { if ident.name == kw::SelfLower {
return match self.ty.kind { return match self.ty.kind {
TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))), TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
@ -2258,23 +2291,10 @@ impl Param {
pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param { pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
let span = eself.span.to(eself_ident.span); let span = eself.span.to(eself_ident.span);
let infer_ty = P(Ty { id: DUMMY_NODE_ID, kind: TyKind::ImplicitSelf, span, tokens: None }); let infer_ty = P(Ty { id: DUMMY_NODE_ID, kind: TyKind::ImplicitSelf, span, tokens: None });
let param = |mutbl, ty| Param { let (mutbl, ty) = match eself.node {
attrs, SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
pat: P(Pat { SelfKind::Value(mutbl) => (mutbl, infer_ty),
id: DUMMY_NODE_ID, SelfKind::Region(lt, mutbl) => (
kind: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
span,
tokens: None,
}),
span,
ty,
id: DUMMY_NODE_ID,
is_placeholder: false,
};
match eself.node {
SelfKind::Explicit(ty, mutbl) => param(mutbl, ty),
SelfKind::Value(mutbl) => param(mutbl, infer_ty),
SelfKind::Region(lt, mutbl) => param(
Mutability::Not, Mutability::Not,
P(Ty { P(Ty {
id: DUMMY_NODE_ID, id: DUMMY_NODE_ID,
@ -2283,6 +2303,19 @@ impl Param {
tokens: None, tokens: None,
}), }),
), ),
};
Param {
attrs,
pat: P(Pat {
id: DUMMY_NODE_ID,
kind: PatKind::Ident(BindingAnnotation(ByRef::No, mutbl), eself_ident, None),
span,
tokens: None,
}),
span,
ty,
id: DUMMY_NODE_ID,
is_placeholder: false,
} }
} }
} }

View file

@ -577,7 +577,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (pat, task_context_hid) = self.pat_ident_binding_mode( let (pat, task_context_hid) = self.pat_ident_binding_mode(
span, span,
Ident::with_dummy_span(sym::_task_context), Ident::with_dummy_span(sym::_task_context),
hir::BindingAnnotation::Mutable, hir::BindingAnnotation::MUT,
); );
let param = hir::Param { let param = hir::Param {
hir_id: self.next_id(), hir_id: self.next_id(),
@ -671,7 +671,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// this name to identify what is being awaited by a suspended async functions. // this name to identify what is being awaited by a suspended async functions.
let awaitee_ident = Ident::with_dummy_span(sym::__awaitee); let awaitee_ident = Ident::with_dummy_span(sym::__awaitee);
let (awaitee_pat, awaitee_pat_hid) = let (awaitee_pat, awaitee_pat_hid) =
self.pat_ident_binding_mode(span, awaitee_ident, hir::BindingAnnotation::Mutable); self.pat_ident_binding_mode(span, awaitee_ident, hir::BindingAnnotation::MUT);
let task_context_ident = Ident::with_dummy_span(sym::_task_context); let task_context_ident = Ident::with_dummy_span(sym::_task_context);
@ -1433,7 +1433,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `mut iter` // `mut iter`
let iter = Ident::with_dummy_span(sym::iter); let iter = Ident::with_dummy_span(sym::iter);
let (iter_pat, iter_pat_nid) = let (iter_pat, iter_pat_nid) =
self.pat_ident_binding_mode(head_span, iter, hir::BindingAnnotation::Mutable); self.pat_ident_binding_mode(head_span, iter, hir::BindingAnnotation::MUT);
// `match Iterator::next(&mut iter) { ... }` // `match Iterator::next(&mut iter) { ... }`
let match_expr = { let match_expr = {

View file

@ -1074,12 +1074,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Check if this is a binding pattern, if so, we can optimize and avoid adding a // Check if this is a binding pattern, if so, we can optimize and avoid adding a
// `let <pat> = __argN;` statement. In this case, we do not rename the parameter. // `let <pat> = __argN;` statement. In this case, we do not rename the parameter.
let (ident, is_simple_parameter) = match parameter.pat.kind { let (ident, is_simple_parameter) = match parameter.pat.kind {
hir::PatKind::Binding( hir::PatKind::Binding(hir::BindingAnnotation(ByRef::No, _), _, ident, _) => {
hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Mutable, (ident, true)
_, }
ident,
_,
) => (ident, true),
// For `ref mut` or wildcard arguments, we can't reuse the binding, but // For `ref mut` or wildcard arguments, we can't reuse the binding, but
// we can keep the same name for the parameter. // we can keep the same name for the parameter.
// This lets rustdoc render it correctly in documentation. // This lets rustdoc render it correctly in documentation.
@ -1144,7 +1141,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (move_pat, move_id) = this.pat_ident_binding_mode( let (move_pat, move_id) = this.pat_ident_binding_mode(
desugared_span, desugared_span,
ident, ident,
hir::BindingAnnotation::Mutable, hir::BindingAnnotation::MUT,
); );
let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id); let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
let move_stmt = this.stmt_let_pat( let move_stmt = this.stmt_let_pat(

View file

@ -1696,10 +1696,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
output, output,
c_variadic, c_variadic,
implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| { implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
use BindingMode::{ByRef, ByValue};
let is_mutable_pat = matches!( let is_mutable_pat = matches!(
arg.pat.kind, arg.pat.kind,
PatKind::Ident(ByValue(Mutability::Mut) | ByRef(Mutability::Mut), ..) PatKind::Ident(hir::BindingAnnotation(_, Mutability::Mut), ..)
); );
match arg.ty.kind { match arg.ty.kind {
@ -2361,11 +2360,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) { fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) {
self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated) self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::NONE)
} }
fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, hir::HirId) { fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, hir::HirId) {
self.pat_ident_binding_mode_mut(span, ident, hir::BindingAnnotation::Unannotated) self.pat_ident_binding_mode_mut(span, ident, hir::BindingAnnotation::NONE)
} }
fn pat_ident_binding_mode( fn pat_ident_binding_mode(

View file

@ -24,7 +24,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let node = loop { let node = loop {
match pattern.kind { match pattern.kind {
PatKind::Wild => break hir::PatKind::Wild, PatKind::Wild => break hir::PatKind::Wild,
PatKind::Ident(ref binding_mode, ident, ref sub) => { PatKind::Ident(binding_mode, ident, ref sub) => {
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s)); let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s));
break self.lower_pat_ident(pattern, binding_mode, ident, lower_sub); break self.lower_pat_ident(pattern, binding_mode, ident, lower_sub);
} }
@ -176,9 +176,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let mut prev_rest_span = None; let mut prev_rest_span = None;
// Lowers `$bm $ident @ ..` to `$bm $ident @ _`. // Lowers `$bm $ident @ ..` to `$bm $ident @ _`.
let lower_rest_sub = |this: &mut Self, pat, bm, ident, sub| { let lower_rest_sub = |this: &mut Self, pat, ann, ident, sub| {
let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub)); let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub));
let node = this.lower_pat_ident(pat, bm, ident, lower_sub); let node = this.lower_pat_ident(pat, ann, ident, lower_sub);
this.pat_with_node_id_of(pat, node) this.pat_with_node_id_of(pat, node)
}; };
@ -194,9 +194,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
// Found a sub-slice pattern `$binding_mode $ident @ ..`. // Found a sub-slice pattern `$binding_mode $ident @ ..`.
// Record, lower it to `$binding_mode $ident @ _`, and stop here. // Record, lower it to `$binding_mode $ident @ _`, and stop here.
PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => { PatKind::Ident(ann, ident, Some(ref sub)) if sub.is_rest() => {
prev_rest_span = Some(sub.span); prev_rest_span = Some(sub.span);
slice = Some(self.arena.alloc(lower_rest_sub(self, pat, bm, ident, sub))); slice = Some(self.arena.alloc(lower_rest_sub(self, pat, ann, ident, sub)));
break; break;
} }
// It was not a subslice pattern so lower it normally. // It was not a subslice pattern so lower it normally.
@ -209,9 +209,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// There was a previous subslice pattern; make sure we don't allow more. // There was a previous subslice pattern; make sure we don't allow more.
let rest_span = match pat.kind { let rest_span = match pat.kind {
PatKind::Rest => Some(pat.span), PatKind::Rest => Some(pat.span),
PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => { PatKind::Ident(ann, ident, Some(ref sub)) if sub.is_rest() => {
// #69103: Lower into `binding @ _` as above to avoid ICEs. // #69103: Lower into `binding @ _` as above to avoid ICEs.
after.push(lower_rest_sub(self, pat, bm, ident, sub)); after.push(lower_rest_sub(self, pat, ann, ident, sub));
Some(sub.span) Some(sub.span)
} }
_ => None, _ => None,
@ -235,7 +235,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_pat_ident( fn lower_pat_ident(
&mut self, &mut self,
p: &Pat, p: &Pat,
binding_mode: &BindingMode, annotation: BindingAnnotation,
ident: Ident, ident: Ident,
lower_sub: impl FnOnce(&mut Self) -> Option<&'hir hir::Pat<'hir>>, lower_sub: impl FnOnce(&mut Self) -> Option<&'hir hir::Pat<'hir>>,
) -> hir::PatKind<'hir> { ) -> hir::PatKind<'hir> {
@ -248,7 +248,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}; };
hir::PatKind::Binding( hir::PatKind::Binding(
self.lower_binding_mode(binding_mode), annotation,
self.lower_node_id(canonical_id), self.lower_node_id(canonical_id),
self.lower_ident(ident), self.lower_ident(ident),
lower_sub(self), lower_sub(self),
@ -265,15 +265,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
} }
fn lower_binding_mode(&mut self, b: &BindingMode) -> hir::BindingAnnotation {
match *b {
BindingMode::ByValue(Mutability::Not) => hir::BindingAnnotation::Unannotated,
BindingMode::ByRef(Mutability::Not) => hir::BindingAnnotation::Ref,
BindingMode::ByValue(Mutability::Mut) => hir::BindingAnnotation::Mutable,
BindingMode::ByRef(Mutability::Mut) => hir::BindingAnnotation::RefMut,
}
}
fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> { fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> {
self.arena.alloc(self.pat_with_node_id_of(p, hir::PatKind::Wild)) self.arena.alloc(self.pat_with_node_id_of(p, hir::PatKind::Wild))
} }

View file

@ -281,8 +281,8 @@ impl<'a> AstValidator<'a> {
fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option<Ident>, bool)) { fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option<Ident>, bool)) {
for Param { pat, .. } in &decl.inputs { for Param { pat, .. } in &decl.inputs {
match pat.kind { match pat.kind {
PatKind::Ident(BindingMode::ByValue(Mutability::Not), _, None) | PatKind::Wild => {} PatKind::Ident(BindingAnnotation::NONE, _, None) | PatKind::Wild => {}
PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ident, None) => { PatKind::Ident(BindingAnnotation::MUT, ident, None) => {
report_err(pat.span, Some(ident), true) report_err(pat.span, Some(ident), true)
} }
_ => report_err(pat.span, None, false), _ => report_err(pat.span, None, false),

View file

@ -11,8 +11,8 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
use rustc_ast::util::classify; use rustc_ast::util::classify;
use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle}; use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle};
use rustc_ast::util::parser; use rustc_ast::util::parser;
use rustc_ast::{self as ast, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; use rustc_ast::{self as ast, BlockCheckMode, Mutability, PatKind, RangeEnd, RangeSyntax};
use rustc_ast::{attr, Term}; use rustc_ast::{attr, BindingAnnotation, ByRef, Term};
use rustc_ast::{GenericArg, MacArgs, MacArgsEq}; use rustc_ast::{GenericArg, MacArgs, MacArgsEq};
use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier}; use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier};
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass}; use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
@ -1399,16 +1399,12 @@ impl<'a> State<'a> {
is that it doesn't matter */ is that it doesn't matter */
match pat.kind { match pat.kind {
PatKind::Wild => self.word("_"), PatKind::Wild => self.word("_"),
PatKind::Ident(binding_mode, ident, ref sub) => { PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, ref sub) => {
match binding_mode { if by_ref == ByRef::Yes {
ast::BindingMode::ByRef(mutbl) => { self.word_nbsp("ref");
self.word_nbsp("ref"); }
self.print_mutability(mutbl, false); if mutbl == Mutability::Mut {
} self.word_nbsp("mut");
ast::BindingMode::ByValue(ast::Mutability::Not) => {}
ast::BindingMode::ByValue(ast::Mutability::Mut) => {
self.word_nbsp("mut");
}
} }
self.print_ident(ident); self.print_ident(ident);
if let Some(ref p) = *sub { if let Some(ref p) = *sub {
@ -1487,12 +1483,10 @@ impl<'a> State<'a> {
} }
PatKind::Ref(ref inner, mutbl) => { PatKind::Ref(ref inner, mutbl) => {
self.word("&"); self.word("&");
if mutbl == ast::Mutability::Mut { if mutbl == Mutability::Mut {
self.word("mut "); self.word("mut ");
} }
if let PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Mut), ..) = if let PatKind::Ident(ast::BindingAnnotation::MUT, ..) = inner.kind {
inner.kind
{
self.popen(); self.popen();
self.print_pat(inner); self.print_pat(inner);
self.pclose(); self.pclose();

View file

@ -367,7 +367,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if let Some(Node::Pat(pat)) = self.infcx.tcx.hir().find(upvar_hir_id) if let Some(Node::Pat(pat)) = self.infcx.tcx.hir().find(upvar_hir_id)
&& let hir::PatKind::Binding( && let hir::PatKind::Binding(
hir::BindingAnnotation::Unannotated, hir::BindingAnnotation::NONE,
_, _,
upvar_ident, upvar_ident,
_, _,

View file

@ -164,7 +164,9 @@ pub use SubstructureFields::*;
use crate::deriving; use crate::deriving;
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::{self as ast, EnumDef, Expr, Generics, PatKind}; use rustc_ast::{
self as ast, BindingAnnotation, ByRef, EnumDef, Expr, Generics, Mutability, PatKind,
};
use rustc_ast::{GenericArg, GenericParamKind, VariantData}; use rustc_ast::{GenericArg, GenericParamKind, VariantData};
use rustc_attr as attr; use rustc_attr as attr;
use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_expand::base::{Annotatable, ExtCtxt};
@ -1063,9 +1065,9 @@ impl<'a> MethodDef<'a> {
let mut body = mk_body(cx, selflike_fields); let mut body = mk_body(cx, selflike_fields);
let struct_path = cx.path(span, vec![Ident::new(kw::SelfUpper, type_ident.span)]); let struct_path = cx.path(span, vec![Ident::new(kw::SelfUpper, type_ident.span)]);
let use_ref_pat = is_packed && !always_copy; let by_ref = ByRef::from(is_packed && !always_copy);
let patterns = let patterns =
trait_.create_struct_patterns(cx, struct_path, struct_def, &prefixes, use_ref_pat); trait_.create_struct_patterns(cx, struct_path, struct_def, &prefixes, by_ref);
// Do the let-destructuring. // Do the let-destructuring.
let mut stmts: Vec<_> = iter::zip(selflike_args, patterns) let mut stmts: Vec<_> = iter::zip(selflike_args, patterns)
@ -1247,13 +1249,13 @@ impl<'a> MethodDef<'a> {
let sp = variant.span.with_ctxt(trait_.span.ctxt()); let sp = variant.span.with_ctxt(trait_.span.ctxt());
let variant_path = cx.path(sp, vec![type_ident, variant.ident]); let variant_path = cx.path(sp, vec![type_ident, variant.ident]);
let use_ref_pat = false; // because enums can't be repr(packed) let by_ref = ByRef::No; // because enums can't be repr(packed)
let mut subpats: Vec<_> = trait_.create_struct_patterns( let mut subpats: Vec<_> = trait_.create_struct_patterns(
cx, cx,
variant_path, variant_path,
&variant.data, &variant.data,
&prefixes, &prefixes,
use_ref_pat, by_ref,
); );
// `(VariantK, VariantK, ...)` or just `VariantK`. // `(VariantK, VariantK, ...)` or just `VariantK`.
@ -1414,7 +1416,7 @@ impl<'a> TraitDef<'a> {
struct_path: ast::Path, struct_path: ast::Path,
struct_def: &'a VariantData, struct_def: &'a VariantData,
prefixes: &[String], prefixes: &[String],
use_ref_pat: bool, by_ref: ByRef,
) -> Vec<P<ast::Pat>> { ) -> Vec<P<ast::Pat>> {
prefixes prefixes
.iter() .iter()
@ -1422,17 +1424,19 @@ impl<'a> TraitDef<'a> {
let pieces_iter = let pieces_iter =
struct_def.fields().iter().enumerate().map(|(i, struct_field)| { struct_def.fields().iter().enumerate().map(|(i, struct_field)| {
let sp = struct_field.span.with_ctxt(self.span.ctxt()); let sp = struct_field.span.with_ctxt(self.span.ctxt());
let binding_mode = if use_ref_pat {
ast::BindingMode::ByRef(ast::Mutability::Not)
} else {
ast::BindingMode::ByValue(ast::Mutability::Not)
};
let ident = self.mk_pattern_ident(prefix, i); let ident = self.mk_pattern_ident(prefix, i);
let path = ident.with_span_pos(sp); let path = ident.with_span_pos(sp);
( (
sp, sp,
struct_field.ident, struct_field.ident,
cx.pat(path.span, PatKind::Ident(binding_mode, path, None)), cx.pat(
path.span,
PatKind::Ident(
BindingAnnotation(by_ref, Mutability::Not),
path,
None,
),
),
) )
}); });

View file

@ -178,8 +178,7 @@ impl<'a> ExtCtxt<'a> {
ex: P<ast::Expr>, ex: P<ast::Expr>,
) -> ast::Stmt { ) -> ast::Stmt {
let pat = if mutbl { let pat = if mutbl {
let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Mut); self.pat_ident_binding_mode(sp, ident, ast::BindingAnnotation::MUT)
self.pat_ident_binding_mode(sp, ident, binding_mode)
} else { } else {
self.pat_ident(sp, ident) self.pat_ident(sp, ident)
}; };
@ -445,17 +444,16 @@ impl<'a> ExtCtxt<'a> {
self.pat(span, PatKind::Lit(expr)) self.pat(span, PatKind::Lit(expr))
} }
pub fn pat_ident(&self, span: Span, ident: Ident) -> P<ast::Pat> { pub fn pat_ident(&self, span: Span, ident: Ident) -> P<ast::Pat> {
let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Not); self.pat_ident_binding_mode(span, ident, ast::BindingAnnotation::NONE)
self.pat_ident_binding_mode(span, ident, binding_mode)
} }
pub fn pat_ident_binding_mode( pub fn pat_ident_binding_mode(
&self, &self,
span: Span, span: Span,
ident: Ident, ident: Ident,
bm: ast::BindingMode, ann: ast::BindingAnnotation,
) -> P<ast::Pat> { ) -> P<ast::Pat> {
let pat = PatKind::Ident(bm, ident.with_span_pos(span), None); let pat = PatKind::Ident(ann, ident.with_span_pos(span), None);
self.pat(span, pat) self.pat(span, pat)
} }
pub fn pat_path(&self, span: Span, path: ast::Path) -> P<ast::Pat> { pub fn pat_path(&self, span: Span, path: ast::Path) -> P<ast::Pat> {

View file

@ -7,7 +7,7 @@ use crate::LangItem;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::util::parser::ExprPrecedence;
use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy}; use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy};
pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto}; pub use rustc_ast::{BindingAnnotation, BorrowKind, ByRef, ImplPolarity, IsAuto};
pub use rustc_ast::{CaptureBy, Movability, Mutability}; pub use rustc_ast::{CaptureBy, Movability, Mutability};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fingerprint::Fingerprint;
@ -1049,30 +1049,6 @@ pub struct PatField<'hir> {
pub span: Span, pub span: Span,
} }
/// 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.
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
pub enum BindingAnnotation {
/// No binding annotation given: this means that the final binding mode
/// will depend on whether we have skipped through a `&` reference
/// when matching. For example, the `x` in `Some(x)` will have binding
/// mode `None`; if you do `let Some(x) = &Some(22)`, it will
/// ultimately be inferred to be by-reference.
///
/// Note that implicit reference skipping is not implemented yet (#42640).
Unannotated,
/// Annotated with `mut x` -- could be either ref or not, similar to `None`.
Mutable,
/// Annotated as `ref`, like `ref x`
Ref,
/// Annotated as `ref mut x`.
RefMut,
}
#[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)] #[derive(Copy, Clone, PartialEq, Encodable, Debug, HashStable_Generic)]
pub enum RangeEnd { pub enum RangeEnd {
Included, Included,

View file

@ -1,6 +1,6 @@
use crate::def::{CtorOf, DefKind, Res}; use crate::def::{CtorOf, DefKind, Res};
use crate::def_id::DefId; use crate::def_id::DefId;
use crate::hir::{self, HirId, PatKind}; use crate::hir::{self, BindingAnnotation, ByRef, HirId, PatKind};
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_span::hygiene::DesugaringKind; use rustc_span::hygiene::DesugaringKind;
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
@ -93,12 +93,7 @@ impl hir::Pat<'_> {
pub fn simple_ident(&self) -> Option<Ident> { pub fn simple_ident(&self) -> Option<Ident> {
match self.kind { match self.kind {
PatKind::Binding( PatKind::Binding(BindingAnnotation(ByRef::No, _), _, ident, None) => Some(ident),
hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Mutable,
_,
ident,
None,
) => Some(ident),
_ => None, _ => None,
} }
} }
@ -135,11 +130,11 @@ impl hir::Pat<'_> {
pub fn contains_explicit_ref_binding(&self) -> Option<hir::Mutability> { pub fn contains_explicit_ref_binding(&self) -> Option<hir::Mutability> {
let mut result = None; let mut result = None;
self.each_binding(|annotation, _, _, _| match annotation { self.each_binding(|annotation, _, _, _| match annotation {
hir::BindingAnnotation::Ref => match result { hir::BindingAnnotation::REF => match result {
None | Some(hir::Mutability::Not) => result = Some(hir::Mutability::Not), None | Some(hir::Mutability::Not) => result = Some(hir::Mutability::Not),
_ => {} _ => {}
}, },
hir::BindingAnnotation::RefMut => result = Some(hir::Mutability::Mut), hir::BindingAnnotation::REF_MUT => result = Some(hir::Mutability::Mut),
_ => {} _ => {}
}); });
result result

View file

@ -9,7 +9,9 @@ use rustc_ast_pretty::pp::{self, Breaks};
use rustc_ast_pretty::pprust::{Comments, PrintState}; use rustc_ast_pretty::pprust::{Comments, PrintState};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::LifetimeParamKind; use rustc_hir::LifetimeParamKind;
use rustc_hir::{GenericArg, GenericParam, GenericParamKind, Node, Term}; use rustc_hir::{
BindingAnnotation, ByRef, GenericArg, GenericParam, GenericParamKind, Mutability, Node, Term,
};
use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier}; use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
use rustc_span::source_map::SourceMap; use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol}; use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol};
@ -1758,20 +1760,12 @@ impl<'a> State<'a> {
// is that it doesn't matter // is that it doesn't matter
match pat.kind { match pat.kind {
PatKind::Wild => self.word("_"), PatKind::Wild => self.word("_"),
PatKind::Binding(binding_mode, _, ident, sub) => { PatKind::Binding(BindingAnnotation(by_ref, mutbl), _, ident, sub) => {
match binding_mode { if by_ref == ByRef::Yes {
hir::BindingAnnotation::Ref => { self.word_nbsp("ref");
self.word_nbsp("ref"); }
self.print_mutability(hir::Mutability::Not, false); if mutbl == Mutability::Mut {
} self.word_nbsp("mut");
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); self.print_ident(ident);
if let Some(p) = sub { if let Some(p) = sub {

View file

@ -259,17 +259,8 @@ impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns {
== Some(cx.tcx.field_index(fieldpat.hir_id, cx.typeck_results())) == Some(cx.tcx.field_index(fieldpat.hir_id, cx.typeck_results()))
{ {
cx.struct_span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span, |lint| { cx.struct_span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span, |lint| {
let binding = match binding_annot { let suggested_ident =
hir::BindingAnnotation::Unannotated => None, format!("{}{}", binding_annot.prefix_str(), ident);
hir::BindingAnnotation::Mutable => Some("mut"),
hir::BindingAnnotation::Ref => Some("ref"),
hir::BindingAnnotation::RefMut => Some("ref mut"),
};
let suggested_ident = if let Some(binding) = binding {
format!("{} {}", binding, ident)
} else {
ident.to_string()
};
lint.build(fluent::lint::builtin_non_shorthand_field_patterns) lint.build(fluent::lint::builtin_non_shorthand_field_patterns)
.set_arg("ident", ident.clone()) .set_arg("ident", ident.clone())
.span_suggestion( .span_suggestion(

View file

@ -751,7 +751,7 @@ impl UnusedParens {
avoid_or: bool, avoid_or: bool,
avoid_mut: bool, avoid_mut: bool,
) { ) {
use ast::{BindingMode, Mutability, PatKind}; use ast::{BindingAnnotation, PatKind};
if let PatKind::Paren(inner) = &value.kind { if let PatKind::Paren(inner) = &value.kind {
match inner.kind { match inner.kind {
@ -763,7 +763,9 @@ impl UnusedParens {
// Avoid `p0 | .. | pn` if we should. // Avoid `p0 | .. | pn` if we should.
PatKind::Or(..) if avoid_or => return, PatKind::Or(..) if avoid_or => return,
// Avoid `mut x` and `mut x @ p` if we should: // Avoid `mut x` and `mut x @ p` if we should:
PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ..) if avoid_mut => return, PatKind::Ident(BindingAnnotation::MUT, ..) if avoid_mut => {
return;
}
// Otherwise proceed with linting. // Otherwise proceed with linting.
_ => {} _ => {}
} }

View file

@ -1,6 +1,4 @@
use rustc_hir::BindingAnnotation; use rustc_hir::{BindingAnnotation, ByRef, Mutability};
use rustc_hir::BindingAnnotation::*;
use rustc_hir::Mutability;
#[derive(Clone, PartialEq, TyEncodable, TyDecodable, Debug, Copy, HashStable)] #[derive(Clone, PartialEq, TyEncodable, TyDecodable, Debug, Copy, HashStable)]
pub enum BindingMode { pub enum BindingMode {
@ -11,12 +9,10 @@ pub enum BindingMode {
TrivialTypeTraversalAndLiftImpls! { BindingMode, } TrivialTypeTraversalAndLiftImpls! { BindingMode, }
impl BindingMode { impl BindingMode {
pub fn convert(ba: BindingAnnotation) -> BindingMode { pub fn convert(BindingAnnotation(by_ref, mutbl): BindingAnnotation) -> BindingMode {
match ba { match by_ref {
Unannotated => BindingMode::BindByValue(Mutability::Not), ByRef::No => BindingMode::BindByValue(mutbl),
Mutable => BindingMode::BindByValue(Mutability::Mut), ByRef::Yes => BindingMode::BindByReference(mutbl),
Ref => BindingMode::BindByReference(Mutability::Not),
RefMut => BindingMode::BindByReference(Mutability::Mut),
} }
} }
} }

View file

@ -10,9 +10,9 @@ use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter, Lit, LitKind, TokenKind}; use rustc_ast::token::{self, Delimiter, Lit, LitKind, TokenKind};
use rustc_ast::util::parser::AssocOp; use rustc_ast::util::parser::AssocOp;
use rustc_ast::{ use rustc_ast::{
AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode, Block, AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingAnnotation, Block,
BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Mutability, Param, Pat, BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Param, Pat, PatKind,
PatKind, Path, PathSegment, QSelf, Ty, TyKind, Path, PathSegment, QSelf, Ty, TyKind,
}; };
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
@ -37,7 +37,7 @@ const TURBOFISH_SUGGESTION_STR: &str =
pub(super) fn dummy_arg(ident: Ident) -> Param { pub(super) fn dummy_arg(ident: Ident) -> Param {
let pat = P(Pat { let pat = P(Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
kind: PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None), kind: PatKind::Ident(BindingAnnotation::NONE, ident, None),
span: ident.span, span: ident.span,
tokens: None, tokens: None,
}); });
@ -2961,7 +2961,7 @@ impl<'a> Parser<'a> {
} }
_ => {} _ => {}
}, },
PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None) => { PatKind::Ident(BindingAnnotation::NONE, ident, None) => {
match &first_pat.kind { match &first_pat.kind {
PatKind::Ident(_, old_ident, _) => { PatKind::Ident(_, old_ident, _) => {
let path = PatKind::Path( let path = PatKind::Path(

View file

@ -8,7 +8,7 @@ use rustc_ast::token::{self, Delimiter, TokenKind};
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
use rustc_ast::{self as ast, AttrVec, Attribute, DUMMY_NODE_ID}; use rustc_ast::{self as ast, AttrVec, Attribute, DUMMY_NODE_ID};
use rustc_ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind}; use rustc_ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind};
use rustc_ast::{BindingMode, Block, FnDecl, FnSig, Param, SelfKind}; use rustc_ast::{BindingAnnotation, Block, FnDecl, FnSig, Param, SelfKind};
use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, VariantData}; use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, VariantData};
use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind}; use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
use rustc_ast::{MacArgs, MacCall, MacDelimiter}; use rustc_ast::{MacArgs, MacCall, MacDelimiter};
@ -2322,7 +2322,7 @@ impl<'a> Parser<'a> {
match ty { match ty {
Ok(ty) => { Ok(ty) => {
let ident = Ident::new(kw::Empty, this.prev_token.span); let ident = Ident::new(kw::Empty, this.prev_token.span);
let bm = BindingMode::ByValue(Mutability::Not); let bm = BindingAnnotation::NONE;
let pat = this.mk_pat_ident(ty.span, bm, ident); let pat = this.mk_pat_ident(ty.span, bm, ident);
(pat, ty) (pat, ty)
} }

View file

@ -4,8 +4,8 @@ use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
use rustc_ast::ptr::P; use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter}; use rustc_ast::token::{self, Delimiter};
use rustc_ast::{ use rustc_ast::{
self as ast, AttrVec, BindingMode, Expr, ExprKind, MacCall, Mutability, Pat, PatField, PatKind, self as ast, AttrVec, BindingAnnotation, ByRef, Expr, ExprKind, MacCall, Mutability, Pat,
Path, QSelf, RangeEnd, RangeSyntax, PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
}; };
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult};
@ -353,7 +353,7 @@ impl<'a> Parser<'a> {
} else if self.eat_keyword(kw::Ref) { } else if self.eat_keyword(kw::Ref) {
// Parse ref ident @ pat / ref mut ident @ pat // Parse ref ident @ pat / ref mut ident @ pat
let mutbl = self.parse_mutability(); let mutbl = self.parse_mutability();
self.parse_pat_ident(BindingMode::ByRef(mutbl))? self.parse_pat_ident(BindingAnnotation(ByRef::Yes, mutbl))?
} else if self.eat_keyword(kw::Box) { } else if self.eat_keyword(kw::Box) {
self.parse_pat_box()? self.parse_pat_box()?
} else if self.check_inline_const(0) { } else if self.check_inline_const(0) {
@ -369,7 +369,7 @@ impl<'a> Parser<'a> {
// Parse `ident @ pat` // Parse `ident @ pat`
// This can give false positives and parse nullary enums, // This can give false positives and parse nullary enums,
// they are dealt with later in resolve. // they are dealt with later in resolve.
self.parse_pat_ident(BindingMode::ByValue(Mutability::Not))? self.parse_pat_ident(BindingAnnotation::NONE)?
} else if self.is_start_of_pat_with_path() { } else if self.is_start_of_pat_with_path() {
// Parse pattern starting with a path // Parse pattern starting with a path
let (qself, path) = if self.eat_lt() { let (qself, path) = if self.eat_lt() {
@ -578,7 +578,8 @@ impl<'a> Parser<'a> {
let mut pat = self.parse_pat_no_top_alt(Some("identifier"))?; let mut pat = self.parse_pat_no_top_alt(Some("identifier"))?;
// If we don't have `mut $ident (@ pat)?`, error. // If we don't have `mut $ident (@ pat)?`, error.
if let PatKind::Ident(BindingMode::ByValue(m @ Mutability::Not), ..) = &mut pat.kind { if let PatKind::Ident(BindingAnnotation(ByRef::No, m @ Mutability::Not), ..) = &mut pat.kind
{
// Don't recurse into the subpattern. // Don't recurse into the subpattern.
// `mut` on the outer binding doesn't affect the inner bindings. // `mut` on the outer binding doesn't affect the inner bindings.
*m = Mutability::Mut; *m = Mutability::Mut;
@ -604,7 +605,7 @@ impl<'a> Parser<'a> {
) )
.emit(); .emit();
self.parse_pat_ident(BindingMode::ByRef(Mutability::Mut)) self.parse_pat_ident(BindingAnnotation::REF_MUT)
} }
/// Turn all by-value immutable bindings in a pattern into mutable bindings. /// Turn all by-value immutable bindings in a pattern into mutable bindings.
@ -613,7 +614,8 @@ impl<'a> Parser<'a> {
struct AddMut(bool); struct AddMut(bool);
impl MutVisitor for AddMut { impl MutVisitor for AddMut {
fn visit_pat(&mut self, pat: &mut P<Pat>) { fn visit_pat(&mut self, pat: &mut P<Pat>) {
if let PatKind::Ident(BindingMode::ByValue(m @ Mutability::Not), ..) = &mut pat.kind if let PatKind::Ident(BindingAnnotation(ByRef::No, m @ Mutability::Not), ..) =
&mut pat.kind
{ {
self.0 = true; self.0 = true;
*m = Mutability::Mut; *m = Mutability::Mut;
@ -838,7 +840,7 @@ impl<'a> Parser<'a> {
/// Parses `ident` or `ident @ pat`. /// Parses `ident` or `ident @ pat`.
/// Used by the copy foo and ref foo patterns to give a good /// Used by the copy foo and ref foo patterns to give a good
/// error message when parsing mistakes like `ref foo(a, b)`. /// 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, binding_annotation: BindingAnnotation) -> PResult<'a, PatKind> {
let ident = self.parse_ident()?; let ident = self.parse_ident()?;
let sub = if self.eat(&token::At) { let sub = if self.eat(&token::At) {
Some(self.parse_pat_no_top_alt(Some("binding pattern"))?) Some(self.parse_pat_no_top_alt(Some("binding pattern"))?)
@ -856,7 +858,7 @@ impl<'a> Parser<'a> {
.struct_span_err(self.prev_token.span, "expected identifier, found enum pattern")); .struct_span_err(self.prev_token.span, "expected identifier, found enum pattern"));
} }
Ok(PatKind::Ident(binding_mode, ident, sub)) Ok(PatKind::Ident(binding_annotation, ident, sub))
} }
/// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`). /// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`).
@ -936,11 +938,7 @@ impl<'a> Parser<'a> {
None None
}; };
Ok(PatKind::Ident( Ok(PatKind::Ident(BindingAnnotation::NONE, Ident::new(kw::Box, box_span), sub))
BindingMode::ByValue(Mutability::Not),
Ident::new(kw::Box, box_span),
sub,
))
} else { } else {
let pat = self.parse_pat_with_range_pat(false, None)?; let pat = self.parse_pat_with_range_pat(false, None)?;
self.sess.gated_spans.gate(sym::box_patterns, box_span.to(self.prev_token.span)); self.sess.gated_spans.gate(sym::box_patterns, box_span.to(self.prev_token.span));
@ -1117,14 +1115,12 @@ impl<'a> Parser<'a> {
let fieldname = self.parse_field_name()?; let fieldname = self.parse_field_name()?;
hi = self.prev_token.span; hi = self.prev_token.span;
let bind_type = match (is_ref, is_mut) { let mutability = match is_mut {
(true, true) => BindingMode::ByRef(Mutability::Mut), false => Mutability::Not,
(true, false) => BindingMode::ByRef(Mutability::Not), true => Mutability::Mut,
(false, true) => BindingMode::ByValue(Mutability::Mut),
(false, false) => BindingMode::ByValue(Mutability::Not),
}; };
let ann = BindingAnnotation(ByRef::from(is_ref), mutability);
let fieldpat = self.mk_pat_ident(boxed_span.to(hi), bind_type, fieldname); let fieldpat = self.mk_pat_ident(boxed_span.to(hi), ann, fieldname);
let subpat = let subpat =
if is_box { self.mk_pat(lo.to(hi), PatKind::Box(fieldpat)) } else { fieldpat }; if is_box { self.mk_pat(lo.to(hi), PatKind::Box(fieldpat)) } else { fieldpat };
(subpat, fieldname, true) (subpat, fieldname, true)
@ -1141,8 +1137,8 @@ impl<'a> Parser<'a> {
}) })
} }
pub(super) fn mk_pat_ident(&self, span: Span, bm: BindingMode, ident: Ident) -> P<Pat> { pub(super) fn mk_pat_ident(&self, span: Span, ann: BindingAnnotation, ident: Ident) -> P<Pat> {
self.mk_pat(span, PatKind::Ident(bm, ident, None)) self.mk_pat(span, PatKind::Ident(ann, ident, None))
} }
pub(super) fn mk_pat(&self, span: Span, kind: PatKind) -> P<Pat> { pub(super) fn mk_pat(&self, span: Span, kind: PatKind) -> P<Pat> {

View file

@ -76,7 +76,7 @@ fn check_no_patterns(tcx: TyCtxt<'_>, params: &[hir::Param<'_>]) {
for param in params { for param in params {
match param.pat.kind { match param.pat.kind {
hir::PatKind::Wild hir::PatKind::Wild
| hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, _, None) => {} | hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, _, None) => {}
_ => { _ => {
tcx.sess tcx.sess
.struct_span_err( .struct_span_err(

View file

@ -20,7 +20,7 @@ use rustc_errors::DiagnosticId;
use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS}; use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS};
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
use rustc_hir::{PrimTy, TraitCandidate}; use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate};
use rustc_middle::middle::resolve_lifetime::Set1; use rustc_middle::middle::resolve_lifetime::Set1;
use rustc_middle::ty::DefIdTree; use rustc_middle::ty::DefIdTree;
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
@ -50,7 +50,7 @@ use diagnostics::{
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
struct BindingInfo { struct BindingInfo {
span: Span, span: Span,
binding_mode: BindingMode, annotation: BindingAnnotation,
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
@ -2865,10 +2865,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
pat.walk(&mut |pat| { pat.walk(&mut |pat| {
match pat.kind { match pat.kind {
PatKind::Ident(binding_mode, ident, ref sub_pat) PatKind::Ident(annotation, ident, ref sub_pat)
if sub_pat.is_some() || self.is_base_res_local(pat.id) => 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, annotation });
} }
PatKind::Or(ref ps) => { PatKind::Or(ref ps) => {
// Check the consistency of this or-pattern and // Check the consistency of this or-pattern and
@ -2925,7 +2925,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
binding_error.target.insert(pat_outer.span); binding_error.target.insert(pat_outer.span);
} }
Some(binding_outer) => { Some(binding_outer) => {
if binding_outer.binding_mode != binding_inner.binding_mode { if binding_outer.annotation != binding_inner.annotation {
// The binding modes in the outer and inner bindings differ. // The binding modes in the outer and inner bindings differ.
inconsistent_vars inconsistent_vars
.entry(name) .entry(name)
@ -3146,14 +3146,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
fn try_resolve_as_non_binding( fn try_resolve_as_non_binding(
&mut self, &mut self,
pat_src: PatternSource, pat_src: PatternSource,
bm: BindingMode, ann: BindingAnnotation,
ident: Ident, ident: Ident,
has_sub: bool, has_sub: bool,
) -> Option<Res> { ) -> Option<Res> {
// An immutable (no `mut`) by-value (no `ref`) binding pattern without // An immutable (no `mut`) by-value (no `ref`) binding pattern without
// a sub pattern (no `@ $pat`) is syntactically ambiguous as it could // a sub pattern (no `@ $pat`) is syntactically ambiguous as it could
// also be interpreted as a path to e.g. a constant, variant, etc. // also be interpreted as a path to e.g. a constant, variant, etc.
let is_syntactic_ambiguity = !has_sub && bm == BindingMode::ByValue(Mutability::Not); let is_syntactic_ambiguity = !has_sub && ann == BindingAnnotation::NONE;
let ls_binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS)?; let ls_binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS)?;
let (res, binding) = match ls_binding { let (res, binding) = match ls_binding {

View file

@ -865,23 +865,12 @@ impl<'l> Visitor<'l> for PathCollector<'l> {
hir::PatKind::TupleStruct(ref path, ..) | hir::PatKind::Path(ref path) => { hir::PatKind::TupleStruct(ref path, ..) | hir::PatKind::Path(ref path) => {
self.collected_paths.push((p.hir_id, path)); self.collected_paths.push((p.hir_id, path));
} }
hir::PatKind::Binding(bm, _, ident, _) => { hir::PatKind::Binding(hir::BindingAnnotation(_, mutbl), _, ident, _) => {
debug!( debug!(
"PathCollector, visit ident in pat {}: {:?} {:?}", "PathCollector, visit ident in pat {}: {:?} {:?}",
ident, p.span, ident.span ident, p.span, ident.span
); );
let immut = match bm { self.collected_idents.push((p.hir_id, ident, mutbl));
// Even if the ref is mut, you can't change the ref, only
// the data pointed at, so showing the initialising expression
// is still worthwhile.
hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Ref => {
hir::Mutability::Not
}
hir::BindingAnnotation::Mutable | hir::BindingAnnotation::RefMut => {
hir::Mutability::Mut
}
};
self.collected_idents.push((p.hir_id, ident, immut));
} }
_ => {} _ => {}
} }

View file

@ -774,7 +774,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// Get the local name of this closure. This can be inaccurate because // Get the local name of this closure. This can be inaccurate because
// of the possibility of reassignment, but this should be good enough. // of the possibility of reassignment, but this should be good enough.
match &kind { match &kind {
hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, None) => { hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, ident, None) => {
Some(ident.name) Some(ident.name)
} }
_ => { _ => {

View file

@ -569,7 +569,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Ty<'tcx> { ) -> Ty<'tcx> {
// Determine the binding mode... // Determine the binding mode...
let bm = match ba { let bm = match ba {
hir::BindingAnnotation::Unannotated => def_bm, hir::BindingAnnotation::NONE => def_bm,
_ => BindingMode::convert(ba), _ => BindingMode::convert(ba),
}; };
// ...and store it in a side table: // ...and store it in a side table:
@ -655,7 +655,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ba: hir::BindingAnnotation, ba: hir::BindingAnnotation,
) { ) {
match (expected.kind(), actual.kind(), ba) { match (expected.kind(), actual.kind(), ba) {
(ty::Ref(_, inner_ty, _), _, hir::BindingAnnotation::Unannotated) (ty::Ref(_, inner_ty, _), _, hir::BindingAnnotation::NONE)
if self.can_eq(self.param_env, *inner_ty, actual).is_ok() => if self.can_eq(self.param_env, *inner_ty, actual).is_ok() =>
{ {
err.span_suggestion_verbose( err.span_suggestion_verbose(
@ -665,7 +665,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
} }
(_, ty::Ref(_, inner_ty, _), hir::BindingAnnotation::Ref) (_, ty::Ref(_, inner_ty, _), hir::BindingAnnotation::REF)
if self.can_eq(self.param_env, expected, *inner_ty).is_ok() => if self.can_eq(self.param_env, expected, *inner_ty).is_ok() =>
{ {
err.span_suggestion_verbose( err.span_suggestion_verbose(

View file

@ -587,8 +587,7 @@ fn resolve_local<'tcx>(
// & expression, and its lifetime would be extended to the end of the block (due // & expression, and its lifetime would be extended to the end of the block (due
// to a different rule, not the below code). // to a different rule, not the below code).
match pat.kind { match pat.kind {
PatKind::Binding(hir::BindingAnnotation::Ref, ..) PatKind::Binding(hir::BindingAnnotation(hir::ByRef::Yes, _), ..) => true,
| PatKind::Binding(hir::BindingAnnotation::RefMut, ..) => true,
PatKind::Struct(_, ref field_pats, _) => { PatKind::Struct(_, ref field_pats, _) => {
field_pats.iter().any(|fp| is_binding_pat(&fp.pat)) field_pats.iter().any(|fp| is_binding_pat(&fp.pat))
@ -607,10 +606,7 @@ fn resolve_local<'tcx>(
PatKind::Box(ref subpat) => is_binding_pat(&subpat), PatKind::Box(ref subpat) => is_binding_pat(&subpat),
PatKind::Ref(_, _) PatKind::Ref(_, _)
| PatKind::Binding( | PatKind::Binding(hir::BindingAnnotation(hir::ByRef::No, _), ..)
hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Mutable,
..,
)
| PatKind::Wild | PatKind::Wild
| PatKind::Path(_) | PatKind::Path(_)
| PatKind::Lit(_) | PatKind::Lit(_)