Add let-else tests

This commit is contained in:
Cameron Steffen 2021-08-01 19:18:50 -05:00
parent df9a2e0687
commit 5b95df4bdc
17 changed files with 322 additions and 0 deletions

View File

@ -0,0 +1,8 @@
// run-rustfix
#![feature(let_else)]
fn main() {
let true = (true && false) else { return }; //~ ERROR a `&&` expression cannot be directly assigned in `let...else`
let true = (true || false) else { return }; //~ ERROR a `||` expression cannot be directly assigned in `let...else`
}

View File

@ -0,0 +1,8 @@
// run-rustfix
#![feature(let_else)]
fn main() {
let true = true && false else { return }; //~ ERROR a `&&` expression cannot be directly assigned in `let...else`
let true = true || false else { return }; //~ ERROR a `||` expression cannot be directly assigned in `let...else`
}

View File

@ -0,0 +1,24 @@
error: a `&&` expression cannot be directly assigned in `let...else`
--> $DIR/let-else-bool-binop-init.rs:6:16
|
LL | let true = true && false else { return };
| ^^^^^^^^^^^^^
|
help: wrap the expression in parenthesis
|
LL | let true = (true && false) else { return };
| + +
error: a `||` expression cannot be directly assigned in `let...else`
--> $DIR/let-else-bool-binop-init.rs:7:16
|
LL | let true = true || false else { return };
| ^^^^^^^^^^^^^
|
help: wrap the expression in parenthesis
|
LL | let true = (true || false) else { return };
| + +
error: aborting due to 2 previous errors

View File

@ -0,0 +1,26 @@
// run-rustfix
#![feature(let_else)]
fn main() {
let Some(1) = ({ Some(1) }) else {
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
return;
};
let Some(1) = (loop { break Some(1) }) else {
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
return;
};
let 2 = 1 + (match 1 { n => n }) else {
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
return;
};
let Some(1) = (unsafe { unsafe_fn() }) else {
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
return;
};
}
unsafe fn unsafe_fn<T>() -> T {
unimplemented!();
}

View File

@ -0,0 +1,26 @@
// run-rustfix
#![feature(let_else)]
fn main() {
let Some(1) = { Some(1) } else {
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
return;
};
let Some(1) = loop { break Some(1) } else {
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
return;
};
let 2 = 1 + match 1 { n => n } else {
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
return;
};
let Some(1) = unsafe { unsafe_fn() } else {
//~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
return;
};
}
unsafe fn unsafe_fn<T>() -> T {
unimplemented!();
}

View File

@ -0,0 +1,46 @@
error: right curly brace `}` before `else` in a `let...else` statement not allowed
--> $DIR/let-else-brace-before-else.rs:6:29
|
LL | let Some(1) = { Some(1) } else {
| ^
|
help: try wrapping the expression in parenthesis
|
LL | let Some(1) = ({ Some(1) }) else {
| + +
error: right curly brace `}` before `else` in a `let...else` statement not allowed
--> $DIR/let-else-brace-before-else.rs:10:40
|
LL | let Some(1) = loop { break Some(1) } else {
| ^
|
help: try wrapping the expression in parenthesis
|
LL | let Some(1) = (loop { break Some(1) }) else {
| + +
error: right curly brace `}` before `else` in a `let...else` statement not allowed
--> $DIR/let-else-brace-before-else.rs:14:34
|
LL | let 2 = 1 + match 1 { n => n } else {
| ^
|
help: try wrapping the expression in parenthesis
|
LL | let 2 = 1 + (match 1 { n => n }) else {
| + +
error: right curly brace `}` before `else` in a `let...else` statement not allowed
--> $DIR/let-else-brace-before-else.rs:18:40
|
LL | let Some(1) = unsafe { unsafe_fn() } else {
| ^
|
help: try wrapping the expression in parenthesis
|
LL | let Some(1) = (unsafe { unsafe_fn() }) else {
| + +
error: aborting due to 4 previous errors

View File

@ -0,0 +1,14 @@
#![feature(let_else)]
#![deny(unused_variables)]
fn main() {
// type annotation, attributes
#[allow(unused_variables)]
let Some(_): Option<u32> = Some(Default::default()) else {
let x = 1; // OK
return;
};
let x = 1; //~ ERROR unused variable: `x`
}

View File

@ -0,0 +1,14 @@
error: unused variable: `x`
--> $DIR/let-else-check.rs:13:9
|
LL | let x = 1;
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
note: the lint level is defined here
--> $DIR/let-else-check.rs:3:9
|
LL | #![deny(unused_variables)]
| ^^^^^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -0,0 +1,7 @@
// check-pass
#![feature(let_else)]
fn main() {
let x = 1 else { return }; //~ WARN irrefutable `let...else` pattern
}

View File

@ -0,0 +1,12 @@
warning: irrefutable `let...else` pattern
--> $DIR/let-else-irrefutable.rs:6:5
|
LL | let x = 1 else { return };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(irrefutable_let_patterns)]` on by default
= note: this pattern will always match, so the `else` clause is useless
= help: consider removing the `else` clause
warning: 1 warning emitted

View File

@ -0,0 +1,11 @@
#![feature(let_else)]
fn main() {
let Some(x) = Some(1) else {
return;
} //~ ERROR expected `;`, found keyword `let`
let _ = "";
let Some(x) = Some(1) else {
panic!();
} //~ ERROR expected `;`, found `}`
}

View File

@ -0,0 +1,18 @@
error: expected `;`, found keyword `let`
--> $DIR/let-else-missing-semicolon.rs:6:6
|
LL | }
| ^ help: add `;` here
LL | let _ = "";
| --- unexpected token
error: expected `;`, found `}`
--> $DIR/let-else-missing-semicolon.rs:10:6
|
LL | }
| ^ help: add `;` here
LL | }
| - unexpected token
error: aborting due to 2 previous errors

View File

@ -0,0 +1,13 @@
#![feature(let_else)]
fn main() {
let Some(x) = Some(1) else { //~ ERROR does not diverge
Some(2)
};
let Some(x) = Some(1) else { //~ ERROR does not diverge
if 1 == 1 {
panic!();
}
};
let Some(x) = Some(1) else { Some(2) }; //~ ERROR does not diverge
}

View File

@ -0,0 +1,44 @@
error[E0308]: `else` clause of `let...else` does not diverge
--> $DIR/let-else-non-diverging.rs:12:32
|
LL | let Some(x) = Some(1) else { Some(2) };
| ^^^^^^^^^^^ expected `!`, found enum `Option`
|
= note: expected type `!`
found type `Option<{integer}>`
= help: try adding a diverging expression, such as `return` or `panic!(..)`
= help: ...or use `match` instead of `let...else`
error[E0308]: `else` clause of `let...else` does not diverge
--> $DIR/let-else-non-diverging.rs:7:32
|
LL | let Some(x) = Some(1) else {
| ________________________________^
LL | | if 1 == 1 {
LL | | panic!();
LL | | }
LL | | };
| |_____^ expected `!`, found `()`
|
= note: expected type `!`
found type `()`
= help: try adding a diverging expression, such as `return` or `panic!(..)`
= help: ...or use `match` instead of `let...else`
error[E0308]: `else` clause of `let...else` does not diverge
--> $DIR/let-else-non-diverging.rs:4:32
|
LL | let Some(x) = Some(1) else {
| ________________________________^
LL | | Some(2)
LL | | };
| |_____^ expected `!`, found enum `Option`
|
= note: expected type `!`
found type `Option<{integer}>`
= help: try adding a diverging expression, such as `return` or `panic!(..)`
= help: ...or use `match` instead of `let...else`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -0,0 +1,35 @@
// run-pass
#![feature(let_else)]
fn main() {
#[allow(dead_code)]
enum MyEnum {
A(String),
B { f: String },
C,
}
// ref binding to non-copy value and or-pattern
let (MyEnum::A(ref x) | MyEnum::B { f: ref x }) = (MyEnum::B { f: String::new() }) else {
panic!();
};
assert_eq!(x, "");
// nested let-else
let mut x = 1;
loop {
let 4 = x else {
let 3 = x else {
x += 1;
continue;
};
break;
};
panic!();
}
assert_eq!(x, 3);
// else return
let Some(1) = Some(2) else { return };
panic!();
}

View File

@ -0,0 +1,7 @@
#![feature(let_else)]
fn main() {
let Some(x) = Some(2) else {
panic!("{}", x); //~ ERROR cannot find value `x` in this scope
};
}

View File

@ -0,0 +1,9 @@
error[E0425]: cannot find value `x` in this scope
--> $DIR/let-else-scope.rs:5:22
|
LL | panic!("{}", x);
| ^ not found in this scope
error: aborting due to previous error
For more information about this error, try `rustc --explain E0425`.