clippy_utils: fix needless parenthesis output from sugg::Sugg::maybe_par

This commit is contained in:
Yoshitomo Nakanishi 2021-04-01 10:39:44 +09:00
parent 8cf7d9b037
commit 6325fe1f54
5 changed files with 44 additions and 6 deletions

View file

@ -267,17 +267,44 @@ impl<'a> Sugg<'a> {
Sugg::NonParen(..) => self,
// `(x)` and `(x).y()` both don't need additional parens.
Sugg::MaybeParen(sugg) => {
if sugg.starts_with('(') && sugg.ends_with(')') {
if has_enclosing_paren(&sugg) {
Sugg::MaybeParen(sugg)
} else {
Sugg::NonParen(format!("({})", sugg).into())
}
},
Sugg::BinOp(_, sugg) => Sugg::NonParen(format!("({})", sugg).into()),
Sugg::BinOp(_, sugg) => {
if has_enclosing_paren(&sugg) {
Sugg::NonParen(sugg)
} else {
Sugg::NonParen(format!("({})", sugg).into())
}
},
}
}
}
/// Return `true` if `sugg` is enclosed in parenthesis.
fn has_enclosing_paren(sugg: impl AsRef<str>) -> bool {
let mut chars = sugg.as_ref().chars();
if let Some('(') = chars.next() {
let mut depth = 1;
while let Some(c) = chars.next() {
if c == '(' {
depth += 1;
} else if c == ')' {
depth -= 1;
}
if depth == 0 {
break;
}
}
chars.next().is_none()
} else {
false
}
}
// Copied from the rust standart library, and then edited
macro_rules! forward_binop_impls_to_ref {
(impl $imp:ident, $method:ident for $t:ty, type Output = $o:ty) => {
@ -668,6 +695,8 @@ impl<T: LintContext> DiagnosticBuilderExt<T> for rustc_errors::DiagnosticBuilder
#[cfg(test)]
mod test {
use super::Sugg;
use rustc_ast::util::parser::AssocOp;
use std::borrow::Cow;
const SUGGESTION: Sugg<'static> = Sugg::NonParen(Cow::Borrowed("function_call()"));
@ -681,4 +710,13 @@ mod test {
fn blockify_transforms_sugg_into_a_block() {
assert_eq!("{ function_call() }", SUGGESTION.blockify().to_string());
}
#[test]
fn binop_maybe_par() {
let sugg = Sugg::BinOp(AssocOp::Add, "(1 + 1)".into());
assert_eq!("(1 + 1)", sugg.maybe_par().to_string());
let sugg = Sugg::BinOp(AssocOp::Add, "(1 + 1) + (1 + 1)".into());
assert_eq!("((1 + 1) + (1 + 1))", sugg.maybe_par().to_string());
}
}