From 102b9125e1cefbb8ed8408d2db3f9f7d5afddbf0 Mon Sep 17 00:00:00 2001 From: Cormac Relf Date: Sun, 17 Oct 2021 18:29:00 +1100 Subject: [PATCH] let-else: build out ref/ref mut tests, with/without explicit annotations expands issue 89960 --- src/test/ui/let-else/issue-89960.rs | 7 -- src/test/ui/let-else/issue-89960.stderr | 12 --- .../ui/let-else/let-else-ref-bindings-pass.rs | 71 ++++++++++++++++++ src/test/ui/let-else/let-else-ref-bindings.rs | 62 +++++++++++++++ .../ui/let-else/let-else-ref-bindings.stderr | 75 +++++++++++++++++++ 5 files changed, 208 insertions(+), 19 deletions(-) delete mode 100644 src/test/ui/let-else/issue-89960.rs delete mode 100644 src/test/ui/let-else/issue-89960.stderr create mode 100644 src/test/ui/let-else/let-else-ref-bindings-pass.rs create mode 100644 src/test/ui/let-else/let-else-ref-bindings.rs create mode 100644 src/test/ui/let-else/let-else-ref-bindings.stderr diff --git a/src/test/ui/let-else/issue-89960.rs b/src/test/ui/let-else/issue-89960.rs deleted file mode 100644 index 8fd55adbfd428..0000000000000 --- a/src/test/ui/let-else/issue-89960.rs +++ /dev/null @@ -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 -} diff --git a/src/test/ui/let-else/issue-89960.stderr b/src/test/ui/let-else/issue-89960.stderr deleted file mode 100644 index 697f04d6d2735..0000000000000 --- a/src/test/ui/let-else/issue-89960.stderr +++ /dev/null @@ -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`. diff --git a/src/test/ui/let-else/let-else-ref-bindings-pass.rs b/src/test/ui/let-else/let-else-ref-bindings-pass.rs new file mode 100644 index 0000000000000..f4abd6cc2df25 --- /dev/null +++ b/src/test/ui/let-else/let-else-ref-bindings-pass.rs @@ -0,0 +1,71 @@ +// check-pass + +#![feature(let_else)] +#![allow(unused_variables)] + +fn ref_() { + let bytes: Vec = 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 = 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(); +} diff --git a/src/test/ui/let-else/let-else-ref-bindings.rs b/src/test/ui/let-else/let-else-ref-bindings.rs new file mode 100644 index 0000000000000..a4cd8e8c47d46 --- /dev/null +++ b/src/test/ui/let-else/let-else-ref-bindings.rs @@ -0,0 +1,62 @@ +#![feature(let_else)] +#![allow(unused_variables)] + +fn ref_() { + let bytes: Vec = 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 = 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(); +} diff --git a/src/test/ui/let-else/let-else-ref-bindings.stderr b/src/test/ui/let-else/let-else-ref-bindings.stderr new file mode 100644 index 0000000000000..650f4ec5e779f --- /dev/null +++ b/src/test/ui/let-else/let-else-ref-bindings.stderr @@ -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>` + +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>` + | + = note: expected enum `Option<&[u8]>` + found reference `&Option>` + +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>` + +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>` + | + = note: expected enum `Option<&[u8]>` + found reference `&Option>` + +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>` + +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>` + +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>` + +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>` + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0308`.