]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_lint/src/unused.rs
Rollup merge of #104193 - TaKO8Ki:fix-104142, r=cjgillot
[rust.git] / compiler / rustc_lint / src / unused.rs
index 045d76cac62b8701af2e2b65aa7bcd2daf6d4353..ff0fb9bae923229ba85cd50d758aafe5eddbab02 100644 (file)
@@ -581,10 +581,24 @@ fn emit_unused_delims(
             lint.set_arg("delim", Self::DELIM_STR);
             lint.set_arg("item", msg);
             if let Some((lo, hi)) = spans {
-                let replacement = vec![
-                    (lo, if keep_space.0 { " ".into() } else { "".into() }),
-                    (hi, if keep_space.1 { " ".into() } else { "".into() }),
-                ];
+                let sm = cx.sess().source_map();
+                let lo_replace =
+                    if keep_space.0 &&
+                        let Ok(snip) = sm.span_to_prev_source(lo) && !snip.ends_with(" ") {
+                        " ".to_string()
+                        } else {
+                            "".to_string()
+                        };
+
+                let hi_replace =
+                    if keep_space.1 &&
+                        let Ok(snip) = sm.span_to_next_source(hi) && !snip.starts_with(" ") {
+                        " ".to_string()
+                        } else {
+                            "".to_string()
+                        };
+
+                let replacement = vec![(lo, lo_replace), (hi, hi_replace)];
                 lint.multipart_suggestion(
                     fluent::suggestion,
                     replacement,
@@ -781,6 +795,7 @@ fn check_unused_parens_pat(
         value: &ast::Pat,
         avoid_or: bool,
         avoid_mut: bool,
+        keep_space: (bool, bool),
     ) {
         use ast::{BindingAnnotation, PatKind};
 
@@ -805,7 +820,7 @@ fn check_unused_parens_pat(
             } else {
                 None
             };
-            self.emit_unused_delims(cx, value.span, spans, "pattern", (false, false));
+            self.emit_unused_delims(cx, value.span, spans, "pattern", keep_space);
         }
     }
 }
@@ -814,7 +829,7 @@ impl EarlyLintPass for UnusedParens {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
         match e.kind {
             ExprKind::Let(ref pat, _, _) | ExprKind::ForLoop(ref pat, ..) => {
-                self.check_unused_parens_pat(cx, pat, false, false);
+                self.check_unused_parens_pat(cx, pat, false, false, (true, true));
             }
             // We ignore parens in cases like `if (((let Some(0) = Some(1))))` because we already
             // handle a hard error for them during AST lowering in `lower_expr_mut`, but we still
@@ -858,6 +873,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
 
     fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
         use ast::{Mutability, PatKind::*};
+        let keep_space = (false, false);
         match &p.kind {
             // Do not lint on `(..)` as that will result in the other arms being useless.
             Paren(_)
@@ -865,33 +881,33 @@ fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
             | Wild | Rest | Lit(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) => {},
             // These are list-like patterns; parens can always be removed.
             TupleStruct(_, _, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
-                self.check_unused_parens_pat(cx, p, false, false);
+                self.check_unused_parens_pat(cx, p, false, false, keep_space);
             },
             Struct(_, _, fps, _) => for f in fps {
-                self.check_unused_parens_pat(cx, &f.pat, false, false);
+                self.check_unused_parens_pat(cx, &f.pat, false, false, keep_space);
             },
             // Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106.
-            Ident(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false),
+            Ident(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false, keep_space),
             // Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342.
             // Also avoid linting on `& mut? (p0 | .. | pn)`, #64106.
-            Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not),
+            Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not, keep_space),
         }
     }
 
     fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
         if let StmtKind::Local(ref local) = s.kind {
-            self.check_unused_parens_pat(cx, &local.pat, true, false);
+            self.check_unused_parens_pat(cx, &local.pat, true, false, (false, false));
         }
 
         <Self as UnusedDelimLint>::check_stmt(self, cx, s)
     }
 
     fn check_param(&mut self, cx: &EarlyContext<'_>, param: &ast::Param) {
-        self.check_unused_parens_pat(cx, &param.pat, true, false);
+        self.check_unused_parens_pat(cx, &param.pat, true, false, (false, false));
     }
 
     fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) {
-        self.check_unused_parens_pat(cx, &arm.pat, false, false);
+        self.check_unused_parens_pat(cx, &arm.pat, false, false, (false, false));
     }
 
     fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) {