Auto merge of #101241 - camsteffen:refactor-binding-annotations, r=cjgillot
`BindingAnnotation` refactor * `ast::BindingMode` is deleted and replaced with `hir::BindingAnnotation` (which is moved to `ast`) * `BindingAnnotation` is changed from an enum to a tuple struct e.g. `BindingAnnotation(ByRef::No, Mutability::Mut)` * Associated constants added for convenience `BindingAnnotation::{NONE, REF, MUT, REF_MUT}` One goal is to make it more clear that `BindingAnnotation` merely represents syntax `ref mut` and not the actual binding mode. This was especially confusing since we had `ast::BindingMode`->`hir::BindingAnnotation`->`thir::BindingMode`. I wish there were more symmetry between `ByRef` and `Mutability` (variant) naming (maybe `Mutable::Yes`?), and I also don't love how long the name `BindingAnnotation` is, but this seems like the best compromise. Ideas welcome.
This commit is contained in:
commit
6c358c67d4
61 changed files with 278 additions and 333 deletions
|
@ -10,9 +10,9 @@ use rustc_ast::ptr::P;
|
|||
use rustc_ast::token::{self, Delimiter, Lit, LitKind, TokenKind};
|
||||
use rustc_ast::util::parser::AssocOp;
|
||||
use rustc_ast::{
|
||||
AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode, Block,
|
||||
BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Mutability, Param, Pat,
|
||||
PatKind, Path, PathSegment, QSelf, Ty, TyKind,
|
||||
AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingAnnotation, Block,
|
||||
BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Param, Pat, PatKind,
|
||||
Path, PathSegment, QSelf, Ty, TyKind,
|
||||
};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
|
@ -37,7 +37,7 @@ const TURBOFISH_SUGGESTION_STR: &str =
|
|||
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),
|
||||
kind: PatKind::Ident(BindingAnnotation::NONE, ident, None),
|
||||
span: ident.span,
|
||||
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 {
|
||||
PatKind::Ident(_, old_ident, _) => {
|
||||
let path = PatKind::Path(
|
||||
|
|
|
@ -8,7 +8,7 @@ use rustc_ast::token::{self, Delimiter, TokenKind};
|
|||
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
|
||||
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::{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::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
|
||||
use rustc_ast::{MacArgs, MacCall, MacDelimiter};
|
||||
|
@ -2322,7 +2322,7 @@ impl<'a> Parser<'a> {
|
|||
match ty {
|
||||
Ok(ty) => {
|
||||
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);
|
||||
(pat, ty)
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
|
|||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, Delimiter};
|
||||
use rustc_ast::{
|
||||
self as ast, AttrVec, BindingMode, Expr, ExprKind, MacCall, Mutability, Pat, PatField, PatKind,
|
||||
Path, QSelf, RangeEnd, RangeSyntax,
|
||||
self as ast, AttrVec, BindingAnnotation, ByRef, Expr, ExprKind, MacCall, Mutability, Pat,
|
||||
PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
|
||||
};
|
||||
use rustc_ast_pretty::pprust;
|
||||
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) {
|
||||
// Parse ref ident @ pat / ref mut ident @ pat
|
||||
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) {
|
||||
self.parse_pat_box()?
|
||||
} else if self.check_inline_const(0) {
|
||||
|
@ -369,7 +369,7 @@ impl<'a> Parser<'a> {
|
|||
// Parse `ident @ pat`
|
||||
// This can give false positives and parse nullary enums,
|
||||
// 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() {
|
||||
// Parse pattern starting with a path
|
||||
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"))?;
|
||||
|
||||
// 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.
|
||||
// `mut` on the outer binding doesn't affect the inner bindings.
|
||||
*m = Mutability::Mut;
|
||||
|
@ -604,7 +605,7 @@ impl<'a> Parser<'a> {
|
|||
)
|
||||
.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.
|
||||
|
@ -613,7 +614,8 @@ impl<'a> Parser<'a> {
|
|||
struct AddMut(bool);
|
||||
impl MutVisitor for AddMut {
|
||||
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;
|
||||
*m = Mutability::Mut;
|
||||
|
@ -838,7 +840,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, binding_annotation: BindingAnnotation) -> PResult<'a, PatKind> {
|
||||
let ident = self.parse_ident()?;
|
||||
let sub = if self.eat(&token::At) {
|
||||
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"));
|
||||
}
|
||||
|
||||
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 { ... }`).
|
||||
|
@ -936,11 +938,7 @@ impl<'a> Parser<'a> {
|
|||
None
|
||||
};
|
||||
|
||||
Ok(PatKind::Ident(
|
||||
BindingMode::ByValue(Mutability::Not),
|
||||
Ident::new(kw::Box, box_span),
|
||||
sub,
|
||||
))
|
||||
Ok(PatKind::Ident(BindingAnnotation::NONE, Ident::new(kw::Box, box_span), sub))
|
||||
} else {
|
||||
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));
|
||||
|
@ -1117,14 +1115,12 @@ impl<'a> Parser<'a> {
|
|||
let fieldname = self.parse_field_name()?;
|
||||
hi = self.prev_token.span;
|
||||
|
||||
let bind_type = match (is_ref, is_mut) {
|
||||
(true, true) => BindingMode::ByRef(Mutability::Mut),
|
||||
(true, false) => BindingMode::ByRef(Mutability::Not),
|
||||
(false, true) => BindingMode::ByValue(Mutability::Mut),
|
||||
(false, false) => BindingMode::ByValue(Mutability::Not),
|
||||
let mutability = match is_mut {
|
||||
false => Mutability::Not,
|
||||
true => Mutability::Mut,
|
||||
};
|
||||
|
||||
let fieldpat = self.mk_pat_ident(boxed_span.to(hi), bind_type, fieldname);
|
||||
let ann = BindingAnnotation(ByRef::from(is_ref), mutability);
|
||||
let fieldpat = self.mk_pat_ident(boxed_span.to(hi), ann, fieldname);
|
||||
let subpat =
|
||||
if is_box { self.mk_pat(lo.to(hi), PatKind::Box(fieldpat)) } else { fieldpat };
|
||||
(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> {
|
||||
self.mk_pat(span, PatKind::Ident(bm, ident, None))
|
||||
pub(super) fn mk_pat_ident(&self, span: Span, ann: BindingAnnotation, ident: Ident) -> P<Pat> {
|
||||
self.mk_pat(span, PatKind::Ident(ann, ident, None))
|
||||
}
|
||||
|
||||
pub(super) fn mk_pat(&self, span: Span, kind: PatKind) -> P<Pat> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue