diff options
| author | bors <bors@rust-lang.org> | 2020-07-26 16:09:42 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-07-26 16:09:42 +0000 |
| commit | c367798cfd3817ca6ae908ce675d1d99242af148 (patch) | |
| tree | 3c697026c11f13b35d61371c36921e6b3d1de1ca /src/librustc_mir/transform | |
| parent | 14485ee1257703df51313efe39daf35e886e4dac (diff) | |
| parent | 41895ca93f3722adf5855089442de3abc94458f0 (diff) | |
| download | rust-1.45.1.tar.gz rust-1.45.1.zip | |
Auto merge of #74746 - wesleywiser:stable_backport_73669, r=Mark-Simulacrum 1.45.1
Stable backport of #73613 This is the backport of #73613 to stable. r? @ghost cc @Mark-Simulacrum In addition the tests added in the original PR passing, I've also confirmed that the test case in #74739 works correctly.
Diffstat (limited to 'src/librustc_mir/transform')
| -rw-r--r-- | src/librustc_mir/transform/const_prop.rs | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 92000e64113..75032eafe30 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -580,8 +580,16 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } // Do not try creating references (#67862) - Rvalue::Ref(_, _, place_ref) => { - trace!("skipping Ref({:?})", place_ref); + Rvalue::AddressOf(_, place) | Rvalue::Ref(_, _, place) => { + trace!("skipping AddressOf | Ref for {:?}", place); + + // This may be creating mutable references or immutable references to cells. + // If that happens, the pointed to value could be mutated via that reference. + // Since we aren't tracking references, the const propagator loses track of what + // value the local has right now. + // Thus, all locals that have their reference taken + // must not take part in propagation. + Self::remove_const(&mut self.ecx, place.local); return None; } @@ -726,7 +734,8 @@ enum ConstPropMode { OnlyInsideOwnBlock, /// The `Local` can be propagated into but reads cannot be propagated. OnlyPropagateInto, - /// No propagation is allowed at all. + /// The `Local` cannot be part of propagation at all. Any statement + /// referencing it either for reading or writing will not get propagated. NoPropagation, } @@ -793,7 +802,9 @@ impl<'tcx> Visitor<'tcx> for CanConstProp { // end of the block anyway, and inside the block we overwrite previous // states as applicable. ConstPropMode::OnlyInsideOwnBlock => {} - other => { + ConstPropMode::NoPropagation => {} + ConstPropMode::OnlyPropagateInto => {} + other @ ConstPropMode::FullConstProp => { trace!( "local {:?} can't be propagated because of multiple assignments", local, @@ -880,13 +891,22 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { } } } - if can_const_prop == ConstPropMode::OnlyPropagateInto - || can_const_prop == ConstPropMode::NoPropagation - { - trace!("can't propagate into {:?}", place); - if place.local != RETURN_PLACE { - Self::remove_const(&mut self.ecx, place.local); + match can_const_prop { + ConstPropMode::OnlyInsideOwnBlock => { + trace!( + "found local restricted to its block. \ + Will remove it from const-prop after block is finished. Local: {:?}", + place.local + ); + self.locals_of_current_block.insert(place.local); + } + ConstPropMode::OnlyPropagateInto | ConstPropMode::NoPropagation => { + trace!("can't propagate into {:?}", place); + if place.local != RETURN_PLACE { + Self::remove_const(&mut self.ecx, place.local); + } } + ConstPropMode::FullConstProp => {} } } else { // Const prop failed, so erase the destination, ensuring that whatever happens @@ -906,6 +926,12 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { ); Self::remove_const(&mut self.ecx, place.local); } + } else { + trace!( + "cannot propagate into {:?}, because the type of the local is generic.", + place, + ); + Self::remove_const(&mut self.ecx, place.local); } } else { match statement.kind { |
