Skip to content

Commit

Permalink
let-else: build out ref/ref mut tests, with/without explicit annotations
Browse files Browse the repository at this point in the history
expands issue 89960
  • Loading branch information
cormacrelf committed Dec 13, 2021
1 parent 61bcd8d commit 102b912
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 19 deletions.
7 changes: 0 additions & 7 deletions src/test/ui/let-else/issue-89960.rs

This file was deleted.

12 changes: 0 additions & 12 deletions src/test/ui/let-else/issue-89960.stderr

This file was deleted.

71 changes: 71 additions & 0 deletions src/test/ui/let-else/let-else-ref-bindings-pass.rs
Original file line number Diff line number Diff line change
@@ -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();
}
62 changes: 62 additions & 0 deletions src/test/ui/let-else/let-else-ref-bindings.rs
Original file line number Diff line number Diff line change
@@ -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();
}
75 changes: 75 additions & 0 deletions src/test/ui/let-else/let-else-ref-bindings.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 102b912

Please sign in to comment.