about summary refs log tree commit diff
path: root/src/test/ui
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-25 14:42:20 +0000
committerbors <bors@rust-lang.org>2020-09-25 14:42:20 +0000
commit5b9e8864032a3bfefa6f69c33fd99e0383a414af (patch)
tree2dbbe921ff9dca5c86e8865a12da48dac8b96409 /src/test/ui
parentb984ef6797ff17faa2b1e0ebb54b78de1491e5fd (diff)
parent24e0913e37cc6fc363b37d13bf519db212f175a2 (diff)
Auto merge of #73453 - erikdesjardins:tuplayout, r=eddyb
Ignore ZST offsets when deciding whether to use Scalar/ScalarPair layout

This is important because Scalar/ScalarPair layout previously would not be used if any ZST had nonzero offset.
For example, before this change, only `((), u128)` would be laid out like `u128`, not `(u128, ())`.

Fixes #63244
Diffstat (limited to 'src/test/ui')
-rw-r--r--src/test/ui/dynamically-sized-types/dst-tuple-no-reorder.rs26
-rw-r--r--src/test/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs22
-rw-r--r--src/test/ui/mir/mir_const_prop_tuple_field_reorder.rs27
3 files changed, 75 insertions, 0 deletions
diff --git a/src/test/ui/dynamically-sized-types/dst-tuple-no-reorder.rs b/src/test/ui/dynamically-sized-types/dst-tuple-no-reorder.rs
new file mode 100644
index 00000000000..26b923f431f
--- /dev/null
+++ b/src/test/ui/dynamically-sized-types/dst-tuple-no-reorder.rs
@@ -0,0 +1,26 @@
+// run-pass
+
+#![feature(unsized_tuple_coercion)]
+
+// Ensure that unsizable fields that might be accessed don't get reordered
+
+fn nonzero_size() {
+    let sized: (u8, [u32; 2]) = (123, [456, 789]);
+    let unsize: &(u8, [u32]) = &sized;
+    assert_eq!(unsize.0, 123);
+    assert_eq!(unsize.1.len(), 2);
+    assert_eq!(unsize.1[0], 456);
+    assert_eq!(unsize.1[1], 789);
+}
+
+fn zst() {
+    let sized: (u8, [u32; 0]) = (123, []);
+    let unsize: &(u8, [u32]) = &sized;
+    assert_eq!(unsize.0, 123);
+    assert_eq!(unsize.1.len(), 0);
+}
+
+pub fn main() {
+    nonzero_size();
+    zst();
+}
diff --git a/src/test/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs b/src/test/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs
new file mode 100644
index 00000000000..b0cefe77039
--- /dev/null
+++ b/src/test/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs
@@ -0,0 +1,22 @@
+// run-pass
+
+#![feature(unsized_tuple_coercion)]
+
+// Check that we do not change the offsets of ZST fields when unsizing
+
+fn scalar_layout() {
+    let sized: &(u8, [(); 13]) = &(123, [(); 13]);
+    let unsize: &(u8, [()]) = sized;
+    assert_eq!(sized.1.as_ptr(), unsize.1.as_ptr());
+}
+
+fn scalarpair_layout() {
+    let sized: &(u8, u16, [(); 13]) = &(123, 456, [(); 13]);
+    let unsize: &(u8, u16, [()]) = sized;
+    assert_eq!(sized.2.as_ptr(), unsize.2.as_ptr());
+}
+
+pub fn main() {
+    scalar_layout();
+    scalarpair_layout();
+}
diff --git a/src/test/ui/mir/mir_const_prop_tuple_field_reorder.rs b/src/test/ui/mir/mir_const_prop_tuple_field_reorder.rs
new file mode 100644
index 00000000000..629b50dec65
--- /dev/null
+++ b/src/test/ui/mir/mir_const_prop_tuple_field_reorder.rs
@@ -0,0 +1,27 @@
+// compile-flags: -Z mir-opt-level=2
+// build-pass
+#![crate_type="lib"]
+
+// This used to ICE: const-prop did not account for field reordering of scalar pairs,
+// and would generate a tuple like `(0x1337, VariantBar): (FooEnum, isize)`,
+// causing assertion failures in codegen when trying to read 0x1337 at the wrong type.
+
+pub enum FooEnum {
+    VariantBar,
+    VariantBaz,
+    VariantBuz,
+}
+
+pub fn wrong_index() -> isize {
+    let (_, b) = id((FooEnum::VariantBar, 0x1337));
+    b
+}
+
+pub fn wrong_index_two() -> isize {
+    let (_, (_, b)) = id(((), (FooEnum::VariantBar, 0x1338)));
+    b
+}
+
+fn id<T>(x: T) -> T {
+    x
+}