let-else: add match-ergonomics tests adapted from rfc2005 · rust-lang/rust@2715c5f (original) (raw)
12 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
1 | +// from rfc2005 test suite | |
2 | + | |
3 | +#![feature(let_else)] | |
4 | + | |
5 | +// Verify the binding mode shifts - only when no `&` are auto-dereferenced is the | |
6 | +// final default binding mode mutable. | |
7 | + | |
8 | +fn main() { | |
9 | +let Some(n): &mut Option<i32> = &&Some(5i32) else { return }; //~ ERROR mismatched types | |
10 | +*n += 1; | |
11 | +let _ = n; | |
12 | + | |
13 | +let Some(n): &mut Option<i32> = &&mut Some(5i32) else { return }; //~ ERROR mismatched types | |
14 | +*n += 1; | |
15 | +let _ = n; | |
16 | +} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
1 | +error[E0308]: mismatched types | |
2 | + --> $DIR/let-else-binding-explicit-mut-annotated.rs:9:37 | |
3 | + | | |
4 | +LL | let Some(n): &mut Option = &&Some(5i32) else { return }; | |
5 | + | ^^^^^^^^^^^^ types differ in mutability | |
6 | + | | |
7 | + = note: expected mutable reference `&mut Option` | |
8 | + found reference `&&Option` | |
9 | + | |
10 | +error[E0308]: mismatched types | |
11 | + --> $DIR/let-else-binding-explicit-mut-annotated.rs:13:37 | |
12 | + | | |
13 | +LL | let Some(n): &mut Option = &&mut Some(5i32) else { return }; | |
14 | + | ^^^^^^^^^^^^^^^^ types differ in mutability | |
15 | + | | |
16 | + = note: expected mutable reference `&mut Option` | |
17 | + found reference `&&mut Option` | |
18 | + | |
19 | +error: aborting due to 2 previous errors | |
20 | + | |
21 | +For more information about this error, try `rustc --explain E0308`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
1 | +#![feature(let_else)] | |
2 | + | |
3 | +// Slightly different from explicit-mut-annotated -- this won't show an error until borrowck. | |
4 | +// Should it show a type error instead? | |
5 | + | |
6 | +fn main() { | |
7 | +let Some(n): &mut Option<i32> = &mut &Some(5i32) else { | |
8 | +//~^ ERROR cannot borrow data in a `&` reference as mutable | |
9 | +return | |
10 | +}; | |
11 | +*n += 1; | |
12 | +let _ = n; | |
13 | +} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
1 | +error[E0596]: cannot borrow data in a `&` reference as mutable | |
2 | + --> $DIR/let-else-binding-explicit-mut-borrow.rs:7:37 | |
3 | + | | |
4 | +LL | let Some(n): &mut Option = &mut &Some(5i32) else { | |
5 | + | ^^^^^^^^^^^^^^^^ cannot borrow as mutable | |
6 | + | |
7 | +error: aborting due to previous error | |
8 | + | |
9 | +For more information about this error, try `rustc --explain E0596`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
1 | +// check-pass | |
2 | + | |
3 | +#![feature(let_else)] | |
4 | + | |
5 | +fn main() { | |
6 | +let Some(n) = &mut &mut Some(5i32) else { return; }; | |
7 | +*n += 1; // OK | |
8 | +let _ = n; | |
9 | + | |
10 | +let Some(n): &mut Option<i32> = &mut &mut Some(5i32) else { return; }; | |
11 | +*n += 1; // OK | |
12 | +let _ = n; | |
13 | +} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
1 | +// from rfc2005 test suite | |
2 | + | |
3 | +#![feature(let_else)] | |
4 | + | |
5 | +// Verify the binding mode shifts - only when no `&` are auto-dereferenced is the | |
6 | +// final default binding mode mutable. | |
7 | + | |
8 | +fn main() { | |
9 | +let Some(n) = &&Some(5i32) else { return }; | |
10 | +*n += 1; //~ ERROR cannot assign to `*n`, which is behind a `&` reference | |
11 | +let _ = n; | |
12 | + | |
13 | +let Some(n) = &mut &Some(5i32) else { return }; | |
14 | +*n += 1; //~ ERROR cannot assign to `*n`, which is behind a `&` reference | |
15 | +let _ = n; | |
16 | + | |
17 | +let Some(n) = &&mut Some(5i32) else { return }; | |
18 | +*n += 1; //~ ERROR cannot assign to `*n`, which is behind a `&` reference | |
19 | +let _ = n; | |
20 | +} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
1 | +error[E0594]: cannot assign to `*n`, which is behind a `&` reference | |
2 | + --> $DIR/let-else-binding-explicit-mut.rs:10:5 | |
3 | + | | |
4 | +LL | *n += 1; | |
5 | + | ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written | |
6 | + | |
7 | +error[E0594]: cannot assign to `*n`, which is behind a `&` reference | |
8 | + --> $DIR/let-else-binding-explicit-mut.rs:14:5 | |
9 | + | | |
10 | +LL | *n += 1; | |
11 | + | ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written | |
12 | + | |
13 | +error[E0594]: cannot assign to `*n`, which is behind a `&` reference | |
14 | + --> $DIR/let-else-binding-explicit-mut.rs🔞5 | |
15 | + | | |
16 | +LL | *n += 1; | |
17 | + | ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written | |
18 | + | |
19 | +error: aborting due to 3 previous errors | |
20 | + | |
21 | +For more information about this error, try `rustc --explain E0594`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
1 | +// from rfc2005 test suite | |
2 | + | |
3 | +#![feature(let_else)] | |
4 | + | |
5 | +pub fn main() { | |
6 | +let Some(x) = &Some(3) else { | |
7 | +panic!(); | |
8 | +}; | |
9 | +*x += 1; //~ ERROR: cannot assign to `*x`, which is behind a `&` reference | |
10 | +} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
1 | +error[E0594]: cannot assign to `*x`, which is behind a `&` reference | |
2 | + --> $DIR/let-else-binding-immutable.rs:9:5 | |
3 | + | | |
4 | +LL | *x += 1; | |
5 | + | ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written | |
6 | + | |
7 | +error: aborting due to previous error | |
8 | + | |
9 | +For more information about this error, try `rustc --explain E0594`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
1 | +// run-pass | |
2 | +// adapted from src/test/ui/binding/if-let.rs | |
3 | +#![feature(let_else)] | |
4 | +#![allow(dead_code)] | |
5 | + | |
6 | +fn none() -> bool { | |
7 | +let None = Some("test") else { | |
8 | +return true; | |
9 | +}; | |
10 | +false | |
11 | +} | |
12 | + | |
13 | +fn ok() -> bool { | |
14 | +let Ok(()) = Err::<(),&'static str>("test") else { | |
15 | +return true; | |
16 | +}; | |
17 | +false | |
18 | +} | |
19 | + | |
20 | +pub fn main() { | |
21 | +let x = Some(3); | |
22 | +let Some(y) = x else { | |
23 | +panic!("let-else panicked"); | |
24 | +}; | |
25 | +assert_eq!(y, 3); | |
26 | +let Some(_) = x else { | |
27 | +panic!("bad match"); | |
28 | +}; | |
29 | +assert!(none()); | |
30 | +assert!(ok()); | |
31 | + | |
32 | +assert!((| | |
33 | +let 1 = 2 else { | |
34 | +return true; | |
35 | +}; | |
36 | +false | |
37 | +})()); | |
38 | + | |
39 | +enum Foo { | |
40 | +One, | |
41 | +Two(usize), | |
42 | +Three(String, isize), | |
43 | +} | |
44 | + | |
45 | +let foo = Foo::Three("three".to_string(), 42); | |
46 | +let one = | | |
47 | +let Foo::One = foo else { | |
48 | +return true; | |
49 | +}; | |
50 | +false | |
51 | +}; | |
52 | +assert!(one()); | |
53 | +let two = | | |
54 | +let Foo::Two(_x) = foo else { | |
55 | +return true; | |
56 | +}; | |
57 | +false | |
58 | +}; | |
59 | +assert!(two()); | |
60 | +let three = | | |
61 | +let Foo::Three(s, _x) = foo else { | |
62 | +return false; | |
63 | +}; | |
64 | + s == "three" | |
65 | +}; | |
66 | +assert!(three()); | |
67 | + | |
68 | +let a@Foo::Two(_) = Foo::Two(42_usize) else { | |
69 | +panic!("bad match") | |
70 | +}; | |
71 | +let Foo::Two(b) = a else { | |
72 | +panic!("panic in nested `if let`"); | |
73 | +}; | |
74 | +assert_eq!(b, 42_usize); | |
75 | +} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
1 | +// from rfc2005 test suite | |
2 | + | |
3 | +#![feature(let_else)] | |
4 | + | |
5 | +// Without caching type lookups in FnCtxt.resolve_ty_and_def_ufcs | |
6 | +// the error below would be reported twice (once when checking | |
7 | +// for a non-ref pattern, once when processing the pattern). | |
8 | + | |
9 | +fn main() { | |
10 | +let foo = 22; | |
11 | +let u32::XXX = foo else { return }; //~ ERROR: no associated item named `XXX` found for type `u32` in the current scope [E0599] | |
12 | +} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
1 | +error[E0599]: no associated item named `XXX` found for type `u32` in the current scope | |
2 | + --> $DIR/let-else-no-double-error.rs:11:14 | |
3 | + | | |
4 | +LL | let u32::XXX = foo else { return }; | |
5 | + | ^^^ associated item not found in `u32` | |
6 | + | |
7 | +error: aborting due to previous error | |
8 | + | |
9 | +For more information about this error, try `rustc --explain E0599`. |