|
37 | 37 | //! if they do not consistently refer to the same place in memory. This is satisfied if they do
|
38 | 38 | //! not contain any indirection through a pointer or any indexing projections.
|
39 | 39 | //!
|
| 40 | +//! * `p` and `q` must have the **same type**. If we replace a local with a subtype or supertype, |
| 41 | +//! we may end up with a differnet vtable for that local. See the `subtyping-impacts-selection` |
| 42 | +//! tests for an example where that causes issues. |
| 43 | +//! |
40 | 44 | //! * We need to make sure that the goal of "merging the memory" is actually structurally possible
|
41 | 45 | //! in MIR. For example, even if all the other conditions are satisfied, there is no way to
|
42 | 46 | //! "merge" `_5.foo` and `_6.bar`. For now, we ensure this by requiring that both `p` and `q` are
|
@@ -134,6 +138,7 @@ use crate::MirPass;
|
134 | 138 | use rustc_data_structures::fx::FxHashMap;
|
135 | 139 | use rustc_index::bit_set::BitSet;
|
136 | 140 | use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
|
| 141 | +use rustc_middle::mir::HasLocalDecls; |
137 | 142 | use rustc_middle::mir::{dump_mir, PassWhere};
|
138 | 143 | use rustc_middle::mir::{
|
139 | 144 | traversal, Body, InlineAsmOperand, Local, LocalKind, Location, Operand, Place, Rvalue,
|
@@ -769,6 +774,14 @@ impl<'tcx> Visitor<'tcx> for FindAssignments<'_, '_, 'tcx> {
|
769 | 774 | return;
|
770 | 775 | }
|
771 | 776 |
|
| 777 | + // As described at the top of this file, we do not touch locals which have different types. |
| 778 | + let src_ty = self.body.local_decls()[src].ty; |
| 779 | + let dest_ty = self.body.local_decls()[dest].ty; |
| 780 | + if src_ty != dest_ty { |
| 781 | + trace!("skipped `{src:?} = {dest:?}` due to subtyping: {src_ty} != {dest_ty}"); |
| 782 | + return; |
| 783 | + } |
| 784 | + |
772 | 785 | // Also, we need to make sure that MIR actually allows the `src` to be removed
|
773 | 786 | if is_local_required(src, self.body) {
|
774 | 787 | return;
|
|
0 commit comments