]> git.lizzy.rs Git - rust.git/commitdiff
remove false positives of unused_braces
authorBastian Kauschke <bastian_kauschke@hotmail.de>
Sat, 4 Apr 2020 20:40:31 +0000 (22:40 +0200)
committerBastian Kauschke <bastian_kauschke@hotmail.de>
Tue, 7 Apr 2020 15:54:50 +0000 (17:54 +0200)
src/librustc_lint/unused.rs
src/test/ui/lint/unused_braces.rs
src/test/ui/lint/unused_braces.stderr
src/test/ui/lint/unused_braces_borrow.rs [new file with mode: 0644]
src/test/ui/lint/unused_braces_borrow.stderr [new file with mode: 0644]
src/test/ui/lint/unused_parens_borrow.rs [deleted file]
src/test/ui/lint/unused_parens_borrow.stderr [deleted file]

index c74b399555a8a874ff96bd74e75af1aeb1515019..aa7c87e9f7bd2a12c49fe59cbc158e32c6fc128f 100644 (file)
@@ -355,6 +355,19 @@ fn from(ctx: UnusedDelimsCtx) -> &'static str {
 trait UnusedDelimLint {
     const DELIM_STR: &'static str;
 
+    /// Due to `ref` pattern, there can be a difference between using
+    /// `{ expr }` and `expr` in pattern-matching contexts. This means
+    /// that we should only lint `unused_parens` and not `unused_braces`
+    /// in this case.
+    ///
+    /// ```rust
+    /// let mut a = 7;
+    /// let ref b = { a }; // We actually borrow a copy of `a` here.
+    /// a += 1; // By mutating `a` we invalidate any borrows of `a`.
+    /// assert_eq!(b + 1, a); // `b` does not borrow `a`, so we can still use it here.
+    /// ```
+    const LINT_EXPR_IN_PATTERN_MATCHING_CTX: bool;
+
     // this cannot be a constant is it refers to a static.
     fn lint(&self) -> &'static Lint;
 
@@ -454,7 +467,10 @@ fn emit_unused_delims(
     fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
         use rustc_ast::ast::ExprKind::*;
         let (value, ctx, followed_by_block, left_pos, right_pos) = match e.kind {
-            If(ref cond, ref block, ..) => {
+            // Do not lint `unused_braces` in `if let` expressions.
+            If(ref cond, ref block, ..)
+                if !matches!(cond.kind, Let(_, _)) || Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX =>
+            {
                 let left = e.span.lo() + rustc_span::BytePos(2);
                 let right = block.span.lo();
                 (cond, UnusedDelimsCtx::IfCond, true, Some(left), Some(right))
@@ -470,7 +486,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
                 (cond, UnusedDelimsCtx::ForIterExpr, true, None, Some(block.span.lo()))
             }
 
-            Match(ref head, _) => {
+            Match(ref head, _) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
                 let left = e.span.lo() + rustc_span::BytePos(5);
                 (head, UnusedDelimsCtx::MatchScrutineeExpr, true, Some(left), None)
             }
@@ -512,7 +528,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
 
     fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
         match s.kind {
-            StmtKind::Local(ref local) => {
+            StmtKind::Local(ref local) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
                 if let Some(ref value) = local.init {
                     self.check_unused_delims_expr(
                         cx,
@@ -565,6 +581,8 @@ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
 impl UnusedDelimLint for UnusedParens {
     const DELIM_STR: &'static str = "parentheses";
 
+    const LINT_EXPR_IN_PATTERN_MATCHING_CTX: bool = true;
+
     fn lint(&self) -> &'static Lint {
         UNUSED_PARENS
     }
@@ -736,6 +754,8 @@ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
 impl UnusedDelimLint for UnusedBraces {
     const DELIM_STR: &'static str = "braces";
 
+    const LINT_EXPR_IN_PATTERN_MATCHING_CTX: bool = false;
+
     fn lint(&self) -> &'static Lint {
         UNUSED_BRACES
     }
index de456ee6c230cac9a7d4c9872ba1dbde8974386d..952398ef0685bd8f0345eb2ac6aa4fe9e7e5b21b 100644 (file)
@@ -1,29 +1,48 @@
 // check-pass
 #![warn(unused_braces, unused_parens)]
 
+fn consume<T>(_: T) {}
+
 fn main() {
     let _ = (7);
     //~^WARN unnecessary parentheses
 
-    let _ = { 7 };
-    //~^ WARN unnecessary braces
+    // Do not emit a lint in these cases,
+    // as we have to be careful with
+    // `ref` patterns.
+    {
+        let _ = { 7 };
+
+        if let 7 = { 7 } { }
+
+        match { 7 } {
+            _ => (),
+        }
+    }
 
-    if let 7 = { 7 } {
+    if { true } {
+        //~^ WARN unnecessary braces
+    }
+
+    while { false } {
         //~^ WARN unnecessary braces
     }
 
     let _: [u8; { 3 }];
     //~^ WARN unnecessary braces
 
-    // do not emit error for multiline blocks.
+    consume({ 7 });
+    //~^ WARN unnecessary braces
+
+    // Do not emit lint for multiline blocks.
     let _ = {
         7
     };
 
-    // do not emit error for unsafe blocks.
+    // Do not emit lint for unsafe blocks.
     let _ = unsafe { 7 };
 
-    // do not emit error, as the `{` would then
+    // Do not emit lint, as the `{` would then
     // be parsed as part of the `return`.
     if { return } {
 
index 72f425ffc3e01147e88c6cc2b1c529545ded8de2..f195c00241836b375e09a4dc55166b9af42c36e7 100644 (file)
@@ -1,5 +1,5 @@
 warning: unnecessary parentheses around assigned value
-  --> $DIR/unused_braces.rs:5:13
+  --> $DIR/unused_braces.rs:7:13
    |
 LL |     let _ = (7);
    |             ^^^ help: remove these parentheses
@@ -10,11 +10,11 @@ note: the lint level is defined here
 LL | #![warn(unused_braces, unused_parens)]
    |                        ^^^^^^^^^^^^^
 
-warning: unnecessary braces around assigned value
-  --> $DIR/unused_braces.rs:8:13
+warning: unnecessary braces around `if` condition
+  --> $DIR/unused_braces.rs:23:8
    |
-LL |     let _ = { 7 };
-   |             ^^^^^ help: remove these braces
+LL |     if { true } {
+   |        ^^^^^^^^ help: remove these braces
    |
 note: the lint level is defined here
   --> $DIR/unused_braces.rs:2:9
@@ -22,15 +22,21 @@ note: the lint level is defined here
 LL | #![warn(unused_braces, unused_parens)]
    |         ^^^^^^^^^^^^^
 
-warning: unnecessary braces around `let` scrutinee expression
-  --> $DIR/unused_braces.rs:11:16
+warning: unnecessary braces around `while` condition
+  --> $DIR/unused_braces.rs:27:11
    |
-LL |     if let 7 = { 7 } {
-   |                ^^^^^ help: remove these braces
+LL |     while { false } {
+   |           ^^^^^^^^^ help: remove these braces
 
 warning: unnecessary braces around const expression
-  --> $DIR/unused_braces.rs:15:17
+  --> $DIR/unused_braces.rs:31:17
    |
 LL |     let _: [u8; { 3 }];
    |                 ^^^^^ help: remove these braces
 
+warning: unnecessary braces around function argument
+  --> $DIR/unused_braces.rs:34:13
+   |
+LL |     consume({ 7 });
+   |             ^^^^^ help: remove these braces
+
diff --git a/src/test/ui/lint/unused_braces_borrow.rs b/src/test/ui/lint/unused_braces_borrow.rs
new file mode 100644 (file)
index 0000000..d0b0597
--- /dev/null
@@ -0,0 +1,24 @@
+// check-pass
+#![warn(unused_braces)]
+
+// changing `&{ expr }` to `&expr` changes the semantic of the program
+// so we should not warn this case
+
+#[repr(packed)]
+struct A {
+    a: u8,
+    b: u32,
+}
+
+fn consume<T>(_: T) {}
+
+fn main() {
+    let a = A {
+        a: 42,
+        b: 1729,
+    };
+
+    consume(&{ a.b });
+    consume({ a.b });
+    //~^ WARN unnecessary braces
+}
diff --git a/src/test/ui/lint/unused_braces_borrow.stderr b/src/test/ui/lint/unused_braces_borrow.stderr
new file mode 100644 (file)
index 0000000..82fb437
--- /dev/null
@@ -0,0 +1,12 @@
+warning: unnecessary braces around function argument
+  --> $DIR/unused_braces_borrow.rs:22:13
+   |
+LL |     consume({ a.b });
+   |             ^^^^^^^ help: remove these braces
+   |
+note: the lint level is defined here
+  --> $DIR/unused_braces_borrow.rs:2:9
+   |
+LL | #![warn(unused_braces)]
+   |         ^^^^^^^^^^^^^
+
diff --git a/src/test/ui/lint/unused_parens_borrow.rs b/src/test/ui/lint/unused_parens_borrow.rs
deleted file mode 100644 (file)
index 98dbbec..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// check-pass
-#![warn(unused_braces)]
-
-// changing `&{ expr }` to `&expr` changes the semantic of the program
-// so we should not warn this case
-
-#[repr(packed)]
-struct A {
-    a: u8,
-    b: u32,
-}
-
-fn main() {
-    let a = A {
-        a: 42,
-        b: 1729,
-    };
-
-    let _ = &{ a.b };
-    let _ = { a.b };
-    //~^ WARN unnecessary braces
-}
diff --git a/src/test/ui/lint/unused_parens_borrow.stderr b/src/test/ui/lint/unused_parens_borrow.stderr
deleted file mode 100644 (file)
index 7e3839a..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-warning: unnecessary braces around assigned value
-  --> $DIR/unused_parens_borrow.rs:20:13
-   |
-LL |     let _ = { a.b };
-   |             ^^^^^^^ help: remove these braces
-   |
-note: the lint level is defined here
-  --> $DIR/unused_parens_borrow.rs:2:9
-   |
-LL | #![warn(unused_braces)]
-   |         ^^^^^^^^^^^^^
-