Skip to content

Commit

Permalink
match_like_matches_macro: strip refs in suggestion
Browse files Browse the repository at this point in the history
fixes rust-lang#6503

changelog: match_like_matches_macro: strip refs in suggestion (rust-lang#6503)
  • Loading branch information
matthiaskrgr committed Jan 3, 2021
1 parent 592f7eb commit a34aca2
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 2 deletions.
10 changes: 9 additions & 1 deletion clippy_lints/src/matches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
40 changes: 40 additions & 0 deletions tests/ui/match_expr_like_matches_macro.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,44 @@ 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));

let _res = matches!(&val, &Some(ref _a));

fun(val);
}
}
52 changes: 52 additions & 0 deletions tests/ui/match_expr_like_matches_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,56 @@ fn main() {
_ => 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));

let _res = match &val {
&Some(ref _a) => true,
_ => false,
};

fun(val);
}
}
59 changes: 58 additions & 1 deletion tests/ui/match_expr_like_matches_macro.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,62 @@ 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:167: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:167: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: aborting due to 12 previous errors

0 comments on commit a34aca2

Please sign in to comment.