Skip to content

Commit 601e25d

Browse files
committed
Wrap Cast expr in parens when the ty ends with empty angle brackets
Fixes 4621 Previously rustfmt would remove empty angle brackets from cast expressions e.g. `x as i32<>` => `x as i32`. This lead to code that could not compile when the cast occurred in an if statement. The advice from the compiler was to wrap the cast in parentheses, which is now the behavior rustfmt employs.
1 parent 7b73b60 commit 601e25d

File tree

3 files changed

+53
-8
lines changed

3 files changed

+53
-8
lines changed

src/expr.rs

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::borrow::Cow;
22
use std::cmp::min;
33
use std::collections::HashMap;
4+
use std::ops::Deref;
45

56
use itertools::Itertools;
67
use rustc_ast::token::{Delimiter, LitKind};
@@ -282,14 +283,31 @@ fn format_expr_inner(
282283
ast::ExprKind::AddrOf(borrow_kind, mutability, ref expr) => {
283284
rewrite_expr_addrof(context, borrow_kind, mutability, expr, shape)
284285
}
285-
ast::ExprKind::Cast(ref expr, ref ty) => rewrite_pair(
286-
&**expr,
287-
&**ty,
288-
PairParts::infix(" as "),
289-
context,
290-
shape,
291-
SeparatorPlace::Front,
292-
),
286+
ast::ExprKind::Cast(ref expr, ref ty) => {
287+
let mut result = String::new();
288+
let empty_angle_brackets = ty_ends_with_empty_angle_brackets(ty);
289+
let shape = if empty_angle_brackets {
290+
result.push('(');
291+
shape.sub_width(2)?
292+
} else {
293+
shape
294+
};
295+
296+
result.push_str(&rewrite_pair(
297+
&**expr,
298+
&**ty,
299+
PairParts::infix(" as "),
300+
context,
301+
shape,
302+
SeparatorPlace::Front,
303+
)?);
304+
305+
if empty_angle_brackets {
306+
result.push(')');
307+
}
308+
309+
Some(result)
310+
}
293311
ast::ExprKind::Type(ref expr, ref ty) => rewrite_pair(
294312
&**expr,
295313
&**ty,
@@ -458,6 +476,21 @@ fn format_expr_inner(
458476
})
459477
}
460478

479+
fn ty_ends_with_empty_angle_brackets(ty: &ast::Ty) -> bool {
480+
if let ast::TyKind::Path(_, path) = &ty.kind {
481+
matches!(
482+
path.segments.last(),
483+
Some(ast::PathSegment {args: Some(generic_args), ..})
484+
if matches!(
485+
generic_args.deref(),
486+
ast::GenericArgs::AngleBracketed(bracket_args) if bracket_args.args.is_empty()
487+
)
488+
)
489+
} else {
490+
false
491+
}
492+
}
493+
461494
pub(crate) fn rewrite_array<'a, T: 'a + IntoOverflowableItem<'a>>(
462495
name: &'a str,
463496
exprs: impl Iterator<Item = &'a T>,
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pub fn foo() {
2+
let x: u32 = 100;
3+
if x as i32<> < 0 {
4+
// ...
5+
}
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pub fn foo() {
2+
let x: u32 = 100;
3+
if (x as i32) < 0 {
4+
// ...
5+
}
6+
}

0 commit comments

Comments
 (0)