Skip to content

Commit

Permalink
Merge pull request #1692 from dtolnay/break
Browse files Browse the repository at this point in the history
Parenthesize break values containing leading label
  • Loading branch information
dtolnay authored Jul 2, 2024
2 parents cc5e64e + 4e71c1c commit 1560f9a
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 2 deletions.
53 changes: 53 additions & 0 deletions src/classify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,59 @@ pub(crate) fn confusable_with_adjacent_lt(mut expr: &Expr) -> bool {
}
}

/// Whether the expression's first token is the label of a loop/block.
#[cfg(all(feature = "printing", feature = "full"))]
pub(crate) fn expr_leading_label(mut expr: &Expr) -> bool {
loop {
match expr {
Expr::Block(e) => return e.label.is_some(),
Expr::ForLoop(e) => return e.label.is_some(),
Expr::Loop(e) => return e.label.is_some(),
Expr::While(e) => return e.label.is_some(),

Expr::Assign(e) => expr = &e.left,
Expr::Await(e) => expr = &e.base,
Expr::Binary(e) => expr = &e.left,
Expr::Call(e) => expr = &e.func,
Expr::Cast(e) => expr = &e.expr,
Expr::Field(e) => expr = &e.base,
Expr::Index(e) => expr = &e.expr,
Expr::MethodCall(e) => expr = &e.receiver,
Expr::Range(e) => match &e.start {
Some(start) => expr = start,
None => return false,
},
Expr::Try(e) => expr = &e.expr,

Expr::Array(_)
| Expr::Async(_)
| Expr::Break(_)
| Expr::Closure(_)
| Expr::Const(_)
| Expr::Continue(_)
| Expr::Group(_)
| Expr::If(_)
| Expr::Infer(_)
| Expr::Let(_)
| Expr::Lit(_)
| Expr::Macro(_)
| Expr::Match(_)
| Expr::Paren(_)
| Expr::Path(_)
| Expr::Reference(_)
| Expr::Repeat(_)
| Expr::Return(_)
| Expr::Struct(_)
| Expr::TryBlock(_)
| Expr::Tuple(_)
| Expr::Unary(_)
| Expr::Unsafe(_)
| Expr::Verbatim(_)
| Expr::Yield(_) => return false,
}
}
}

/// Whether the expression's last token is `}`.
#[cfg(feature = "full")]
pub(crate) fn expr_trailing_brace(mut expr: &Expr) -> bool {
Expand Down
11 changes: 9 additions & 2 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3286,8 +3286,15 @@ pub(crate) mod printing {
outer_attrs_to_tokens(&e.attrs, tokens);
e.break_token.to_tokens(tokens);
e.label.to_tokens(tokens);
if let Some(expr) = &e.expr {
print_expr(expr, tokens, fixup.subsequent_subexpression());
if let Some(value) = &e.expr {
print_subexpression(
value,
// Parenthesize `break 'inner: loop { break 'inner 1 } + 1`
// ^---------------------------------^
e.label.is_none() && classify::expr_leading_label(value),
tokens,
fixup.subsequent_subexpression(),
);
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/test_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,7 @@ fn test_fixup() {
quote! { match m { _ => ({}) - 1 } },
quote! { if let _ = (a && b) && c {} },
quote! { if let _ = (S {}) {} },
quote! { break ('a: loop { break 'a 1 } + 1) },
] {
let original: Expr = syn::parse2(tokens).unwrap();

Expand Down

0 comments on commit 1560f9a

Please sign in to comment.