about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-02-03 12:46:02 +0000
committerbors <bors@rust-lang.org>2022-02-03 12:46:02 +0000
commit8b7853fe1f87a40ceaddf63aa404817bbfa69676 (patch)
tree50f563e57cb1672245225b9113a139e8a8ea3ab3
parent796bf14f2e129283d9daee7f05d14c2dfa76d643 (diff)
parentfd5be23a96274cb1d1f83acdd8f7370ee15e00fa (diff)
downloadrust-8b7853fe1f87a40ceaddf63aa404817bbfa69676.tar.gz
rust-8b7853fe1f87a40ceaddf63aa404817bbfa69676.zip
Auto merge of #92932 - ouz-a:master, r=oli-obk
Temporary fix for the layout of aligned enums

Fix for the issue #92464

~~I was after this issue for quite some time now, I have a temporary fix for it.
I think the current problem is [here](https://github.com/ouz-a/rust/blob/e75f96763f99d56d03ada939fe05cbeb2254888d/compiler/rustc_middle/src/ty/layout.rs#L1305-L1310) created `tag` value might be wrong, because when I checked `min` and `max` values it's always between 0..1, which results in wrong size comparison in a few lines down below.
I think `min` and `max` values don't take `#[repr(aligned(8))]` into consideration and just act from base values assigned inside the enum. If what I am saying is true, aligned enums were created with the wrong layout for some time.~~

~~As stated in the title this is only a temporary fix and I think this needs further investigation, if someone wants to mentor it I would like to work on that too.~~ 😸

**Edit: Weird some tests fail now going to close this for now...**

**Edit2: I made it work again.**

I think I figured out the main problem of the issue, layout types of aligned enums with custom discriminant types were not handled, which resulted in confusing(such as this issue) behavior down the line, this is a kinda hacky fix for the issue.
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs5
-rw-r--r--src/test/ui/aligned_enum_cast.rs15
2 files changed, 19 insertions, 1 deletions
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index caf33fa5d21..ad817e185a3 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1310,7 +1310,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     },
                 };
                 let mut abi = Abi::Aggregate { sized: true };
-                if tag.value.size(dl) == size {
+
+                // Without latter check aligned enums with custom discriminant values
+                // Would result in ICE see the issue #92464 for more info
+                if tag.value.size(dl) == size || variants.iter().all(|layout| layout.is_empty()) {
                     abi = Abi::Scalar(tag);
                 } else {
                     // Try to use a ScalarPair for all tagged enums.
diff --git a/src/test/ui/aligned_enum_cast.rs b/src/test/ui/aligned_enum_cast.rs
new file mode 100644
index 00000000000..4b5776a6aa8
--- /dev/null
+++ b/src/test/ui/aligned_enum_cast.rs
@@ -0,0 +1,15 @@
+// run-pass
+// allows aligned custom discriminant enums to cast into other types
+// See the issue #92464 for more info
+#[allow(dead_code)]
+#[repr(align(8))]
+enum Aligned {
+    Zero = 0,
+    One = 1,
+}
+
+fn main() {
+    let aligned = Aligned::Zero;
+    let fo = aligned as u8;
+    println!("foo {}",fo);
+}