From 2037075b38ae2af58b1c0b6860a559892f766fa4 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 5 Jun 2025 22:03:05 +0200 Subject: [PATCH] `Sugg`: do not parenthesize a double unary operator For example, adding `*` in front of `*expression` is best shown as `**expression` rather than `*(*expression)`. This is not perfect, as it checks whether the operator is already a prefix of the expression, but it is better than it was before. For example, `&`+`&mut x` will get `&&mut x` but `&mut `+`&x` will get `&mut (&x)` as it did before this change. --- clippy_utils/src/sugg.rs | 22 +++++++++++++++++++++- tests/ui/nonminimal_bool.stderr | 4 ++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index 6974e6512e2c..7a24d07fa1df 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -494,7 +494,17 @@ impl Display for ParenHelper { /// operators have the same /// precedence. pub fn make_unop(op: &str, expr: Sugg<'_>) -> Sugg<'static> { - Sugg::MaybeParen(format!("{op}{}", expr.maybe_paren()).into()) + // If the `expr` starts with `op` already, do not add wrap it in + // parentheses. + let expr = if let Sugg::MaybeParen(ref sugg) = expr + && !has_enclosing_paren(sugg) + && sugg.starts_with(op) + { + expr + } else { + expr.maybe_paren() + }; + Sugg::MaybeParen(format!("{op}{expr}").into()) } /// Builds the string for ` ` adding parenthesis when necessary. @@ -1016,6 +1026,16 @@ mod test { let sugg = Sugg::BinOp(AssocOp::Binary(ast::BinOpKind::Add), "(1 + 1)".into(), "(1 + 1)".into()); assert_eq!("((1 + 1) + (1 + 1))", sugg.maybe_paren().to_string()); } + + #[test] + fn unop_parenthesize() { + let sugg = Sugg::NonParen("x".into()).mut_addr(); + assert_eq!("&mut x", sugg.to_string()); + let sugg = sugg.mut_addr(); + assert_eq!("&mut &mut x", sugg.to_string()); + assert_eq!("(&mut &mut x)", sugg.maybe_paren().to_string()); + } + #[test] fn not_op() { use ast::BinOpKind::{Add, And, Eq, Ge, Gt, Le, Lt, Ne, Or}; diff --git a/tests/ui/nonminimal_bool.stderr b/tests/ui/nonminimal_bool.stderr index 0e3e4cf7988e..ecb82a23da03 100644 --- a/tests/ui/nonminimal_bool.stderr +++ b/tests/ui/nonminimal_bool.stderr @@ -179,7 +179,7 @@ error: inequality checks against true can be replaced by a negation --> tests/ui/nonminimal_bool.rs:186:8 | LL | if !b != true {} - | ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)` + | ^^^^^^^^^^ help: try simplifying it as shown: `!!b` error: this boolean expression can be simplified --> tests/ui/nonminimal_bool.rs:189:8 @@ -209,7 +209,7 @@ error: inequality checks against true can be replaced by a negation --> tests/ui/nonminimal_bool.rs:193:8 | LL | if true != !b {} - | ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)` + | ^^^^^^^^^^ help: try simplifying it as shown: `!!b` error: this boolean expression can be simplified --> tests/ui/nonminimal_bool.rs:196:8