about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCormac Relf <web@cormacrelf.net>2021-10-17 18:29:00 +1100
committerCormac Relf <web@cormacrelf.net>2021-12-13 14:02:41 +1100
commit102b9125e1cefbb8ed8408d2db3f9f7d5afddbf0 (patch)
tree1160276137c50b3c0810cf5fca4089003570117f
parent61bcd8d3075471b3867428788c49f54fffe53f52 (diff)
downloadrust-102b9125e1cefbb8ed8408d2db3f9f7d5afddbf0.tar.gz
rust-102b9125e1cefbb8ed8408d2db3f9f7d5afddbf0.zip
let-else: build out ref/ref mut tests, with/without explicit annotations
expands issue 89960
-rw-r--r--src/test/ui/let-else/issue-89960.rs7
-rw-r--r--src/test/ui/let-else/issue-89960.stderr12
-rw-r--r--src/test/ui/let-else/let-else-ref-bindings-pass.rs71
-rw-r--r--src/test/ui/let-else/let-else-ref-bindings.rs62
-rw-r--r--src/test/ui/let-else/let-else-ref-bindings.stderr75
5 files changed, 208 insertions, 19 deletions
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 8fd55adbfd4..00000000000
--- 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 697f04d6d27..00000000000
--- 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 00000000000..f4abd6cc2df
--- /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<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();
+}
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 00000000000..a4cd8e8c47d
--- /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<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();
+}
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 00000000000..650f4ec5e77
--- /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<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`.