let-else: build out ref/ref mut tests, with/without explicit annotations

expands issue 89960
This commit is contained in:
Cormac Relf 2021-10-17 18:29:00 +11:00
parent 61bcd8d307
commit 102b9125e1
5 changed files with 208 additions and 19 deletions

View File

@ -1,7 +0,0 @@
#![feature(let_else)]
fn main() {
// FIXME: more precise diagnostics
let Some(ref mut meow) = Some(()) else { return };
//~^ ERROR: cannot borrow value as mutable, as `val` is not declared as mutable
}

View File

@ -1,12 +0,0 @@
error[E0596]: cannot borrow value as mutable, as `val` is not declared as mutable
--> $DIR/issue-89960.rs:5:14
|
LL | let Some(ref mut meow) = Some(()) else { return };
| ---------^^^^^^^^^^^^-----------------------------
| | |
| | cannot borrow as mutable
| help: consider changing this to be mutable: `mut val`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0596`.

View File

@ -0,0 +1,71 @@
// check-pass
#![feature(let_else)]
#![allow(unused_variables)]
fn ref_() {
let bytes: Vec<u8> = b"Hello"[..].to_vec();
let some = Some(bytes);
let Some(ref a) = Some(()) else { return };
// | ref | type annotation | & |
// | --- | --------------- | - |
// | x | x | | error
// | x | x | x | error
// | | x | | error
// | | x | x | error
// | x | | |
let Some(ref a) = some else { return }; // OK
let b: &[u8] = a;
// | x | | x |
let Some(ref a) = &some else { return }; // OK
let b: &[u8] = a;
// | | | x |
let Some(a) = &some else { return }; // OK
let b: &[u8] = a;
let Some(a): Option<&[u8]> = some.as_deref() else { return }; // OK
let b: &[u8] = a;
let Some(ref a): Option<&[u8]> = some.as_deref() else { return }; // OK
let b: &[u8] = a;
}
fn ref_mut() {
// This `ref mut` case had an ICE, see issue #89960
let Some(ref mut a) = Some(()) else { return };
let bytes: Vec<u8> = b"Hello"[..].to_vec();
let mut some = Some(bytes);
// | ref mut | type annotation | &mut |
// | ------- | --------------- | ---- |
// | x | x | | error
// | x | x | x | error
// | | x | | error
// | | x | x | error
// | x | | |
let Some(ref mut a) = some else { return }; // OK
let b: &mut [u8] = a;
// | x | | x |
let Some(ref mut a) = &mut some else { return }; // OK
let b: &mut [u8] = a;
// | | | x |
let Some(a) = &mut some else { return }; // OK
let b: &mut [u8] = a;
let Some(a): Option<&mut [u8]> = some.as_deref_mut() else { return }; // OK
let b: &mut [u8] = a;
let Some(ref mut a): Option<&mut [u8]> = some.as_deref_mut() else { return }; // OK
let b: &mut [u8] = a;
}
fn main() {
ref_();
ref_mut();
}

View File

@ -0,0 +1,62 @@
#![feature(let_else)]
#![allow(unused_variables)]
fn ref_() {
let bytes: Vec<u8> = b"Hello"[..].to_vec();
let some = Some(bytes);
let Some(ref a) = Some(()) else { return };
// | ref | type annotation | & |
// | --- | --------------- | - |
// | x | | | OK
// | x | | x | OK
// | | | x | OK
// | x | x | |
let Some(ref a): Option<&[u8]> = some else { return }; //~ ERROR mismatched types
let b: & [u8] = a;
// | x | x | x |
let Some(ref a): Option<&[u8]> = &some else { return }; //~ ERROR mismatched types
let b: & [u8] = a;
// | | x | |
let Some(a): Option<&[u8]> = some else { return }; //~ ERROR mismatched types
let b: &[u8] = a;
// | | x | x |
let Some(a): Option<&[u8]> = &some else { return }; //~ ERROR mismatched types
let b: &[u8] = a;
}
fn ref_mut() {
// This `ref mut` case had an ICE, see issue #89960
let Some(ref mut a) = Some(()) else { return };
let bytes: Vec<u8> = b"Hello"[..].to_vec();
let mut some = Some(bytes);
// | ref mut | type annotation | &mut |
// | ------- | --------------- | ---- |
// | x | | | OK
// | x | | x | OK
// | | | x | OK
// | x | x | |
let Some(ref mut a): Option<&mut [u8]> = some else { return }; //~ ERROR mismatched types
let b: &mut [u8] = a;
// | x | x | x | (nope)
let Some(ref mut a): Option<&mut [u8]> = &mut some else { return }; //~ ERROR mismatched types
let b: &mut [u8] = a;
// | | x | |
let Some(a): Option<&mut [u8]> = some else { return }; //~ ERROR mismatched types
let b: &mut [u8] = a;
// | | x | x |
let Some(a): Option<&mut [u8]> = &mut some else { return }; //~ ERROR mismatched types
let b: &mut [u8] = a;
}
fn main() {
ref_();
ref_mut();
}

View File

@ -0,0 +1,75 @@
error[E0308]: mismatched types
--> $DIR/let-else-ref-bindings.rs:16:38
|
LL | let Some(ref a): Option<&[u8]> = some else { return };
| ^^^^ expected `&[u8]`, found struct `Vec`
|
= note: expected enum `Option<&[u8]>`
found enum `Option<Vec<u8>>`
error[E0308]: mismatched types
--> $DIR/let-else-ref-bindings.rs:20:38
|
LL | let Some(ref a): Option<&[u8]> = &some else { return };
| ^^^^^ expected enum `Option`, found `&Option<Vec<u8>>`
|
= note: expected enum `Option<&[u8]>`
found reference `&Option<Vec<u8>>`
error[E0308]: mismatched types
--> $DIR/let-else-ref-bindings.rs:24:34
|
LL | let Some(a): Option<&[u8]> = some else { return };
| ^^^^ expected `&[u8]`, found struct `Vec`
|
= note: expected enum `Option<&[u8]>`
found enum `Option<Vec<u8>>`
error[E0308]: mismatched types
--> $DIR/let-else-ref-bindings.rs:27:34
|
LL | let Some(a): Option<&[u8]> = &some else { return };
| ^^^^^ expected enum `Option`, found `&Option<Vec<u8>>`
|
= note: expected enum `Option<&[u8]>`
found reference `&Option<Vec<u8>>`
error[E0308]: mismatched types
--> $DIR/let-else-ref-bindings.rs:44:46
|
LL | let Some(ref mut a): Option<&mut [u8]> = some else { return };
| ^^^^ expected `&mut [u8]`, found struct `Vec`
|
= note: expected enum `Option<&mut [u8]>`
found enum `Option<Vec<u8>>`
error[E0308]: mismatched types
--> $DIR/let-else-ref-bindings.rs:48:46
|
LL | let Some(ref mut a): Option<&mut [u8]> = &mut some else { return };
| ^^^^^^^^^ expected enum `Option`, found mutable reference
|
= note: expected enum `Option<&mut [u8]>`
found mutable reference `&mut Option<Vec<u8>>`
error[E0308]: mismatched types
--> $DIR/let-else-ref-bindings.rs:52:38
|
LL | let Some(a): Option<&mut [u8]> = some else { return };
| ^^^^ expected `&mut [u8]`, found struct `Vec`
|
= note: expected enum `Option<&mut [u8]>`
found enum `Option<Vec<u8>>`
error[E0308]: mismatched types
--> $DIR/let-else-ref-bindings.rs:55:38
|
LL | let Some(a): Option<&mut [u8]> = &mut some else { return };
| ^^^^^^^^^ expected enum `Option`, found mutable reference
|
= note: expected enum `Option<&mut [u8]>`
found mutable reference `&mut Option<Vec<u8>>`
error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0308`.