`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
diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs
index 6974e65..7a24d07 100644
--- a/clippy_utils/src/sugg.rs
+++ b/clippy_utils/src/sugg.rs
@@ -494,7 +494,17 @@
/// 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 @@
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 0e3e4cf..ecb82a2 100644
--- a/tests/ui/nonminimal_bool.stderr
+++ b/tests/ui/nonminimal_bool.stderr
@@ -179,7 +179,7 @@
--> 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 @@
--> 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