Rollup merge of #107271 - Zeegomo:drop-rmw, r=oli-obk

Treat Drop as a rmw operation

Previously, a Drop terminator was considered a move in MIR. This commit changes the behavior to only treat Drop as a mutable access to the dropped place.

In order for this change to be correct, we need to guarantee that

1.  A dropped value won't be used again
   2.  Places that appear in a drop won't be used again before a
     subsequent initialization.

We can ensure this to be correct at MIR construction because Drop will only be emitted when a variable goes out of scope, thus having:
*   (1) as there is no way of reaching the old value. drop-elaboration
     will also remove any uninitialized drop.
 * (2) as the place can't be named following the end of the scope.

However, the initialization status, previously tracked by moves, should also be tied to the execution of a Drop, hence the additional logic in the dataflow analyses.

From discussion in [this thread](https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/.60DROP.60.20to.20.60DROP_IF.60.20compiler-team.23558), originating from https://github.com/rust-lang/compiler-team/issues/558.
See also https://github.com/rust-lang/rust/pull/104488#discussion_r1085556010
This commit is contained in:
Matthias Krüger 2023-02-08 18:32:41 +01:00 committed by GitHub
commit 05748c66a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 9 deletions

View file

@ -376,7 +376,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
| TerminatorKind::Resume
| TerminatorKind::Abort
| TerminatorKind::GeneratorDrop
| TerminatorKind::Unreachable => {}
| TerminatorKind::Unreachable
| TerminatorKind::Drop { .. } => {}
TerminatorKind::Assert { ref cond, .. } => {
self.gather_operand(cond);
@ -391,10 +392,6 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
self.create_move_path(place);
self.gather_init(place.as_ref(), InitKind::Deep);
}
TerminatorKind::Drop { place, target: _, unwind: _ } => {
self.gather_move(place);
}
TerminatorKind::DropAndReplace { place, ref value, .. } => {
self.create_move_path(place);
self.gather_operand(value);