Skip to content

Commit 3df8232

Browse files
committed
fix: labels on the closure body can be disappearing
1 parent beb37b0 commit 3df8232

File tree

1 file changed

+30
-13
lines changed

1 file changed

+30
-13
lines changed

src/closures.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_ast::{ast, ptr};
1+
use rustc_ast::{Label, ast, ptr};
22
use rustc_span::Span;
33
use thin_vec::thin_vec;
44
use tracing::debug;
@@ -55,7 +55,7 @@ pub(crate) fn rewrite_closure(
5555
// 1 = space between `|...|` and body.
5656
let body_shape = shape.offset_left(extra_offset, span)?;
5757

58-
if let ast::ExprKind::Block(ref block, _) = body.kind {
58+
if let ast::ExprKind::Block(ref block, ref label) = body.kind {
5959
// The body of the closure is an empty block.
6060
if block.stmts.is_empty() && !block_contains_comment(context, block) {
6161
return body
@@ -72,7 +72,7 @@ pub(crate) fn rewrite_closure(
7272

7373
result.or_else(|_| {
7474
// Either we require a block, or tried without and failed.
75-
rewrite_closure_block(block, &prefix, context, body_shape)
75+
rewrite_closure_block(block, label, &prefix, context, body_shape)
7676
})
7777
} else {
7878
rewrite_closure_expr(body, &prefix, context, body_shape).or_else(|_| {
@@ -104,8 +104,8 @@ fn get_inner_expr<'a>(
104104
prefix: &str,
105105
context: &RewriteContext<'_>,
106106
) -> &'a ast::Expr {
107-
if let ast::ExprKind::Block(ref block, _) = expr.kind {
108-
if !needs_block(block, prefix, context) {
107+
if let ast::ExprKind::Block(ref block, ref label) = expr.kind {
108+
if !needs_block(block, label, prefix, context) {
109109
// block.stmts.len() == 1 except with `|| {{}}`;
110110
// https://github.com/rust-lang/rustfmt/issues/3844
111111
if let Some(expr) = block.stmts.first().and_then(stmt_expr) {
@@ -118,7 +118,12 @@ fn get_inner_expr<'a>(
118118
}
119119

120120
// Figure out if a block is necessary.
121-
fn needs_block(block: &ast::Block, prefix: &str, context: &RewriteContext<'_>) -> bool {
121+
fn needs_block(
122+
block: &ast::Block,
123+
label: &Option<Label>,
124+
prefix: &str,
125+
context: &RewriteContext<'_>,
126+
) -> bool {
122127
let has_attributes = block.stmts.first().map_or(false, |first_stmt| {
123128
!get_attrs_from_stmt(first_stmt).is_empty()
124129
});
@@ -128,6 +133,7 @@ fn needs_block(block: &ast::Block, prefix: &str, context: &RewriteContext<'_>) -
128133
|| has_attributes
129134
|| block_contains_comment(context, block)
130135
|| prefix.contains('\n')
136+
|| label.is_some()
131137
}
132138

133139
fn veto_block(e: &ast::Expr) -> bool {
@@ -231,15 +237,25 @@ fn rewrite_closure_expr(
231237
// Rewrite closure whose body is block.
232238
fn rewrite_closure_block(
233239
block: &ast::Block,
240+
label: &Option<Label>,
234241
prefix: &str,
235242
context: &RewriteContext<'_>,
236243
shape: Shape,
237244
) -> RewriteResult {
238-
Ok(format!(
239-
"{} {}",
240-
prefix,
241-
block.rewrite_result(context, shape)?
242-
))
245+
if let Some(label) = label {
246+
Ok(format!(
247+
"{} {}: {}",
248+
prefix,
249+
context.snippet(label.ident.span),
250+
block.rewrite_result(context, shape)?
251+
))
252+
} else {
253+
Ok(format!(
254+
"{} {}",
255+
prefix,
256+
block.rewrite_result(context, shape)?
257+
))
258+
}
243259
}
244260

245261
// Return type is (prefix, extra_offset)
@@ -368,10 +384,11 @@ pub(crate) fn rewrite_last_closure(
368384
fn_arg_span: _,
369385
} = **closure;
370386
let body = match body.kind {
371-
ast::ExprKind::Block(ref block, _)
387+
ast::ExprKind::Block(ref block, ref label)
372388
if !is_unsafe_block(block)
373389
&& !context.inside_macro()
374-
&& is_simple_block(context, block, Some(&body.attrs)) =>
390+
&& is_simple_block(context, block, Some(&body.attrs))
391+
&& label.is_none() =>
375392
{
376393
stmt_expr(&block.stmts[0]).unwrap_or(body)
377394
}

0 commit comments

Comments
 (0)