Skip to content

Commit

Permalink
Fix double drops for conditionally dropped values
Browse files Browse the repository at this point in the history
When dropping a value conditionally, we didn't set the drop flag to
`false`, resulting in future checks potentially dropping the same value
again.

In addition, we didn't set the register state to "moved" in the block
_after_ the drop, resulting in a second check/drop being generated. We
have to set the state in the after block also, as this block will have
multiple predecessors and thus treat the register state as "maybe moved"
instead of "moved".

This fixes #560.

Changelog: fixed
  • Loading branch information
yorickpeterse committed May 29, 2023
1 parent c21c4b7 commit dd2f93f
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions compiler/src/mir/passes.rs
Expand Up @@ -3876,9 +3876,16 @@ impl<'a> LowerMethod<'a> {

self.current_block = drop_block;

self.current_block_mut().false_literal(drop_flag, location);
self.unconditional_drop_register(register, location);

self.current_block = after_block;

// Successor blocks may still try to drop the register as the next
// successor will have two ancestors (the before and drop blocks),
// but this is redundant because we just dropped it, so we also mark
// it as moved here.
self.mark_register_as_moved(register);
} else {
self.unconditional_drop_register(register, location);
}
Expand Down Expand Up @@ -3922,9 +3929,11 @@ impl<'a> LowerMethod<'a> {

self.current_block = drop_block;

self.current_block_mut().false_literal(drop_flag, location);
self.unconditional_drop_field(receiver, field, register, location);

self.current_block = after_block;
self.mark_register_as_moved(register);
} else {
self.unconditional_drop_field(receiver, field, register, location);
}
Expand Down

0 comments on commit dd2f93f

Please sign in to comment.