diff options
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/dataflow_const_prop.rs | 20 |
1 files changed, 14 insertions, 6 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); |
