about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2023-02-18 10:04:14 +0000
committerCamille GILLOT <gillot.camille@gmail.com>2023-02-18 10:11:53 +0000
commitefb468866e5757d404c220c812f52f8657b2fdce (patch)
tree0fbd9cd91c47f96bffa3ebd990a2f5abd7396ad4
parent7213eaa1c06bc75e6730fd5a7dea869dbdf4bed1 (diff)
downloadrust-efb468866e5757d404c220c812f52f8657b2fdce.tar.gz
rust-efb468866e5757d404c220c812f52f8657b2fdce.zip
Use the correct place for enum variants.
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs20
-rw-r--r--tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff6
2 files changed, 18 insertions, 8 deletions
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 4dc1564ce3b..0637143a145 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -134,18 +134,21 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
                         AggregateKind::Adt(def_id, variant_index, ..) => {
                             match self.tcx.def_kind(def_id) {
                                 DefKind::Struct => (Some(target_idx), None),
-                                DefKind::Enum => (Some(target_idx), Some(variant_index)),
+                                DefKind::Enum => (
+                                    self.map.apply(target_idx, TrackElem::Variant(variant_index)),
+                                    Some(variant_index),
+                                ),
                                 _ => (None, None),
                             }
                         }
                         _ => (None, None),
                     };
-                    if let Some(target) = variant_target {
+                    if let Some(variant_target_idx) = variant_target {
                         for (field_index, operand) in operands.iter().enumerate() {
-                            if let Some(field) = self
-                                .map()
-                                .apply(target, TrackElem::Field(Field::from_usize(field_index)))
-                            {
+                            if let Some(field) = self.map().apply(
+                                variant_target_idx,
+                                TrackElem::Field(Field::from_usize(field_index)),
+                            ) {
                                 let result = self.handle_operand(operand, state);
                                 state.insert_idx(field, result, self.map());
                             }
@@ -154,6 +157,11 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
                     if let Some(variant_index) = variant_index
                         && let Some(discr_idx) = self.map().apply(target_idx, TrackElem::Discriminant)
                     {
+                        // We are assigning the discriminant as part of an aggregate.
+                        // This discriminant can only alias a variant field's value if the operand
+                        // had an invalid value for that type.
+                        // Using invalid values is UB, so we are allowed to perform the assignment
+                        // without extra flooding.
                         let enum_ty = target.ty(self.local_decls, self.tcx).ty;
                         if let Some(discr_val) = self.eval_discriminant(enum_ty, variant_index) {
                             state.insert_value_idx(discr_idx, FlatSet::Elem(discr_val), &self.map);
diff --git a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff
index 1fb65e65845..22bdc35d694 100644
--- a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff
+++ b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff
@@ -45,8 +45,10 @@
   
       bb3: {
           StorageLive(_4);                 // scope 1 at $DIR/enum.rs:+2:29: +2:30
-          _4 = ((_1 as V1).0: i32);        // scope 1 at $DIR/enum.rs:+2:29: +2:30
-          _2 = _4;                         // scope 3 at $DIR/enum.rs:+2:35: +2:36
+-         _4 = ((_1 as V1).0: i32);        // scope 1 at $DIR/enum.rs:+2:29: +2:30
+-         _2 = _4;                         // scope 3 at $DIR/enum.rs:+2:35: +2:36
++         _4 = const 0_i32;                // scope 1 at $DIR/enum.rs:+2:29: +2:30
++         _2 = const 0_i32;                // scope 3 at $DIR/enum.rs:+2:35: +2:36
           StorageDead(_4);                 // scope 1 at $DIR/enum.rs:+2:35: +2:36
           goto -> bb4;                     // scope 1 at $DIR/enum.rs:+2:35: +2:36
       }