]> git.lizzy.rs Git - rust.git/commitdiff
match_like_matches_macro: strip refs in suggestion
authorMatthias Krüger <matthias.krueger@famsik.de>
Fri, 1 Jan 2021 16:43:24 +0000 (17:43 +0100)
committerMatthias Krüger <matthias.krueger@famsik.de>
Sun, 3 Jan 2021 19:28:46 +0000 (20:28 +0100)
fixes #6503

changelog: match_like_matches_macro: strip refs in suggestion (#6503)

clippy_lints/src/matches.rs
tests/ui/match_expr_like_matches_macro.fixed
tests/ui/match_expr_like_matches_macro.rs
tests/ui/match_expr_like_matches_macro.stderr

index 04b35835c6b8eeed5325e41c2e01763c2d9ba99b..6372cb86616ec07c12cfb615f24df935b070fc0d 100644 (file)
@@ -1185,6 +1185,14 @@ fn find_matches_sugg(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr
             } else {
                 pat
             };
+
+            // strip potential borrows (#6503), but only if the type is a reference
+            let mut ex_new = ex;
+            if let ExprKind::AddrOf(BorrowKind::Ref, .., ex_inner) = ex.kind {
+                if let ty::Ref(..) = cx.typeck_results().expr_ty(&ex_inner).kind() {
+                    ex_new = ex_inner;
+                }
+            };
             span_lint_and_sugg(
                 cx,
                 MATCH_LIKE_MATCHES_MACRO,
@@ -1194,7 +1202,7 @@ fn find_matches_sugg(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr
                 format!(
                     "{}matches!({}, {})",
                     if b0 { "" } else { "!" },
-                    snippet_with_applicability(cx, ex.span, "..", &mut applicability),
+                    snippet_with_applicability(cx, ex_new.span, "..", &mut applicability),
                     pat_and_guard,
                 ),
                 applicability,
index 84981a52597327992a772f61ceff6ea23dcd59be..319299862a7003462cbaffe429edb6235c28f482 100644 (file)
@@ -99,4 +99,51 @@ fn main() {
             _ => false,
         };
     }
+
+    {
+        // should print "z" in suggestion (#6503)
+        let z = &Some(3);
+        let _z = matches!(z, Some(3));
+    }
+
+    {
+        // this could also print "z" in suggestion..?
+        let z = Some(3);
+        let _z = matches!(&z, Some(3));
+    }
+
+    {
+        enum AnEnum {
+            X,
+            Y,
+        }
+
+        fn foo(_x: AnEnum) {}
+
+        fn main() {
+            let z = AnEnum::X;
+            // we can't remove the reference here!
+            let _ = matches!(&z, AnEnum::X);
+            foo(z);
+        }
+    }
+
+    {
+        struct S(i32);
+
+        fn fun(_val: Option<S>) {}
+        let val = Some(S(42));
+        // we need the reference here because later val is consumed by fun()
+        let _res = matches!(&val, &Some(ref _a));
+        fun(val);
+    }
+
+    {
+        struct S(i32);
+
+        fn fun(_val: Option<S>) {}
+        let val = Some(S(42));
+        let _res = matches!(&val, &Some(ref _a));
+        fun(val);
+    }
 }
index 94c7c3cadacf749799ba4a32510e28466e560001..2ef6cf42387f6e5b5cd71d788fbabe4f8f7ac01d 100644 (file)
@@ -119,4 +119,66 @@ enum E {
             _ => false,
         };
     }
+
+    {
+        // should print "z" in suggestion (#6503)
+        let z = &Some(3);
+        let _z = match &z {
+            Some(3) => true,
+            _ => false,
+        };
+    }
+
+    {
+        // this could also print "z" in suggestion..?
+        let z = Some(3);
+        let _z = match &z {
+            Some(3) => true,
+            _ => false,
+        };
+    }
+
+    {
+        enum AnEnum {
+            X,
+            Y,
+        }
+
+        fn foo(_x: AnEnum) {}
+
+        fn main() {
+            let z = AnEnum::X;
+            // we can't remove the reference here!
+            let _ = match &z {
+                AnEnum::X => true,
+                _ => false,
+            };
+            foo(z);
+        }
+    }
+
+    {
+        struct S(i32);
+
+        fn fun(_val: Option<S>) {}
+        let val = Some(S(42));
+        // we need the reference here because later val is consumed by fun()
+        let _res = match &val {
+            &Some(ref _a) => true,
+            _ => false,
+        };
+        fun(val);
+    }
+
+    {
+        struct S(i32);
+
+        fn fun(_val: Option<S>) {}
+        let val = Some(S(42));
+        let _res = match &val {
+            &Some(ref _a) => true,
+            _ => false,
+        };
+        fun(val);
+    }
 }
index c52e41c788944e5757c3f26c2f97d500f3dbf92a..f27b4e9cb20b11786aec24c4066c147e3a51350c 100644 (file)
@@ -70,5 +70,88 @@ LL | |             _ => true,
 LL | |         };
    | |_________^ help: try this: `!matches!(x, E::B(_) | E::C)`
 
-error: aborting due to 7 previous errors
+error: match expression looks like `matches!` macro
+  --> $DIR/match_expr_like_matches_macro.rs:126:18
+   |
+LL |           let _z = match &z {
+   |  __________________^
+LL | |             Some(3) => true,
+LL | |             _ => false,
+LL | |         };
+   | |_________^ help: try this: `matches!(z, Some(3))`
+
+error: match expression looks like `matches!` macro
+  --> $DIR/match_expr_like_matches_macro.rs:135:18
+   |
+LL |           let _z = match &z {
+   |  __________________^
+LL | |             Some(3) => true,
+LL | |             _ => false,
+LL | |         };
+   | |_________^ help: try this: `matches!(&z, Some(3))`
+
+error: match expression looks like `matches!` macro
+  --> $DIR/match_expr_like_matches_macro.rs:152:21
+   |
+LL |               let _ = match &z {
+   |  _____________________^
+LL | |                 AnEnum::X => true,
+LL | |                 _ => false,
+LL | |             };
+   | |_____________^ help: try this: `matches!(&z, AnEnum::X)`
+
+error: match expression looks like `matches!` macro
+  --> $DIR/match_expr_like_matches_macro.rs:166:20
+   |
+LL |           let _res = match &val {
+   |  ____________________^
+LL | |             &Some(ref _a) => true,
+LL | |             _ => false,
+LL | |         };
+   | |_________^ help: try this: `matches!(&val, &Some(ref _a))`
+
+error: you don't need to add `&` to both the expression and the patterns
+  --> $DIR/match_expr_like_matches_macro.rs:166:20
+   |
+LL |           let _res = match &val {
+   |  ____________________^
+LL | |             &Some(ref _a) => true,
+LL | |             _ => false,
+LL | |         };
+   | |_________^
+   |
+   = note: `-D clippy::match-ref-pats` implied by `-D warnings`
+help: try
+   |
+LL |         let _res = match val {
+LL |             Some(ref _a) => true,
+   |
+
+error: match expression looks like `matches!` macro
+  --> $DIR/match_expr_like_matches_macro.rs:178:20
+   |
+LL |           let _res = match &val {
+   |  ____________________^
+LL | |             &Some(ref _a) => true,
+LL | |             _ => false,
+LL | |         };
+   | |_________^ help: try this: `matches!(&val, &Some(ref _a))`
+
+error: you don't need to add `&` to both the expression and the patterns
+  --> $DIR/match_expr_like_matches_macro.rs:178:20
+   |
+LL |           let _res = match &val {
+   |  ____________________^
+LL | |             &Some(ref _a) => true,
+LL | |             _ => false,
+LL | |         };
+   | |_________^
+   |
+help: try
+   |
+LL |         let _res = match val {
+LL |             Some(ref _a) => true,
+   |
+
+error: aborting due to 14 previous errors