about summary refs log tree commit diff
diff options
context:
space:
mode:
authordianne <diannes.gm@gmail.com>2025-04-01 21:35:12 -0700
committerdianne <diannes.gm@gmail.com>2025-04-01 21:35:12 -0700
commit7a4d4de8a87f3dca6870e79e4110d8e3ecd7385b (patch)
tree806d95f933b1f52153c5e341acb96d4f2f51261c
parent3779c6b7974f715c1fba0e6b559798a16178193c (diff)
downloadrust-7a4d4de8a87f3dca6870e79e4110d8e3ecd7385b.tar.gz
rust-7a4d4de8a87f3dca6870e79e4110d8e3ecd7385b.zip
add tests for array/slice const patterns
-rw-r--r--tests/ui/consts/const_in_pattern/arrays-and-slices.rs53
-rw-r--r--tests/ui/consts/const_in_pattern/arrays-and-slices.stderr84
2 files changed, 137 insertions, 0 deletions
diff --git a/tests/ui/consts/const_in_pattern/arrays-and-slices.rs b/tests/ui/consts/const_in_pattern/arrays-and-slices.rs
new file mode 100644
index 00000000000..bb38490206b
--- /dev/null
+++ b/tests/ui/consts/const_in_pattern/arrays-and-slices.rs
@@ -0,0 +1,53 @@
+//! Tests that arrays and slices in constants aren't interchangeable when used as patterns.
+
+#[derive(PartialEq, Eq)]
+struct SomeStruct<T: ?Sized>(T);
+
+const BSTR_SIZED: &'static [u8; 3] = b"012";
+const BSTR_UNSIZED: &'static [u8] = BSTR_SIZED;
+const STRUCT_SIZED: &'static SomeStruct<[u8; 3]> = &SomeStruct(*BSTR_SIZED);
+const STRUCT_UNSIZED: &'static SomeStruct<[u8]> = STRUCT_SIZED;
+
+fn type_mismatches() {
+    // Test that array consts can't be used where a slice pattern is expected. This helps ensure
+    // that `const_to_pat` won't produce irrefutable `thir::PatKind::Array` patterns when matching
+    // on slices, which would result in missing length checks.
+    // See also `tests/ui/match/pattern-deref-miscompile.rs`, which tests that byte string literal
+    // patterns check slices' length appropriately when matching on slices.
+    match BSTR_UNSIZED {
+        BSTR_SIZED => {}
+        //~^ ERROR: mismatched types
+        _ => {}
+    }
+    match STRUCT_UNSIZED {
+        STRUCT_SIZED => {}
+        //~^ ERROR: mismatched types
+        _ => {}
+    }
+
+    // Test that slice consts can't be used where an array pattern is expected.
+    match BSTR_UNSIZED {
+        BSTR_SIZED => {}
+        //~^ ERROR: mismatched types
+        _ => {}
+    }
+    // If the types matched here, this would still error, since unsized structs aren't permitted in
+    // constant patterns. See the `invalid_patterns` test below.
+    match STRUCT_UNSIZED {
+        STRUCT_SIZED => {}
+        //~^ ERROR: mismatched types
+        _ => {}
+    }
+}
+
+fn invalid_patterns() {
+    // Test that unsized structs containing slices can't be used as patterns.
+    // See `tests/ui/consts/issue-87046.rs` for an example with `str`.
+    match STRUCT_UNSIZED {
+        STRUCT_UNSIZED => {}
+        //~^ ERROR: cannot use unsized non-slice type `SomeStruct<[u8]>` in constant patterns
+        _ => {}
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/consts/const_in_pattern/arrays-and-slices.stderr b/tests/ui/consts/const_in_pattern/arrays-and-slices.stderr
new file mode 100644
index 00000000000..412caf60f7d
--- /dev/null
+++ b/tests/ui/consts/const_in_pattern/arrays-and-slices.stderr
@@ -0,0 +1,84 @@
+error[E0308]: mismatched types
+  --> $DIR/arrays-and-slices.rs:18:9
+   |
+LL | const BSTR_SIZED: &'static [u8; 3] = b"012";
+   | ---------------------------------- constant defined here
+...
+LL |     match BSTR_UNSIZED {
+   |           ------------ this expression has type `&[u8]`
+LL |         BSTR_SIZED => {}
+   |         ^^^^^^^^^^
+   |         |
+   |         expected `&[u8]`, found `&[u8; 3]`
+   |         `BSTR_SIZED` is interpreted as a constant, not a new binding
+   |         help: introduce a new binding instead: `other_bstr_sized`
+   |
+   = note: expected reference `&[u8]`
+              found reference `&'static [u8; 3]`
+
+error[E0308]: mismatched types
+  --> $DIR/arrays-and-slices.rs:23:9
+   |
+LL | const STRUCT_SIZED: &'static SomeStruct<[u8; 3]> = &SomeStruct(*BSTR_SIZED);
+   | ------------------------------------------------ constant defined here
+...
+LL |     match STRUCT_UNSIZED {
+   |           -------------- this expression has type `&SomeStruct<[u8]>`
+LL |         STRUCT_SIZED => {}
+   |         ^^^^^^^^^^^^
+   |         |
+   |         expected `&SomeStruct<[u8]>`, found `&SomeStruct<[u8; 3]>`
+   |         `STRUCT_SIZED` is interpreted as a constant, not a new binding
+   |         help: introduce a new binding instead: `other_struct_sized`
+   |
+   = note: expected reference `&SomeStruct<[u8]>`
+              found reference `&'static SomeStruct<[u8; 3]>`
+
+error[E0308]: mismatched types
+  --> $DIR/arrays-and-slices.rs:30:9
+   |
+LL | const BSTR_SIZED: &'static [u8; 3] = b"012";
+   | ---------------------------------- constant defined here
+...
+LL |     match BSTR_UNSIZED {
+   |           ------------ this expression has type `&[u8]`
+LL |         BSTR_SIZED => {}
+   |         ^^^^^^^^^^
+   |         |
+   |         expected `&[u8]`, found `&[u8; 3]`
+   |         `BSTR_SIZED` is interpreted as a constant, not a new binding
+   |         help: introduce a new binding instead: `other_bstr_sized`
+   |
+   = note: expected reference `&[u8]`
+              found reference `&'static [u8; 3]`
+
+error[E0308]: mismatched types
+  --> $DIR/arrays-and-slices.rs:37:9
+   |
+LL | const STRUCT_SIZED: &'static SomeStruct<[u8; 3]> = &SomeStruct(*BSTR_SIZED);
+   | ------------------------------------------------ constant defined here
+...
+LL |     match STRUCT_UNSIZED {
+   |           -------------- this expression has type `&SomeStruct<[u8]>`
+LL |         STRUCT_SIZED => {}
+   |         ^^^^^^^^^^^^
+   |         |
+   |         expected `&SomeStruct<[u8]>`, found `&SomeStruct<[u8; 3]>`
+   |         `STRUCT_SIZED` is interpreted as a constant, not a new binding
+   |         help: introduce a new binding instead: `other_struct_sized`
+   |
+   = note: expected reference `&SomeStruct<[u8]>`
+              found reference `&'static SomeStruct<[u8; 3]>`
+
+error: cannot use unsized non-slice type `SomeStruct<[u8]>` in constant patterns
+  --> $DIR/arrays-and-slices.rs:47:9
+   |
+LL | const STRUCT_UNSIZED: &'static SomeStruct<[u8]> = STRUCT_SIZED;
+   | ----------------------------------------------- constant defined here
+...
+LL |         STRUCT_UNSIZED => {}
+   |         ^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.