summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/tests/ui/manual_let_else.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/clippy/tests/ui/manual_let_else.rs')
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else.rs113
1 files changed, 103 insertions, 10 deletions
diff --git a/src/tools/clippy/tests/ui/manual_let_else.rs b/src/tools/clippy/tests/ui/manual_let_else.rs
index 27717ab3a..5d94660ec 100644
--- a/src/tools/clippy/tests/ui/manual_let_else.rs
+++ b/src/tools/clippy/tests/ui/manual_let_else.rs
@@ -5,7 +5,9 @@
clippy::let_unit_value,
clippy::match_single_binding,
clippy::never_loop,
- clippy::needless_if
+ clippy::needless_if,
+ clippy::diverging_sub_expression,
+ clippy::single_match
)]
#![warn(clippy::manual_let_else)]
//@no-rustfix
@@ -24,7 +26,7 @@ fn main() {}
fn fire() {
let v = if let Some(v_some) = g() { v_some } else { return };
//~^ ERROR: this could be rewritten as `let...else`
- //~| NOTE: `-D clippy::manual-let-else` implied by `-D warnings`
+
let v = if let Some(v_some) = g() {
//~^ ERROR: this could be rewritten as `let...else`
v_some
@@ -79,22 +81,76 @@ fn fire() {
panic!();
};
+ // The final expression will need to be turned into a statement.
+ let v = if let Some(v_some) = g() {
+ //~^ ERROR: this could be rewritten as `let...else`
+ v_some
+ } else {
+ panic!();
+ ()
+ };
+
+ // Even if the result is buried multiple expressions deep.
+ let v = if let Some(v_some) = g() {
+ //~^ ERROR: this could be rewritten as `let...else`
+ v_some
+ } else {
+ panic!();
+ if true {
+ match 0 {
+ 0 => (),
+ _ => (),
+ }
+ } else {
+ panic!()
+ }
+ };
+
+ // Or if a break gives the value.
+ let v = if let Some(v_some) = g() {
+ //~^ ERROR: this could be rewritten as `let...else`
+ v_some
+ } else {
+ loop {
+ panic!();
+ break ();
+ }
+ };
+
+ // Even if the break is in a weird position.
+ let v = if let Some(v_some) = g() {
+ //~^ ERROR: this could be rewritten as `let...else`
+ v_some
+ } else {
+ 'a: loop {
+ panic!();
+ loop {
+ match 0 {
+ 0 if (return break 'a ()) => {},
+ _ => {},
+ }
+ }
+ }
+ };
+
// A match diverges if all branches diverge:
- // Note: the corresponding let-else requires a ; at the end of the match
- // as otherwise the type checker does not turn it into a ! type.
let v = if let Some(v_some) = g() {
//~^ ERROR: this could be rewritten as `let...else`
v_some
} else {
- match () {
- _ if panic!() => {},
+ match 0 {
+ 0 if true => panic!(),
_ => panic!(),
- }
+ };
};
// An if's expression can cause divergence:
- let v = if let Some(v_some) = g() { v_some } else { if panic!() {} };
- //~^ ERROR: this could be rewritten as `let...else`
+ let v = if let Some(v_some) = g() {
+ //~^ ERROR: this could be rewritten as `let...else`
+ v_some
+ } else {
+ if panic!() {};
+ };
// An expression of a match can cause divergence:
let v = if let Some(v_some) = g() {
@@ -103,7 +159,7 @@ fn fire() {
} else {
match panic!() {
_ => {},
- }
+ };
};
// Top level else if
@@ -342,6 +398,43 @@ fn not_fire() {
} else {
return;
};
+
+ // A break that skips the divergent statement will cause the expression to be non-divergent.
+ let _x = if let Some(x) = Some(0) {
+ x
+ } else {
+ 'foo: loop {
+ break 'foo 0;
+ panic!();
+ }
+ };
+
+ // Even in inner loops.
+ let _x = if let Some(x) = Some(0) {
+ x
+ } else {
+ 'foo: {
+ loop {
+ break 'foo 0;
+ }
+ panic!();
+ }
+ };
+
+ // But a break that can't ever be reached still affects divergence checking.
+ let _x = if let Some(x) = g() {
+ x
+ } else {
+ 'foo: {
+ 'bar: loop {
+ loop {
+ break 'bar ();
+ }
+ break 'foo ();
+ }
+ panic!();
+ };
+ };
}
struct S<T> {