Skip to content

Commit 8f1be83

Browse files
committed
Implement &pin patterns and ref pin bindings
1 parent 5bc58c7 commit 8f1be83

4 files changed

Lines changed: 91 additions & 18 deletions

File tree

src/patterns.rs

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ use crate::shape::Shape;
1717
use crate::source_map::SpanUtils;
1818
use crate::spanned::Spanned;
1919
use crate::types::{PathContext, rewrite_path};
20-
use crate::utils::{format_mutability, mk_sp, mk_sp_lo_plus_one, rewrite_ident};
20+
use crate::utils::{
21+
format_mutability, format_pinnedness_and_mutability, mk_sp, mk_sp_lo_plus_one, rewrite_ident,
22+
};
2123

2224
/// Returns `true` if the given pattern is "short".
2325
/// A short pattern is defined by the following grammar:
@@ -69,7 +71,7 @@ fn is_short_pattern_inner(context: &RewriteContext<'_>, pat: &ast::Pat) -> bool
6971
}
7072
ast::PatKind::Box(ref p)
7173
| PatKind::Deref(ref p)
72-
| ast::PatKind::Ref(ref p, _)
74+
| ast::PatKind::Ref(ref p, _, _)
7375
| ast::PatKind::Paren(ref p) => is_short_pattern_inner(context, &*p),
7476
PatKind::Or(ref pats) => pats.iter().all(|p| is_short_pattern_inner(context, p)),
7577
}
@@ -133,10 +135,13 @@ impl Rewrite for Pat {
133135
PatKind::Ident(BindingMode(by_ref, mutability), ident, ref sub_pat) => {
134136
let mut_prefix = format_mutability(mutability).trim();
135137

136-
let (ref_kw, mut_infix) = match by_ref {
137-
// FIXME(pin_ergonomics): format the pinnedness
138-
ByRef::Yes(_, rmutbl) => ("ref", format_mutability(rmutbl).trim()),
139-
ByRef::No => ("", ""),
138+
let (ref_kw, pin_infix, mut_infix) = match by_ref {
139+
ByRef::Yes(pinnedness, rmutbl) => {
140+
let (pin_infix, mut_infix) =
141+
format_pinnedness_and_mutability(pinnedness, rmutbl);
142+
("ref", pin_infix.trim(), mut_infix.trim())
143+
}
144+
ByRef::No => ("", "", ""),
140145
};
141146
let id_str = rewrite_ident(context, ident);
142147
let sub_pat = match *sub_pat {
@@ -147,6 +152,7 @@ impl Rewrite for Pat {
147152
.checked_sub(
148153
mut_prefix.len()
149154
+ ref_kw.len()
155+
+ pin_infix.len()
150156
+ mut_infix.len()
151157
+ id_str.len()
152158
+ 2,
@@ -193,26 +199,51 @@ impl Rewrite for Pat {
193199
(true, true) => (self.span.lo(), "".to_owned()),
194200
};
195201

196-
// combine result of above and mut
197-
let (second_lo, second) = match (first.is_empty(), mut_infix.is_empty()) {
202+
// combine result of above and pin
203+
let (second_lo, second) = match (first.is_empty(), pin_infix.is_empty()) {
198204
(false, false) => {
199205
let lo = context.snippet_provider.span_after(self.span, "ref");
200-
let end_span = mk_sp(first_lo, self.span.hi());
201-
let hi = context.snippet_provider.span_before(end_span, "mut");
206+
let hi = context.snippet_provider.span_before(self.span, "pin");
202207
(
203-
context.snippet_provider.span_after(end_span, "mut"),
208+
context.snippet_provider.span_after(self.span, "pin"),
204209
combine_strs_with_missing_comments(
205210
context,
206211
&first,
207-
mut_infix,
212+
pin_infix,
208213
mk_sp(lo, hi),
209214
shape,
210215
true,
211216
)?,
212217
)
213218
}
214219
(false, true) => (first_lo, first),
215-
(true, false) => unreachable!("mut_infix necessarily follows a ref"),
220+
(true, false) => unreachable!("pin_infix necessarily follows a ref"),
221+
(true, true) => (self.span.lo(), "".to_owned()),
222+
};
223+
224+
// combine result of above and const|mut
225+
let (third_lo, third) = match (second.is_empty(), mut_infix.is_empty()) {
226+
(false, false) => {
227+
let lo = context.snippet_provider.span_after(
228+
self.span,
229+
if pin_infix.is_empty() { "ref" } else { "pin" },
230+
);
231+
let end_span = mk_sp(second_lo, self.span.hi());
232+
let hi = context.snippet_provider.span_before(end_span, mut_infix);
233+
(
234+
context.snippet_provider.span_after(end_span, mut_infix),
235+
combine_strs_with_missing_comments(
236+
context,
237+
&second,
238+
mut_infix,
239+
mk_sp(lo, hi),
240+
shape,
241+
true,
242+
)?,
243+
)
244+
}
245+
(false, true) => (second_lo, second),
246+
(true, false) => unreachable!("mut_infix necessarily follows a pin or ref"),
216247
(true, true) => (self.span.lo(), "".to_owned()),
217248
};
218249

@@ -232,9 +263,9 @@ impl Rewrite for Pat {
232263

233264
combine_strs_with_missing_comments(
234265
context,
235-
&second,
266+
&third,
236267
&next,
237-
mk_sp(second_lo, ident.span.lo()),
268+
mk_sp(third_lo, ident.span.lo()),
238269
shape,
239270
true,
240271
)
@@ -263,8 +294,10 @@ impl Rewrite for Pat {
263294
PatKind::Range(ref lhs, ref rhs, ref end_kind) => {
264295
rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span)
265296
}
266-
PatKind::Ref(ref pat, mutability) => {
267-
let prefix = format!("&{}", format_mutability(mutability));
297+
PatKind::Ref(ref pat, pinnedness, mutability) => {
298+
let (pin_prefix, mut_prefix) =
299+
format_pinnedness_and_mutability(pinnedness, mutability);
300+
let prefix = format!("&{}{}", pin_prefix, mut_prefix);
268301
rewrite_unary_prefix(context, &prefix, &**pat, shape)
269302
}
270303
PatKind::Tuple(ref items) => rewrite_tuple_pat(items, None, self.span, context, shape),
@@ -551,7 +584,7 @@ pub(crate) fn can_be_overflowed_pat(
551584
| ast::PatKind::Tuple(..)
552585
| ast::PatKind::Struct(..)
553586
| ast::PatKind::TupleStruct(..) => context.use_block_indent() && len == 1,
554-
ast::PatKind::Ref(ref p, _) | ast::PatKind::Box(ref p) => {
587+
ast::PatKind::Ref(ref p, _, _) | ast::PatKind::Box(ref p) => {
555588
can_be_overflowed_pat(context, &TuplePatField::Pat(p), len)
556589
}
557590
ast::PatKind::Expr(ref expr) => can_be_overflowed_expr(context, expr, len),

src/utils.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,19 @@ pub(crate) fn format_mutability(mutability: ast::Mutability) -> &'static str {
132132
}
133133
}
134134

135+
#[inline]
136+
pub(crate) fn format_pinnedness_and_mutability(
137+
pinnedness: ast::Pinnedness,
138+
mutability: ast::Mutability,
139+
) -> (&'static str, &'static str) {
140+
match (pinnedness, mutability) {
141+
(ast::Pinnedness::Pinned, ast::Mutability::Mut) => ("pin ", "mut "),
142+
(ast::Pinnedness::Pinned, ast::Mutability::Not) => ("pin ", "const "),
143+
(ast::Pinnedness::Not, ast::Mutability::Mut) => ("", "mut "),
144+
(ast::Pinnedness::Not, ast::Mutability::Not) => ("", ""),
145+
}
146+
}
147+
135148
#[inline]
136149
pub(crate) fn format_extern(ext: ast::Extern, explicit_abi: bool) -> Cow<'static, str> {
137150
match ext {

tests/source/pin_sugar.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,22 @@ fn borrows() {
2828
pin const
2929
foo;
3030
}
31+
32+
fn patterns<'a>(
33+
&pin mut x: &pin
34+
mut
35+
i32,
36+
&
37+
pin
38+
const
39+
y: &
40+
'a pin
41+
const
42+
i32,
43+
ref pin mut z: i32,
44+
mut
45+
ref
46+
pin
47+
const
48+
w: i32,
49+
) {}

tests/target/pin_sugar.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,11 @@ fn borrows() {
2323

2424
let x: Pin<&_> = &pin const foo;
2525
}
26+
27+
fn patterns<'a>(
28+
&pin mut x: &pin mut i32,
29+
&pin const y: &'a pin const i32,
30+
ref pin mut z: i32,
31+
mut ref pin const w: i32,
32+
) {
33+
}

0 commit comments

Comments
 (0)