@@ -565,10 +565,24 @@ trait UnusedDelimLint {
565565 lint. set_arg ( "delim" , Self :: DELIM_STR ) ;
566566 lint. set_arg ( "item" , msg) ;
567567 if let Some ( ( lo, hi) ) = spans {
568- let replacement = vec ! [
569- ( lo, if keep_space. 0 { " " . into( ) } else { "" . into( ) } ) ,
570- ( hi, if keep_space. 1 { " " . into( ) } else { "" . into( ) } ) ,
571- ] ;
568+ let sm = cx. sess ( ) . source_map ( ) ;
569+ let lo_replace =
570+ if keep_space. 0 &&
571+ let Ok ( snip) = sm. span_to_prev_source ( lo) && !snip. ends_with ( " " ) {
572+ " " . to_string ( )
573+ } else {
574+ "" . to_string ( )
575+ } ;
576+
577+ let hi_replace =
578+ if keep_space. 1 &&
579+ let Ok ( snip) = sm. span_to_next_source ( hi) && !snip. starts_with ( " " ) {
580+ " " . to_string ( )
581+ } else {
582+ "" . to_string ( )
583+ } ;
584+
585+ let replacement = vec ! [ ( lo, lo_replace) , ( hi, hi_replace) ] ;
572586 lint. multipart_suggestion (
573587 fluent:: suggestion,
574588 replacement,
@@ -765,6 +779,7 @@ impl UnusedParens {
765779 value : & ast:: Pat ,
766780 avoid_or : bool ,
767781 avoid_mut : bool ,
782+ keep_space : ( bool , bool ) ,
768783 ) {
769784 use ast:: { BindingAnnotation , PatKind } ;
770785
@@ -789,7 +804,7 @@ impl UnusedParens {
789804 } else {
790805 None
791806 } ;
792- self . emit_unused_delims ( cx, value. span , spans, "pattern" , ( false , false ) ) ;
807+ self . emit_unused_delims ( cx, value. span , spans, "pattern" , keep_space ) ;
793808 }
794809 }
795810}
@@ -798,7 +813,7 @@ impl EarlyLintPass for UnusedParens {
798813 fn check_expr ( & mut self , cx : & EarlyContext < ' _ > , e : & ast:: Expr ) {
799814 match e. kind {
800815 ExprKind :: Let ( ref pat, _, _) | ExprKind :: ForLoop ( ref pat, ..) => {
801- self . check_unused_parens_pat ( cx, pat, false , false ) ;
816+ self . check_unused_parens_pat ( cx, pat, false , false , ( true , true ) ) ;
802817 }
803818 // We ignore parens in cases like `if (((let Some(0) = Some(1))))` because we already
804819 // handle a hard error for them during AST lowering in `lower_expr_mut`, but we still
@@ -842,40 +857,41 @@ impl EarlyLintPass for UnusedParens {
842857
843858 fn check_pat ( & mut self , cx : & EarlyContext < ' _ > , p : & ast:: Pat ) {
844859 use ast:: { Mutability , PatKind :: * } ;
860+ let keep_space = ( false , false ) ;
845861 match & p. kind {
846862 // Do not lint on `(..)` as that will result in the other arms being useless.
847863 Paren ( _)
848864 // The other cases do not contain sub-patterns.
849865 | Wild | Rest | Lit ( ..) | MacCall ( ..) | Range ( ..) | Ident ( .., None ) | Path ( ..) => { } ,
850866 // These are list-like patterns; parens can always be removed.
851867 TupleStruct ( _, _, ps) | Tuple ( ps) | Slice ( ps) | Or ( ps) => for p in ps {
852- self . check_unused_parens_pat ( cx, p, false , false ) ;
868+ self . check_unused_parens_pat ( cx, p, false , false , keep_space ) ;
853869 } ,
854870 Struct ( _, _, fps, _) => for f in fps {
855- self . check_unused_parens_pat ( cx, & f. pat , false , false ) ;
871+ self . check_unused_parens_pat ( cx, & f. pat , false , false , keep_space ) ;
856872 } ,
857873 // Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106.
858- Ident ( .., Some ( p) ) | Box ( p) => self . check_unused_parens_pat ( cx, p, true , false ) ,
874+ Ident ( .., Some ( p) ) | Box ( p) => self . check_unused_parens_pat ( cx, p, true , false , keep_space ) ,
859875 // Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342.
860876 // Also avoid linting on `& mut? (p0 | .. | pn)`, #64106.
861- Ref ( p, m) => self . check_unused_parens_pat ( cx, p, true , * m == Mutability :: Not ) ,
877+ Ref ( p, m) => self . check_unused_parens_pat ( cx, p, true , * m == Mutability :: Not , keep_space ) ,
862878 }
863879 }
864880
865881 fn check_stmt ( & mut self , cx : & EarlyContext < ' _ > , s : & ast:: Stmt ) {
866882 if let StmtKind :: Local ( ref local) = s. kind {
867- self . check_unused_parens_pat ( cx, & local. pat , true , false ) ;
883+ self . check_unused_parens_pat ( cx, & local. pat , true , false , ( false , false ) ) ;
868884 }
869885
870886 <Self as UnusedDelimLint >:: check_stmt ( self , cx, s)
871887 }
872888
873889 fn check_param ( & mut self , cx : & EarlyContext < ' _ > , param : & ast:: Param ) {
874- self . check_unused_parens_pat ( cx, & param. pat , true , false ) ;
890+ self . check_unused_parens_pat ( cx, & param. pat , true , false , ( false , false ) ) ;
875891 }
876892
877893 fn check_arm ( & mut self , cx : & EarlyContext < ' _ > , arm : & ast:: Arm ) {
878- self . check_unused_parens_pat ( cx, & arm. pat , false , false ) ;
894+ self . check_unused_parens_pat ( cx, & arm. pat , false , false , ( false , false ) ) ;
879895 }
880896
881897 fn check_ty ( & mut self , cx : & EarlyContext < ' _ > , ty : & ast:: Ty ) {
0 commit comments