manual_let_else: do not suggest semantically different replacements
This commit is contained in:
parent
d880cae0b5
commit
09d3097734
@ -115,6 +115,13 @@ fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &'tcx Stmt<'tcx>) {
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(_, arm)| expr_diverges(cx, arm.body) && pat_allowed_for_else(cx, arm.pat, check_types));
|
.find(|(_, arm)| expr_diverges(cx, arm.body) && pat_allowed_for_else(cx, arm.pat, check_types));
|
||||||
let Some((idx, diverging_arm)) = diverging_arm_opt else { return; };
|
let Some((idx, diverging_arm)) = diverging_arm_opt else { return; };
|
||||||
|
// If the non-diverging arm is the first one, its pattern can be reused in a let/else statement.
|
||||||
|
// However, if it arrives in second position, its pattern may cover some cases already covered
|
||||||
|
// by the diverging one.
|
||||||
|
// TODO: accept the non-diverging arm as a second position if patterns are disjointed.
|
||||||
|
if idx == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let pat_arm = &arms[1 - idx];
|
let pat_arm = &arms[1 - idx];
|
||||||
if !expr_is_simple_identity(pat_arm.pat, pat_arm.body) {
|
if !expr_is_simple_identity(pat_arm.pat, pat_arm.body) {
|
||||||
return;
|
return;
|
||||||
|
@ -42,13 +42,13 @@ fn fire() {
|
|||||||
loop {
|
loop {
|
||||||
// More complex pattern for the identity arm and diverging arm
|
// More complex pattern for the identity arm and diverging arm
|
||||||
let v = match h() {
|
let v = match h() {
|
||||||
(Some(_), Some(_)) | (None, None) => continue,
|
|
||||||
(Some(v), None) | (None, Some(v)) => v,
|
(Some(v), None) | (None, Some(v)) => v,
|
||||||
|
(Some(_), Some(_)) | (None, None) => continue,
|
||||||
};
|
};
|
||||||
// Custom enums are supported as long as the "else" arm is a simple _
|
// Custom enums are supported as long as the "else" arm is a simple _
|
||||||
let v = match build_enum() {
|
let v = match build_enum() {
|
||||||
_ => continue,
|
|
||||||
Variant::Bar(v) | Variant::Baz(v) => v,
|
Variant::Bar(v) | Variant::Baz(v) => v,
|
||||||
|
_ => continue,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,6 +71,12 @@ fn fire() {
|
|||||||
Variant::Bar(_) | Variant::Baz(_) => (),
|
Variant::Bar(_) | Variant::Baz(_) => (),
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let data = [1_u8, 2, 3, 4, 0, 0, 0, 0];
|
||||||
|
let data = match data.as_slice() {
|
||||||
|
[data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0] => data,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn not_fire() {
|
fn not_fire() {
|
||||||
@ -125,4 +131,23 @@ fn not_fire() {
|
|||||||
Ok(v) | Err(Variant::Bar(v) | Variant::Baz(v)) => v,
|
Ok(v) | Err(Variant::Bar(v) | Variant::Baz(v)) => v,
|
||||||
Err(Variant::Foo) => return,
|
Err(Variant::Foo) => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Issue 10241
|
||||||
|
// The non-divergent arm arrives in second position and
|
||||||
|
// may cover values already matched in the first arm.
|
||||||
|
let v = match h() {
|
||||||
|
(Some(_), Some(_)) | (None, None) => return,
|
||||||
|
(Some(v), _) | (None, Some(v)) => v,
|
||||||
|
};
|
||||||
|
|
||||||
|
let v = match build_enum() {
|
||||||
|
_ => return,
|
||||||
|
Variant::Bar(v) | Variant::Baz(v) => v,
|
||||||
|
};
|
||||||
|
|
||||||
|
let data = [1_u8, 2, 3, 4, 0, 0, 0, 0];
|
||||||
|
let data = match data.as_slice() {
|
||||||
|
[] | [0, 0] => return,
|
||||||
|
[data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ ..] => data,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,8 @@ error: this could be rewritten as `let...else`
|
|||||||
--> $DIR/manual_let_else_match.rs:44:9
|
--> $DIR/manual_let_else_match.rs:44:9
|
||||||
|
|
|
|
||||||
LL | / let v = match h() {
|
LL | / let v = match h() {
|
||||||
LL | | (Some(_), Some(_)) | (None, None) => continue,
|
|
||||||
LL | | (Some(v), None) | (None, Some(v)) => v,
|
LL | | (Some(v), None) | (None, Some(v)) => v,
|
||||||
|
LL | | (Some(_), Some(_)) | (None, None) => continue,
|
||||||
LL | | };
|
LL | | };
|
||||||
| |__________^ help: consider writing: `let ((Some(v), None) | (None, Some(v))) = h() else { continue };`
|
| |__________^ help: consider writing: `let ((Some(v), None) | (None, Some(v))) = h() else { continue };`
|
||||||
|
|
||||||
@ -31,8 +31,8 @@ error: this could be rewritten as `let...else`
|
|||||||
--> $DIR/manual_let_else_match.rs:49:9
|
--> $DIR/manual_let_else_match.rs:49:9
|
||||||
|
|
|
|
||||||
LL | / let v = match build_enum() {
|
LL | / let v = match build_enum() {
|
||||||
LL | | _ => continue,
|
|
||||||
LL | | Variant::Bar(v) | Variant::Baz(v) => v,
|
LL | | Variant::Bar(v) | Variant::Baz(v) => v,
|
||||||
|
LL | | _ => continue,
|
||||||
LL | | };
|
LL | | };
|
||||||
| |__________^ help: consider writing: `let (Variant::Bar(v) | Variant::Baz(v)) = build_enum() else { continue };`
|
| |__________^ help: consider writing: `let (Variant::Bar(v) | Variant::Baz(v)) = build_enum() else { continue };`
|
||||||
|
|
||||||
@ -63,5 +63,14 @@ LL | | _ => return,
|
|||||||
LL | | };
|
LL | | };
|
||||||
| |______^ help: consider writing: `let (Variant::Bar(_) | Variant::Baz(_)) = f else { return };`
|
| |______^ help: consider writing: `let (Variant::Bar(_) | Variant::Baz(_)) = f else { return };`
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: this could be rewritten as `let...else`
|
||||||
|
--> $DIR/manual_let_else_match.rs:76:5
|
||||||
|
|
|
||||||
|
LL | / let data = match data.as_slice() {
|
||||||
|
LL | | [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0] => data,
|
||||||
|
LL | | _ => return,
|
||||||
|
LL | | };
|
||||||
|
| |______^ help: consider writing: `let ([data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0]) = data.as_slice() else { return };`
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user