Skip to content

Commit 6c358c6

Browse files
committed
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.
2 parents 56b2711 + 9ea82d5 commit 6c358c6

File tree

61 files changed

+276
-331
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+276
-331
lines changed

compiler/rustc_ast/src/ast.rs

+55-22
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ impl Pat {
594594
// In a type expression `_` is an inference variable.
595595
PatKind::Wild => TyKind::Infer,
596596
// An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`.
597-
PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None) => {
597+
PatKind::Ident(BindingAnnotation::NONE, ident, None) => {
598598
TyKind::Path(None, Path::from_ident(*ident))
599599
}
600600
PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
@@ -681,10 +681,43 @@ pub struct PatField {
681681
pub is_placeholder: bool,
682682
}
683683

684-
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
685-
pub enum BindingMode {
686-
ByRef(Mutability),
687-
ByValue(Mutability),
684+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
685+
#[derive(Encodable, Decodable, HashStable_Generic)]
686+
pub enum ByRef {
687+
Yes,
688+
No,
689+
}
690+
691+
impl From<bool> for ByRef {
692+
fn from(b: bool) -> ByRef {
693+
match b {
694+
false => ByRef::No,
695+
true => ByRef::Yes,
696+
}
697+
}
698+
}
699+
700+
/// Explicit binding annotations given in the HIR for a binding. Note
701+
/// that this is not the final binding *mode* that we infer after type
702+
/// inference.
703+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
704+
#[derive(Encodable, Decodable, HashStable_Generic)]
705+
pub struct BindingAnnotation(pub ByRef, pub Mutability);
706+
707+
impl BindingAnnotation {
708+
pub const NONE: Self = Self(ByRef::No, Mutability::Not);
709+
pub const REF: Self = Self(ByRef::Yes, Mutability::Not);
710+
pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
711+
pub const REF_MUT: Self = Self(ByRef::Yes, Mutability::Mut);
712+
713+
pub fn prefix_str(self) -> &'static str {
714+
match self {
715+
Self::NONE => "",
716+
Self::REF => "ref ",
717+
Self::MUT => "mut ",
718+
Self::REF_MUT => "ref mut ",
719+
}
720+
}
688721
}
689722

690723
#[derive(Clone, Encodable, Decodable, Debug)]
@@ -713,7 +746,7 @@ pub enum PatKind {
713746
/// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
714747
/// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
715748
/// during name resolution.
716-
Ident(BindingMode, Ident, Option<P<Pat>>),
749+
Ident(BindingAnnotation, Ident, Option<P<Pat>>),
717750

718751
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
719752
/// The `bool` is `true` in the presence of a `..`.
@@ -2228,7 +2261,7 @@ pub type ExplicitSelf = Spanned<SelfKind>;
22282261
impl Param {
22292262
/// Attempts to cast parameter to `ExplicitSelf`.
22302263
pub fn to_self(&self) -> Option<ExplicitSelf> {
2231-
if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.kind {
2264+
if let PatKind::Ident(BindingAnnotation(ByRef::No, mutbl), ident, _) = self.pat.kind {
22322265
if ident.name == kw::SelfLower {
22332266
return match self.ty.kind {
22342267
TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
@@ -2258,31 +2291,31 @@ impl Param {
22582291
pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
22592292
let span = eself.span.to(eself_ident.span);
22602293
let infer_ty = P(Ty { id: DUMMY_NODE_ID, kind: TyKind::ImplicitSelf, span, tokens: None });
2261-
let param = |mutbl, ty| Param {
2294+
let (mutbl, ty) = match eself.node {
2295+
SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
2296+
SelfKind::Value(mutbl) => (mutbl, infer_ty),
2297+
SelfKind::Region(lt, mutbl) => (
2298+
Mutability::Not,
2299+
P(Ty {
2300+
id: DUMMY_NODE_ID,
2301+
kind: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl }),
2302+
span,
2303+
tokens: None,
2304+
}),
2305+
),
2306+
};
2307+
Param {
22622308
attrs,
22632309
pat: P(Pat {
22642310
id: DUMMY_NODE_ID,
2265-
kind: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
2311+
kind: PatKind::Ident(BindingAnnotation(ByRef::No, mutbl), eself_ident, None),
22662312
span,
22672313
tokens: None,
22682314
}),
22692315
span,
22702316
ty,
22712317
id: DUMMY_NODE_ID,
22722318
is_placeholder: false,
2273-
};
2274-
match eself.node {
2275-
SelfKind::Explicit(ty, mutbl) => param(mutbl, ty),
2276-
SelfKind::Value(mutbl) => param(mutbl, infer_ty),
2277-
SelfKind::Region(lt, mutbl) => param(
2278-
Mutability::Not,
2279-
P(Ty {
2280-
id: DUMMY_NODE_ID,
2281-
kind: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl }),
2282-
span,
2283-
tokens: None,
2284-
}),
2285-
),
22862319
}
22872320
}
22882321
}

compiler/rustc_ast_lowering/src/expr.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
577577
let (pat, task_context_hid) = self.pat_ident_binding_mode(
578578
span,
579579
Ident::with_dummy_span(sym::_task_context),
580-
hir::BindingAnnotation::Mutable,
580+
hir::BindingAnnotation::MUT,
581581
);
582582
let param = hir::Param {
583583
hir_id: self.next_id(),
@@ -671,7 +671,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
671671
// this name to identify what is being awaited by a suspended async functions.
672672
let awaitee_ident = Ident::with_dummy_span(sym::__awaitee);
673673
let (awaitee_pat, awaitee_pat_hid) =
674-
self.pat_ident_binding_mode(span, awaitee_ident, hir::BindingAnnotation::Mutable);
674+
self.pat_ident_binding_mode(span, awaitee_ident, hir::BindingAnnotation::MUT);
675675

676676
let task_context_ident = Ident::with_dummy_span(sym::_task_context);
677677

@@ -1433,7 +1433,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14331433
// `mut iter`
14341434
let iter = Ident::with_dummy_span(sym::iter);
14351435
let (iter_pat, iter_pat_nid) =
1436-
self.pat_ident_binding_mode(head_span, iter, hir::BindingAnnotation::Mutable);
1436+
self.pat_ident_binding_mode(head_span, iter, hir::BindingAnnotation::MUT);
14371437

14381438
// `match Iterator::next(&mut iter) { ... }`
14391439
let match_expr = {

compiler/rustc_ast_lowering/src/item.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -1083,12 +1083,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
10831083
// Check if this is a binding pattern, if so, we can optimize and avoid adding a
10841084
// `let <pat> = __argN;` statement. In this case, we do not rename the parameter.
10851085
let (ident, is_simple_parameter) = match parameter.pat.kind {
1086-
hir::PatKind::Binding(
1087-
hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Mutable,
1088-
_,
1089-
ident,
1090-
_,
1091-
) => (ident, true),
1086+
hir::PatKind::Binding(hir::BindingAnnotation(ByRef::No, _), _, ident, _) => {
1087+
(ident, true)
1088+
}
10921089
// For `ref mut` or wildcard arguments, we can't reuse the binding, but
10931090
// we can keep the same name for the parameter.
10941091
// This lets rustdoc render it correctly in documentation.
@@ -1153,7 +1150,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11531150
let (move_pat, move_id) = this.pat_ident_binding_mode(
11541151
desugared_span,
11551152
ident,
1156-
hir::BindingAnnotation::Mutable,
1153+
hir::BindingAnnotation::MUT,
11571154
);
11581155
let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
11591156
let move_stmt = this.stmt_let_pat(

compiler/rustc_ast_lowering/src/lib.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1692,10 +1692,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16921692
output,
16931693
c_variadic,
16941694
implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1695-
use BindingMode::{ByRef, ByValue};
16961695
let is_mutable_pat = matches!(
16971696
arg.pat.kind,
1698-
PatKind::Ident(ByValue(Mutability::Mut) | ByRef(Mutability::Mut), ..)
1697+
PatKind::Ident(hir::BindingAnnotation(_, Mutability::Mut), ..)
16991698
);
17001699

17011700
match arg.ty.kind {
@@ -2360,11 +2359,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23602359
}
23612360

23622361
fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) {
2363-
self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated)
2362+
self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::NONE)
23642363
}
23652364

23662365
fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, hir::HirId) {
2367-
self.pat_ident_binding_mode_mut(span, ident, hir::BindingAnnotation::Unannotated)
2366+
self.pat_ident_binding_mode_mut(span, ident, hir::BindingAnnotation::NONE)
23682367
}
23692368

23702369
fn pat_ident_binding_mode(

compiler/rustc_ast_lowering/src/pat.rs

+9-18
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2424
let node = loop {
2525
match pattern.kind {
2626
PatKind::Wild => break hir::PatKind::Wild,
27-
PatKind::Ident(ref binding_mode, ident, ref sub) => {
27+
PatKind::Ident(binding_mode, ident, ref sub) => {
2828
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s));
2929
break self.lower_pat_ident(pattern, binding_mode, ident, lower_sub);
3030
}
@@ -176,9 +176,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
176176
let mut prev_rest_span = None;
177177

178178
// Lowers `$bm $ident @ ..` to `$bm $ident @ _`.
179-
let lower_rest_sub = |this: &mut Self, pat, bm, ident, sub| {
179+
let lower_rest_sub = |this: &mut Self, pat, ann, ident, sub| {
180180
let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub));
181-
let node = this.lower_pat_ident(pat, bm, ident, lower_sub);
181+
let node = this.lower_pat_ident(pat, ann, ident, lower_sub);
182182
this.pat_with_node_id_of(pat, node)
183183
};
184184

@@ -194,9 +194,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
194194
}
195195
// Found a sub-slice pattern `$binding_mode $ident @ ..`.
196196
// Record, lower it to `$binding_mode $ident @ _`, and stop here.
197-
PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => {
197+
PatKind::Ident(ann, ident, Some(ref sub)) if sub.is_rest() => {
198198
prev_rest_span = Some(sub.span);
199-
slice = Some(self.arena.alloc(lower_rest_sub(self, pat, bm, ident, sub)));
199+
slice = Some(self.arena.alloc(lower_rest_sub(self, pat, ann, ident, sub)));
200200
break;
201201
}
202202
// It was not a subslice pattern so lower it normally.
@@ -209,9 +209,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
209209
// There was a previous subslice pattern; make sure we don't allow more.
210210
let rest_span = match pat.kind {
211211
PatKind::Rest => Some(pat.span),
212-
PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => {
212+
PatKind::Ident(ann, ident, Some(ref sub)) if sub.is_rest() => {
213213
// #69103: Lower into `binding @ _` as above to avoid ICEs.
214-
after.push(lower_rest_sub(self, pat, bm, ident, sub));
214+
after.push(lower_rest_sub(self, pat, ann, ident, sub));
215215
Some(sub.span)
216216
}
217217
_ => None,
@@ -235,7 +235,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
235235
fn lower_pat_ident(
236236
&mut self,
237237
p: &Pat,
238-
binding_mode: &BindingMode,
238+
annotation: BindingAnnotation,
239239
ident: Ident,
240240
lower_sub: impl FnOnce(&mut Self) -> Option<&'hir hir::Pat<'hir>>,
241241
) -> hir::PatKind<'hir> {
@@ -248,7 +248,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
248248
};
249249

250250
hir::PatKind::Binding(
251-
self.lower_binding_mode(binding_mode),
251+
annotation,
252252
self.lower_node_id(canonical_id),
253253
self.lower_ident(ident),
254254
lower_sub(self),
@@ -269,15 +269,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
269269
}
270270
}
271271

272-
fn lower_binding_mode(&mut self, b: &BindingMode) -> hir::BindingAnnotation {
273-
match *b {
274-
BindingMode::ByValue(Mutability::Not) => hir::BindingAnnotation::Unannotated,
275-
BindingMode::ByRef(Mutability::Not) => hir::BindingAnnotation::Ref,
276-
BindingMode::ByValue(Mutability::Mut) => hir::BindingAnnotation::Mutable,
277-
BindingMode::ByRef(Mutability::Mut) => hir::BindingAnnotation::RefMut,
278-
}
279-
}
280-
281272
fn pat_wild_with_node_id_of(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> {
282273
self.arena.alloc(self.pat_with_node_id_of(p, hir::PatKind::Wild))
283274
}

compiler/rustc_ast_passes/src/ast_validation.rs

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

compiler/rustc_ast_pretty/src/pprust/state.rs

+10-16
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
1111
use rustc_ast::util::classify;
1212
use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle};
1313
use rustc_ast::util::parser;
14-
use rustc_ast::{self as ast, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
15-
use rustc_ast::{attr, Term};
14+
use rustc_ast::{self as ast, BlockCheckMode, Mutability, PatKind, RangeEnd, RangeSyntax};
15+
use rustc_ast::{attr, BindingAnnotation, ByRef, Term};
1616
use rustc_ast::{GenericArg, MacArgs, MacArgsEq};
1717
use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier};
1818
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
@@ -1399,16 +1399,12 @@ impl<'a> State<'a> {
13991399
is that it doesn't matter */
14001400
match pat.kind {
14011401
PatKind::Wild => self.word("_"),
1402-
PatKind::Ident(binding_mode, ident, ref sub) => {
1403-
match binding_mode {
1404-
ast::BindingMode::ByRef(mutbl) => {
1405-
self.word_nbsp("ref");
1406-
self.print_mutability(mutbl, false);
1407-
}
1408-
ast::BindingMode::ByValue(ast::Mutability::Not) => {}
1409-
ast::BindingMode::ByValue(ast::Mutability::Mut) => {
1410-
self.word_nbsp("mut");
1411-
}
1402+
PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, ref sub) => {
1403+
if by_ref == ByRef::Yes {
1404+
self.word_nbsp("ref");
1405+
}
1406+
if mutbl == Mutability::Mut {
1407+
self.word_nbsp("mut");
14121408
}
14131409
self.print_ident(ident);
14141410
if let Some(ref p) = *sub {
@@ -1487,12 +1483,10 @@ impl<'a> State<'a> {
14871483
}
14881484
PatKind::Ref(ref inner, mutbl) => {
14891485
self.word("&");
1490-
if mutbl == ast::Mutability::Mut {
1486+
if mutbl == Mutability::Mut {
14911487
self.word("mut ");
14921488
}
1493-
if let PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Mut), ..) =
1494-
inner.kind
1495-
{
1489+
if let PatKind::Ident(ast::BindingAnnotation::MUT, ..) = inner.kind {
14961490
self.popen();
14971491
self.print_pat(inner);
14981492
self.pclose();

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
367367

368368
if let Some(Node::Pat(pat)) = self.infcx.tcx.hir().find(upvar_hir_id)
369369
&& let hir::PatKind::Binding(
370-
hir::BindingAnnotation::Unannotated,
370+
hir::BindingAnnotation::NONE,
371371
_,
372372
upvar_ident,
373373
_,

0 commit comments

Comments
 (0)