about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-02-26 16:06:04 +0100
committerGitHub <noreply@github.com>2024-02-26 16:06:04 +0100
commit218be2771d89907ff704b9a3561c3fa96899a991 (patch)
tree8da4a4e2c3dcab305d9413de94d2a5e0cdcc7371 /compiler
parent4f167b4baf2a05580d09db9d2d374bbb4852c71c (diff)
parent633c92cd6de9e269b9c5b10f341fc10280503f0c (diff)
downloadrust-218be2771d89907ff704b9a3561c3fa96899a991.tar.gz
rust-218be2771d89907ff704b9a3561c3fa96899a991.zip
Rollup merge of #121628 - gurry:121534-ice-asymm-binop, r=oli-obk
Do not const prop unions

Unions can produce values whose types don't match their underlying layout types which can lead to ICEs on eval.

Fixes #121534
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs40
1 files changed, 26 insertions, 14 deletions
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index a9cd688c315..7cab6650994 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -585,20 +585,32 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 val.into()
             }
 
-            Aggregate(ref kind, ref fields) => Value::Aggregate {
-                fields: fields
-                    .iter()
-                    .map(|field| self.eval_operand(field).map_or(Value::Uninit, Value::Immediate))
-                    .collect(),
-                variant: match **kind {
-                    AggregateKind::Adt(_, variant, _, _, _) => variant,
-                    AggregateKind::Array(_)
-                    | AggregateKind::Tuple
-                    | AggregateKind::Closure(_, _)
-                    | AggregateKind::Coroutine(_, _)
-                    | AggregateKind::CoroutineClosure(_, _) => VariantIdx::new(0),
-                },
-            },
+            Aggregate(ref kind, ref fields) => {
+                // Do not const pop union fields as they can be
+                // made to produce values that don't match their
+                // underlying layout's type (see ICE #121534).
+                // If the last element of the `Adt` tuple
+                // is `Some` it indicates the ADT is a union
+                if let AggregateKind::Adt(_, _, _, _, Some(_)) = **kind {
+                    return None;
+                };
+                Value::Aggregate {
+                    fields: fields
+                        .iter()
+                        .map(|field| {
+                            self.eval_operand(field).map_or(Value::Uninit, Value::Immediate)
+                        })
+                        .collect(),
+                    variant: match **kind {
+                        AggregateKind::Adt(_, variant, _, _, _) => variant,
+                        AggregateKind::Array(_)
+                        | AggregateKind::Tuple
+                        | AggregateKind::Closure(_, _)
+                        | AggregateKind::Coroutine(_, _)
+                        | AggregateKind::CoroutineClosure(_, _) => VariantIdx::new(0),
+                    },
+                }
+            }
 
             Repeat(ref op, n) => {
                 trace!(?op, ?n);