[move-only] Perform an exclusive borrow when passing a var to a consuming var. #63591
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Consider the following example:
In this case, we want to have an exclusivity violation. Before this patch, we did a by-value load [copy] of y and then performed the inout access. Since the access scopes did not overlap, we would not get an exclusivity violation. Additionally, since the checker assumes that exclusivity violations will be caught in such a situation, we convert the load [copy] to a load [take] causing a later memory lifetime violation as seen in the following SIL:
Now, instead we create a [consume] access and get the nice exclusivity error we are looking for.
NOTE: As part of this I needed to tweak the verifier so that [deinit] accesses are now allowed to have any form of access enforcement before we are in LoweredSIL. I left in the original verifier error in LoweredSIL and additionally left in the original error in IRGen. The reason why I am doing this is that I need the deinit access to represent semantically what consuming from a ref_element_addr, global, or escaping mutable var look like at the SIL level so that the move checker can error upon it. Since we will error upon such consumptions in Canonical SIL, such code patterns will never actually hit Lowered/IRGen SIL, so it is safe to do so (and the verifier/errors will help us if we make any mistakes). In the case of a non-escaping var though, we will be able to use deinit statically and the move checker will make sure that it is not reused before it is reinitialized.
rdar://101767439