Skip to content

Commit cdccf23

Browse files
authored
Add #![feature(ergonomic_clones)] formatting (#6532)
Tracking issue r-l/rust#134797 Closes 6512
1 parent e3f0a53 commit cdccf23

File tree

5 files changed

+147
-10
lines changed

5 files changed

+147
-10
lines changed

src/chains.rs

+8
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ enum ChainItemKind {
195195
StructField(symbol::Ident),
196196
TupleField(symbol::Ident, bool),
197197
Await,
198+
Use,
198199
Yield,
199200
Comment(String, CommentPosition),
200201
}
@@ -207,6 +208,7 @@ impl ChainItemKind {
207208
| ChainItemKind::StructField(..)
208209
| ChainItemKind::TupleField(..)
209210
| ChainItemKind::Await
211+
| ChainItemKind::Use
210212
| ChainItemKind::Yield
211213
| ChainItemKind::Comment(..) => false,
212214
}
@@ -262,6 +264,10 @@ impl ChainItemKind {
262264
let span = mk_sp(nested.span.hi(), expr.span.hi());
263265
(ChainItemKind::Await, span)
264266
}
267+
ast::ExprKind::Use(ref nested, _) => {
268+
let span = mk_sp(nested.span.hi(), expr.span.hi());
269+
(ChainItemKind::Use, span)
270+
}
265271
ast::ExprKind::Yield(ast::YieldKind::Postfix(ref nested)) => {
266272
let span = mk_sp(nested.span.hi(), expr.span.hi());
267273
(ChainItemKind::Yield, span)
@@ -313,6 +319,7 @@ impl Rewrite for ChainItem {
313319
rewrite_ident(context, ident)
314320
),
315321
ChainItemKind::Await => ".await".to_owned(),
322+
ChainItemKind::Use => ".use".to_owned(),
316323
ChainItemKind::Yield => ".yield".to_owned(),
317324
ChainItemKind::Comment(ref comment, _) => {
318325
rewrite_comment(comment, false, shape, context.config)?
@@ -517,6 +524,7 @@ impl Chain {
517524
ast::ExprKind::Field(ref subexpr, _)
518525
| ast::ExprKind::Try(ref subexpr)
519526
| ast::ExprKind::Await(ref subexpr, _)
527+
| ast::ExprKind::Use(ref subexpr, _)
520528
| ast::ExprKind::Yield(ast::YieldKind::Postfix(ref subexpr)) => Some(SubExpr {
521529
expr: Self::convert_try(subexpr, context),
522530
is_method_call_receiver: false,

src/closures.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -294,14 +294,14 @@ fn rewrite_closure_fn_decl(
294294
Some(ast::CoroutineKind::AsyncGen { .. }) => "async gen ",
295295
None => "",
296296
};
297-
let mover = if matches!(capture, ast::CaptureBy::Value { .. }) {
298-
"move "
299-
} else {
300-
""
297+
let capture_str = match capture {
298+
ast::CaptureBy::Value { .. } => "move ",
299+
ast::CaptureBy::Use { .. } => "use ",
300+
ast::CaptureBy::Ref => "",
301301
};
302302
// 4 = "|| {".len(), which is overconservative when the closure consists of
303303
// a single expression.
304-
let offset = binder.len() + const_.len() + immovable.len() + coro.len() + mover.len();
304+
let offset = binder.len() + const_.len() + immovable.len() + coro.len() + capture_str.len();
305305
let nested_shape = shape.shrink_left(offset, span)?.sub_width(4, span)?;
306306

307307
// 1 = |
@@ -339,7 +339,7 @@ fn rewrite_closure_fn_decl(
339339
.tactic(tactic)
340340
.preserve_newline(true);
341341
let list_str = write_list(&item_vec, &fmt)?;
342-
let mut prefix = format!("{binder}{const_}{immovable}{coro}{mover}|{list_str}|");
342+
let mut prefix = format!("{binder}{const_}{immovable}{coro}{capture_str}|{list_str}|");
343343

344344
if !ret_str.is_empty() {
345345
if prefix.contains('\n') {

src/expr.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,6 @@ pub(crate) fn format_expr(
161161
ast::ExprKind::Tup(ref items) => {
162162
rewrite_tuple(context, items.iter(), expr.span, shape, items.len() == 1)
163163
}
164-
ast::ExprKind::Use(_, _) => {
165-
// FIXME: properly implement this
166-
Ok(context.snippet(expr.span()).to_owned())
167-
}
168164
ast::ExprKind::Let(ref pat, ref expr, _span, _) => rewrite_let(context, shape, pat, expr),
169165
ast::ExprKind::If(..)
170166
| ast::ExprKind::ForLoop { .. }
@@ -276,6 +272,7 @@ pub(crate) fn format_expr(
276272
| ast::ExprKind::Field(..)
277273
| ast::ExprKind::MethodCall(..)
278274
| ast::ExprKind::Await(_, _)
275+
| ast::ExprKind::Use(_, _)
279276
| ast::ExprKind::Yield(ast::YieldKind::Postfix(_)) => rewrite_chain(expr, context, shape),
280277
ast::ExprKind::MacCall(ref mac) => {
281278
rewrite_macro(mac, context, shape, MacroPosition::Expression).or_else(|_| {

tests/source/ergonomic_clones.rs

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// rustfmt-edition: 2018
2+
3+
#![feature(ergonomic_clones)]
4+
5+
mod closure_syntax {
6+
fn ergonomic_clone_closure_no_captures() -> i32 {
7+
let cl = use || {
8+
1
9+
};
10+
cl()
11+
}
12+
13+
fn ergonomic_clone_closure_move() -> String {
14+
let s = String::from("hi");
15+
16+
let cl = use || {
17+
s
18+
};
19+
cl()
20+
}
21+
22+
fn ergonomic_clone_closure_use_cloned() -> Foo {
23+
let f = Foo;
24+
25+
let f1 = use || {
26+
f
27+
};
28+
29+
let f2 = use || {
30+
f
31+
};
32+
33+
f
34+
}
35+
36+
fn ergonomic_clone_closure_copy() -> i32 {
37+
let i = 1;
38+
39+
let i1 = use || {
40+
i
41+
};
42+
43+
let i2 = use || {
44+
i
45+
};
46+
47+
i
48+
}
49+
50+
fn nested() {
51+
let a = Box::new(Foo);
52+
foo(use || { foo(use || { work(a) }) });
53+
let x = use || { use || { Foo } };
54+
let _y = x();
55+
}
56+
57+
fn with_binders() {
58+
for<'a> use || -> () {};
59+
}
60+
}
61+
62+
mod dotuse {
63+
fn basic_test(x: i32) -> i32 {
64+
x.use
65+
.use
66+
.abs()
67+
}
68+
69+
fn do_not_move_test(x: Foo) -> Foo {
70+
let s = x.use;
71+
x
72+
}
73+
}

tests/target/ergonomic_clones.rs

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// rustfmt-edition: 2018
2+
3+
#![feature(ergonomic_clones)]
4+
5+
mod closure_syntax {
6+
fn ergonomic_clone_closure_no_captures() -> i32 {
7+
let cl = use || 1;
8+
cl()
9+
}
10+
11+
fn ergonomic_clone_closure_move() -> String {
12+
let s = String::from("hi");
13+
14+
let cl = use || s;
15+
cl()
16+
}
17+
18+
fn ergonomic_clone_closure_use_cloned() -> Foo {
19+
let f = Foo;
20+
21+
let f1 = use || f;
22+
23+
let f2 = use || f;
24+
25+
f
26+
}
27+
28+
fn ergonomic_clone_closure_copy() -> i32 {
29+
let i = 1;
30+
31+
let i1 = use || i;
32+
33+
let i2 = use || i;
34+
35+
i
36+
}
37+
38+
fn nested() {
39+
let a = Box::new(Foo);
40+
foo(use || foo(use || work(a)));
41+
let x = use || use || Foo;
42+
let _y = x();
43+
}
44+
45+
fn with_binders() {
46+
for<'a> use || -> () {};
47+
}
48+
}
49+
50+
mod dotuse {
51+
fn basic_test(x: i32) -> i32 {
52+
x.use.use.abs()
53+
}
54+
55+
fn do_not_move_test(x: Foo) -> Foo {
56+
let s = x.use;
57+
x
58+
}
59+
}

0 commit comments

Comments
 (0)