mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
let-else: add match-ergonomics tests adapted from rfc2005
collect explicit-mut passing tests in one file
This commit is contained in:
parent
102b9125e1
commit
2715c5f984
@ -0,0 +1,16 @@
|
||||
// from rfc2005 test suite
|
||||
|
||||
#![feature(let_else)]
|
||||
|
||||
// Verify the binding mode shifts - only when no `&` are auto-dereferenced is the
|
||||
// final default binding mode mutable.
|
||||
|
||||
fn main() {
|
||||
let Some(n): &mut Option<i32> = &&Some(5i32) else { return }; //~ ERROR mismatched types
|
||||
*n += 1;
|
||||
let _ = n;
|
||||
|
||||
let Some(n): &mut Option<i32> = &&mut Some(5i32) else { return }; //~ ERROR mismatched types
|
||||
*n += 1;
|
||||
let _ = n;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/let-else-binding-explicit-mut-annotated.rs:9:37
|
||||
|
|
||||
LL | let Some(n): &mut Option<i32> = &&Some(5i32) else { return };
|
||||
| ^^^^^^^^^^^^ types differ in mutability
|
||||
|
|
||||
= note: expected mutable reference `&mut Option<i32>`
|
||||
found reference `&&Option<i32>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/let-else-binding-explicit-mut-annotated.rs:13:37
|
||||
|
|
||||
LL | let Some(n): &mut Option<i32> = &&mut Some(5i32) else { return };
|
||||
| ^^^^^^^^^^^^^^^^ types differ in mutability
|
||||
|
|
||||
= note: expected mutable reference `&mut Option<i32>`
|
||||
found reference `&&mut Option<i32>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
13
src/test/ui/let-else/let-else-binding-explicit-mut-borrow.rs
Normal file
13
src/test/ui/let-else/let-else-binding-explicit-mut-borrow.rs
Normal file
@ -0,0 +1,13 @@
|
||||
#![feature(let_else)]
|
||||
|
||||
// Slightly different from explicit-mut-annotated -- this won't show an error until borrowck.
|
||||
// Should it show a type error instead?
|
||||
|
||||
fn main() {
|
||||
let Some(n): &mut Option<i32> = &mut &Some(5i32) else {
|
||||
//~^ ERROR cannot borrow data in a `&` reference as mutable
|
||||
return
|
||||
};
|
||||
*n += 1;
|
||||
let _ = n;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
error[E0596]: cannot borrow data in a `&` reference as mutable
|
||||
--> $DIR/let-else-binding-explicit-mut-borrow.rs:7:37
|
||||
|
|
||||
LL | let Some(n): &mut Option<i32> = &mut &Some(5i32) else {
|
||||
| ^^^^^^^^^^^^^^^^ cannot borrow as mutable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0596`.
|
13
src/test/ui/let-else/let-else-binding-explicit-mut-pass.rs
Normal file
13
src/test/ui/let-else/let-else-binding-explicit-mut-pass.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(let_else)]
|
||||
|
||||
fn main() {
|
||||
let Some(n) = &mut &mut Some(5i32) else { return; };
|
||||
*n += 1; // OK
|
||||
let _ = n;
|
||||
|
||||
let Some(n): &mut Option<i32> = &mut &mut Some(5i32) else { return; };
|
||||
*n += 1; // OK
|
||||
let _ = n;
|
||||
}
|
20
src/test/ui/let-else/let-else-binding-explicit-mut.rs
Normal file
20
src/test/ui/let-else/let-else-binding-explicit-mut.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// from rfc2005 test suite
|
||||
|
||||
#![feature(let_else)]
|
||||
|
||||
// Verify the binding mode shifts - only when no `&` are auto-dereferenced is the
|
||||
// final default binding mode mutable.
|
||||
|
||||
fn main() {
|
||||
let Some(n) = &&Some(5i32) else { return };
|
||||
*n += 1; //~ ERROR cannot assign to `*n`, which is behind a `&` reference
|
||||
let _ = n;
|
||||
|
||||
let Some(n) = &mut &Some(5i32) else { return };
|
||||
*n += 1; //~ ERROR cannot assign to `*n`, which is behind a `&` reference
|
||||
let _ = n;
|
||||
|
||||
let Some(n) = &&mut Some(5i32) else { return };
|
||||
*n += 1; //~ ERROR cannot assign to `*n`, which is behind a `&` reference
|
||||
let _ = n;
|
||||
}
|
21
src/test/ui/let-else/let-else-binding-explicit-mut.stderr
Normal file
21
src/test/ui/let-else/let-else-binding-explicit-mut.stderr
Normal file
@ -0,0 +1,21 @@
|
||||
error[E0594]: cannot assign to `*n`, which is behind a `&` reference
|
||||
--> $DIR/let-else-binding-explicit-mut.rs:10:5
|
||||
|
|
||||
LL | *n += 1;
|
||||
| ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written
|
||||
|
||||
error[E0594]: cannot assign to `*n`, which is behind a `&` reference
|
||||
--> $DIR/let-else-binding-explicit-mut.rs:14:5
|
||||
|
|
||||
LL | *n += 1;
|
||||
| ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written
|
||||
|
||||
error[E0594]: cannot assign to `*n`, which is behind a `&` reference
|
||||
--> $DIR/let-else-binding-explicit-mut.rs:18:5
|
||||
|
|
||||
LL | *n += 1;
|
||||
| ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0594`.
|
10
src/test/ui/let-else/let-else-binding-immutable.rs
Normal file
10
src/test/ui/let-else/let-else-binding-immutable.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// from rfc2005 test suite
|
||||
|
||||
#![feature(let_else)]
|
||||
|
||||
pub fn main() {
|
||||
let Some(x) = &Some(3) else {
|
||||
panic!();
|
||||
};
|
||||
*x += 1; //~ ERROR: cannot assign to `*x`, which is behind a `&` reference
|
||||
}
|
9
src/test/ui/let-else/let-else-binding-immutable.stderr
Normal file
9
src/test/ui/let-else/let-else-binding-immutable.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0594]: cannot assign to `*x`, which is behind a `&` reference
|
||||
--> $DIR/let-else-binding-immutable.rs:9:5
|
||||
|
|
||||
LL | *x += 1;
|
||||
| ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0594`.
|
75
src/test/ui/let-else/let-else-bindings.rs
Normal file
75
src/test/ui/let-else/let-else-bindings.rs
Normal file
@ -0,0 +1,75 @@
|
||||
// run-pass
|
||||
// adapted from src/test/ui/binding/if-let.rs
|
||||
#![feature(let_else)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn none() -> bool {
|
||||
let None = Some("test") else {
|
||||
return true;
|
||||
};
|
||||
false
|
||||
}
|
||||
|
||||
fn ok() -> bool {
|
||||
let Ok(()) = Err::<(),&'static str>("test") else {
|
||||
return true;
|
||||
};
|
||||
false
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let x = Some(3);
|
||||
let Some(y) = x else {
|
||||
panic!("let-else panicked");
|
||||
};
|
||||
assert_eq!(y, 3);
|
||||
let Some(_) = x else {
|
||||
panic!("bad match");
|
||||
};
|
||||
assert!(none());
|
||||
assert!(ok());
|
||||
|
||||
assert!((|| {
|
||||
let 1 = 2 else {
|
||||
return true;
|
||||
};
|
||||
false
|
||||
})());
|
||||
|
||||
enum Foo {
|
||||
One,
|
||||
Two(usize),
|
||||
Three(String, isize),
|
||||
}
|
||||
|
||||
let foo = Foo::Three("three".to_string(), 42);
|
||||
let one = || {
|
||||
let Foo::One = foo else {
|
||||
return true;
|
||||
};
|
||||
false
|
||||
};
|
||||
assert!(one());
|
||||
let two = || {
|
||||
let Foo::Two(_x) = foo else {
|
||||
return true;
|
||||
};
|
||||
false
|
||||
};
|
||||
assert!(two());
|
||||
let three = || {
|
||||
let Foo::Three(s, _x) = foo else {
|
||||
return false;
|
||||
};
|
||||
s == "three"
|
||||
};
|
||||
assert!(three());
|
||||
|
||||
let a@Foo::Two(_) = Foo::Two(42_usize) else {
|
||||
panic!("bad match")
|
||||
};
|
||||
let Foo::Two(b) = a else {
|
||||
panic!("panic in nested `if let`");
|
||||
};
|
||||
assert_eq!(b, 42_usize);
|
||||
}
|
12
src/test/ui/let-else/let-else-no-double-error.rs
Normal file
12
src/test/ui/let-else/let-else-no-double-error.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// from rfc2005 test suite
|
||||
|
||||
#![feature(let_else)]
|
||||
|
||||
// Without caching type lookups in FnCtxt.resolve_ty_and_def_ufcs
|
||||
// the error below would be reported twice (once when checking
|
||||
// for a non-ref pattern, once when processing the pattern).
|
||||
|
||||
fn main() {
|
||||
let foo = 22;
|
||||
let u32::XXX = foo else { return }; //~ ERROR: no associated item named `XXX` found for type `u32` in the current scope [E0599]
|
||||
}
|
9
src/test/ui/let-else/let-else-no-double-error.stderr
Normal file
9
src/test/ui/let-else/let-else-no-double-error.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0599]: no associated item named `XXX` found for type `u32` in the current scope
|
||||
--> $DIR/let-else-no-double-error.rs:11:14
|
||||
|
|
||||
LL | let u32::XXX = foo else { return };
|
||||
| ^^^ associated item not found in `u32`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
Loading…
Reference in New Issue
Block a user