fix a bug that caused internal test fail

This commit is contained in:
J-ZhengLi 2022-03-08 18:15:11 +08:00
parent 6bfc1120cf
commit 750204e3e3
4 changed files with 49 additions and 27 deletions

View File

@ -80,26 +80,29 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>) {
} }
fn check_if_let(cx: &LateContext<'_>, if_let: &higher::IfLet<'_>) -> bool { fn check_if_let(cx: &LateContext<'_>, if_let: &higher::IfLet<'_>) -> bool {
if let Some(else_block) = if_let.if_else { if let Some(if_else) = if_let.if_else {
if !pat_same_as_expr(if_let.let_pat, peel_blocks_with_stmt(if_let.if_then)) { if !pat_same_as_expr(if_let.let_pat, peel_blocks_with_stmt(if_let.if_then)) {
return false; return false;
} }
let else_expr = peel_blocks_with_stmt(else_block);
// Recurrsively check for each `else if let` phrase, // Recurrsively check for each `else if let` phrase,
if let Some(ref nested_if_let) = higher::IfLet::hir(cx, else_expr) { if let Some(ref nested_if_let) = higher::IfLet::hir(cx, if_else) {
return check_if_let(cx, nested_if_let); return check_if_let(cx, nested_if_let);
} }
let ret = strip_return(else_expr);
let let_expr_ty = cx.typeck_results().expr_ty(if_let.let_expr); if matches!(if_else.kind, ExprKind::Block(..)) {
if is_type_diagnostic_item(cx, let_expr_ty, sym::Option) { let else_expr = peel_blocks_with_stmt(if_else);
if let ExprKind::Path(ref qpath) = ret.kind { let ret = strip_return(else_expr);
return is_lang_ctor(cx, qpath, OptionNone) || eq_expr_value(cx, if_let.let_expr, ret); let let_expr_ty = cx.typeck_results().expr_ty(if_let.let_expr);
if is_type_diagnostic_item(cx, let_expr_ty, sym::Option) {
if let ExprKind::Path(ref qpath) = ret.kind {
return is_lang_ctor(cx, qpath, OptionNone) || eq_expr_value(cx, if_let.let_expr, ret);
}
} else {
return eq_expr_value(cx, if_let.let_expr, ret);
} }
} else { return true;
return eq_expr_value(cx, if_let.let_expr, ret);
} }
return true;
} }
false false
} }

View File

@ -3,6 +3,7 @@
#![allow(clippy::manual_map)] #![allow(clippy::manual_map)]
#![allow(dead_code)] #![allow(dead_code)]
#[derive(Clone, Copy)]
enum Choice { enum Choice {
A, A,
B, B,
@ -60,8 +61,16 @@ fn if_let_result(x: Result<(), i32>) {
let _: Result<(), i32> = if let Err(e) = Ok(1) { Err(e) } else { x }; let _: Result<(), i32> = if let Err(e) = Ok(1) { Err(e) } else { x };
} }
fn custom_enum_a(x: Choice) -> Choice { fn if_let_custom_enum(x: Choice) {
x let _: Choice = x;
// Don't trigger
let _: Choice = if let Choice::A = x {
Choice::A
} else if true {
Choice::B
} else {
x
};
} }
fn main() {} fn main() {}

View File

@ -3,6 +3,7 @@
#![allow(clippy::manual_map)] #![allow(clippy::manual_map)]
#![allow(dead_code)] #![allow(dead_code)]
#[derive(Clone, Copy)]
enum Choice { enum Choice {
A, A,
B, B,
@ -79,8 +80,8 @@ fn if_let_result(x: Result<(), i32>) {
let _: Result<(), i32> = if let Err(e) = Ok(1) { Err(e) } else { x }; let _: Result<(), i32> = if let Err(e) = Ok(1) { Err(e) } else { x };
} }
fn custom_enum_a(x: Choice) -> Choice { fn if_let_custom_enum(x: Choice) {
if let Choice::A = x { let _: Choice = if let Choice::A = x {
Choice::A Choice::A
} else if let Choice::B = x { } else if let Choice::B = x {
Choice::B Choice::B
@ -88,7 +89,15 @@ fn custom_enum_a(x: Choice) -> Choice {
Choice::C Choice::C
} else { } else {
x x
} };
// Don't trigger
let _: Choice = if let Choice::A = x {
Choice::A
} else if true {
Choice::B
} else {
x
};
} }
fn main() {} fn main() {}

View File

@ -1,5 +1,5 @@
error: this match expression is unnecessary error: this match expression is unnecessary
--> $DIR/nop_match.rs:14:18 --> $DIR/nop_match.rs:15:18
| |
LL | let _: i32 = match x { LL | let _: i32 = match x {
| __________________^ | __________________^
@ -13,7 +13,7 @@ LL | | };
= note: `-D clippy::nop-match` implied by `-D warnings` = note: `-D clippy::nop-match` implied by `-D warnings`
error: this match expression is unnecessary error: this match expression is unnecessary
--> $DIR/nop_match.rs:23:21 --> $DIR/nop_match.rs:24:21
| |
LL | let _: Choice = match se { LL | let _: Choice = match se {
| _____________________^ | _____________________^
@ -25,7 +25,7 @@ LL | | };
| |_____^ help: replace it with: `se` | |_____^ help: replace it with: `se`
error: this match expression is unnecessary error: this match expression is unnecessary
--> $DIR/nop_match.rs:45:26 --> $DIR/nop_match.rs:46:26
| |
LL | let _: Option<i32> = match x { LL | let _: Option<i32> = match x {
| __________________________^ | __________________________^
@ -35,7 +35,7 @@ LL | | };
| |_____^ help: replace it with: `x` | |_____^ help: replace it with: `x`
error: this match expression is unnecessary error: this match expression is unnecessary
--> $DIR/nop_match.rs:61:31 --> $DIR/nop_match.rs:62:31
| |
LL | let _: Result<i32, i32> = match Ok(1) { LL | let _: Result<i32, i32> = match Ok(1) {
| _______________________________^ | _______________________________^
@ -45,7 +45,7 @@ LL | | };
| |_____^ help: replace it with: `Ok(1)` | |_____^ help: replace it with: `Ok(1)`
error: this match expression is unnecessary error: this match expression is unnecessary
--> $DIR/nop_match.rs:65:31 --> $DIR/nop_match.rs:66:31
| |
LL | let _: Result<i32, i32> = match func_ret_err(0_i32) { LL | let _: Result<i32, i32> = match func_ret_err(0_i32) {
| _______________________________^ | _______________________________^
@ -55,33 +55,34 @@ LL | | };
| |_____^ help: replace it with: `func_ret_err(0_i32)` | |_____^ help: replace it with: `func_ret_err(0_i32)`
error: this if-let expression is unnecessary error: this if-let expression is unnecessary
--> $DIR/nop_match.rs:72:5 --> $DIR/nop_match.rs:73:5
| |
LL | if let Some(a) = Some(1) { Some(a) } else { None } LL | if let Some(a) = Some(1) { Some(a) } else { None }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(1)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(1)`
error: this if-let expression is unnecessary error: this if-let expression is unnecessary
--> $DIR/nop_match.rs:76:30 --> $DIR/nop_match.rs:77:30
| |
LL | let _: Result<(), i32> = if let Err(e) = x { Err(e) } else { x }; LL | let _: Result<(), i32> = if let Err(e) = x { Err(e) } else { x };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
error: this if-let expression is unnecessary error: this if-let expression is unnecessary
--> $DIR/nop_match.rs:77:30 --> $DIR/nop_match.rs:78:30
| |
LL | let _: Result<(), i32> = if let Ok(val) = x { Ok(val) } else { x }; LL | let _: Result<(), i32> = if let Ok(val) = x { Ok(val) } else { x };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
error: this if-let expression is unnecessary error: this if-let expression is unnecessary
--> $DIR/nop_match.rs:83:5 --> $DIR/nop_match.rs:84:21
| |
LL | / if let Choice::A = x { LL | let _: Choice = if let Choice::A = x {
| _____________________^
LL | | Choice::A LL | | Choice::A
LL | | } else if let Choice::B = x { LL | | } else if let Choice::B = x {
LL | | Choice::B LL | | Choice::B
... | ... |
LL | | x LL | | x
LL | | } LL | | };
| |_____^ help: replace it with: `x` | |_____^ help: replace it with: `x`
error: aborting due to 9 previous errors error: aborting due to 9 previous errors