diff --git a/src/expr.rs b/src/expr.rs index f0e56ffb8ea..67f97cab254 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1660,14 +1660,15 @@ pub(crate) fn span_ends_with_comma(context: &RewriteContext<'_>, span: Span) -> result } -pub(crate) fn rewrite_paren( +/// Remove any unnecessary nested parentheses from the expression. Parentheses are unnecessary when +/// they contain only whitespace. +pub(crate) fn unwrap_parens<'a, R: Rewrite + Spanned>( context: &RewriteContext<'_>, - mut subexpr: &ast::Expr, + mut subexpr: &'a R, shape: Shape, mut span: Span, -) -> RewriteResult { - debug!("rewrite_paren, shape: {:?}", shape); - + nested_getter: fn(&R) -> Option<&R>, +) -> Result<(&'a R, Span, Span, String, String), RewriteError> { // Extract comments within parens. let mut pre_span; let mut post_span; @@ -1677,14 +1678,14 @@ pub(crate) fn rewrite_paren( loop { // 1 = "(" or ")" pre_span = mk_sp(span.lo() + BytePos(1), subexpr.span().lo()); - post_span = mk_sp(subexpr.span.hi(), span.hi() - BytePos(1)); + post_span = mk_sp(subexpr.span().hi(), span.hi() - BytePos(1)); pre_comment = rewrite_missing_comment(pre_span, shape, context)?; post_comment = rewrite_missing_comment(post_span, shape, context)?; // Remove nested parens if there are no comments. - if let ast::ExprKind::Paren(ref subsubexpr) = subexpr.kind { + if let Some(subsubexpr) = nested_getter(&subexpr) { if remove_nested_parens && pre_comment.is_empty() && post_comment.is_empty() { - span = subexpr.span; + span = subexpr.span(); subexpr = subsubexpr; continue; } @@ -1692,6 +1693,27 @@ pub(crate) fn rewrite_paren( break; } + Ok((subexpr, pre_span, post_span, pre_comment, post_comment)) +} + +pub(crate) fn rewrite_paren( + context: &RewriteContext<'_>, + subexpr: &ast::Expr, + shape: Shape, + span: Span, +) -> RewriteResult { + debug!("rewrite_paren, shape: {:?}", shape); + + let (subexpr, pre_span, post_span, pre_comment, post_comment) = unwrap_parens( + context, + subexpr, + shape, + span, + |expr: &ast::Expr| match &expr.kind { + ast::ExprKind::Paren(subsubexpr) => Some(subsubexpr), + _ => None, + }, + )?; // 1 = `(` and `)` let sub_shape = shape.offset_left(1, span)?.sub_width(1, span)?; diff --git a/src/types.rs b/src/types.rs index e2c92e58062..8703636df71 100644 --- a/src/types.rs +++ b/src/types.rs @@ -9,6 +9,7 @@ use crate::config::lists::*; use crate::config::{IndentStyle, StyleEdition, TypeDensity}; use crate::expr::{ ExprType, RhsAssignKind, format_expr, rewrite_assign_rhs, rewrite_tuple, rewrite_unary_prefix, + unwrap_parens, }; use crate::lists::{ ListFormatting, ListItem, Separator, definitive_tactic, itemize_list, write_list, @@ -928,6 +929,18 @@ impl Rewrite for ast::Ty { .rewrite_result(context, Shape::legacy(budget, shape.indent + 1)) .map(|ty_str| format!("({})", ty_str)); } + let ty = if context.config.style_edition() < StyleEdition::Edition2027 { + ty + } else { + let (ty, _, _, _, _) = + unwrap_parens(context, ty.as_ref(), shape, self.span, |ty: &ast::Ty| { + match &ty.kind { + ast::TyKind::Paren(nested) => Some(nested), + _ => None, + } + })?; + ty + }; // 2 = () if let Some(sh) = shape.sub_width_opt(2) { diff --git a/tests/source/struct_fields.rs b/tests/source/struct_fields.rs new file mode 100644 index 00000000000..9b0fff71227 --- /dev/null +++ b/tests/source/struct_fields.rs @@ -0,0 +1,7 @@ +// rustfmt-style_edition: 2027 + +struct F { + f: ((u32)), +} + +struct F(((u32))); diff --git a/tests/target/struct_fields.rs b/tests/target/struct_fields.rs new file mode 100644 index 00000000000..8b374d055ea --- /dev/null +++ b/tests/target/struct_fields.rs @@ -0,0 +1,7 @@ +// rustfmt-style_edition: 2027 + +struct F { + f: (u32), +} + +struct F((u32));