@@ -267,17 +267,44 @@ impl<'a> Sugg<'a> {
267267 Sugg :: NonParen ( ..) => self ,
268268 // `(x)` and `(x).y()` both don't need additional parens.
269269 Sugg :: MaybeParen ( sugg) => {
270- if sugg . starts_with ( '(' ) && sugg. ends_with ( ')' ) {
270+ if has_enclosing_paren ( & sugg) {
271271 Sugg :: MaybeParen ( sugg)
272272 } else {
273273 Sugg :: NonParen ( format ! ( "({})" , sugg) . into ( ) )
274274 }
275275 } ,
276- Sugg :: BinOp ( _, sugg) => Sugg :: NonParen ( format ! ( "({})" , sugg) . into ( ) ) ,
276+ Sugg :: BinOp ( _, sugg) => {
277+ if has_enclosing_paren ( & sugg) {
278+ Sugg :: NonParen ( sugg)
279+ } else {
280+ Sugg :: NonParen ( format ! ( "({})" , sugg) . into ( ) )
281+ }
282+ } ,
277283 }
278284 }
279285}
280286
287+ /// Return `true` if `sugg` is enclosed in parenthesis.
288+ fn has_enclosing_paren ( sugg : impl AsRef < str > ) -> bool {
289+ let mut chars = sugg. as_ref ( ) . chars ( ) ;
290+ if let Some ( '(' ) = chars. next ( ) {
291+ let mut depth = 1 ;
292+ while let Some ( c) = chars. next ( ) {
293+ if c == '(' {
294+ depth += 1 ;
295+ } else if c == ')' {
296+ depth -= 1 ;
297+ }
298+ if depth == 0 {
299+ break ;
300+ }
301+ }
302+ chars. next ( ) . is_none ( )
303+ } else {
304+ false
305+ }
306+ }
307+
281308// Copied from the rust standart library, and then edited
282309macro_rules! forward_binop_impls_to_ref {
283310 ( 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
668695#[ cfg( test) ]
669696mod test {
670697 use super :: Sugg ;
698+
699+ use rustc_ast:: util:: parser:: AssocOp ;
671700 use std:: borrow:: Cow ;
672701
673702 const SUGGESTION : Sugg < ' static > = Sugg :: NonParen ( Cow :: Borrowed ( "function_call()" ) ) ;
@@ -681,4 +710,13 @@ mod test {
681710 fn blockify_transforms_sugg_into_a_block ( ) {
682711 assert_eq ! ( "{ function_call() }" , SUGGESTION . blockify( ) . to_string( ) ) ;
683712 }
713+
714+ #[ test]
715+ fn binop_maybe_par ( ) {
716+ let sugg = Sugg :: BinOp ( AssocOp :: Add , "(1 + 1)" . into ( ) ) ;
717+ assert_eq ! ( "(1 + 1)" , sugg. maybe_par( ) . to_string( ) ) ;
718+
719+ let sugg = Sugg :: BinOp ( AssocOp :: Add , "(1 + 1) + (1 + 1)" . into ( ) ) ;
720+ assert_eq ! ( "((1 + 1) + (1 + 1))" , sugg. maybe_par( ) . to_string( ) ) ;
721+ }
684722}
0 commit comments