diff options
| author | Jason Newcomb <jsnewcomb@pm.me> | 2025-06-20 22:00:40 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-20 22:00:40 +0000 |
| commit | 37cb83488afb47c3405da01f170def7ac4104f51 (patch) | |
| tree | 65ed37b7fa30791d98da70784c8c9752079e41fd | |
| parent | 98555244f05499b1cad768713da9a10d80992964 (diff) | |
| parent | 2037075b38ae2af58b1c0b6860a559892f766fa4 (diff) | |
| download | rust-37cb83488afb47c3405da01f170def7ac4104f51.tar.gz rust-37cb83488afb47c3405da01f170def7ac4104f51.zip | |
`Sugg`: do not parenthesize a double unary operator (#14983)
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. changelog: none
| -rw-r--r-- | clippy_utils/src/sugg.rs | 22 | ||||
| -rw-r--r-- | 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 6974e6512e2..7a24d07fa1d 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -494,7 +494,17 @@ impl<T: Display> Display for ParenHelper<T> { /// 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 `<lhs> <op> <rhs>` 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 0e3e4cf7988..ecb82a23da0 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 |
