about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
diff options
context:
space:
mode:
authorGurinder Singh <frederick.the.fool@gmail.com>2024-02-26 15:22:22 +0530
committerGurinder Singh <frederick.the.fool@gmail.com>2024-02-26 15:22:22 +0530
commit633c92cd6de9e269b9c5b10f341fc10280503f0c (patch)
treed9635cef700249491198ee0482fcbb500ac5c537 /compiler/rustc_mir_transform/src
parent0250ef2571185b05701ed9d74fc904c17508a397 (diff)
downloadrust-633c92cd6de9e269b9c5b10f341fc10280503f0c.tar.gz
rust-633c92cd6de9e269b9c5b10f341fc10280503f0c.zip
Do not const pop unions
as they can made to produce values whose types don't
match their underlying layout types which can lead to
ICEs on eval
Diffstat (limited to 'compiler/rustc_mir_transform/src')
-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);