Skip to content

Forwarding force unwrap 6.0 #73545

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

jckarter
Copy link
Contributor

@jckarter jckarter commented May 9, 2024

(includes #73411 as a prerequisite)

Explanation: Changes the handling of the x! force unwrap operator on Optional to be any of borrowing, consuming, or mutating based on the use of the unwrapped value.
Scope: Noncopyable stdlib adoption work.
Issue: rdar://127459955
Original PR: #73531
Risk: Low. The change only affects the ! operator and should be a safe extension of its behavior for noncopyable Optionals.
Testing: Swift CI, test case from bug report
Reviewer: @kavon

@jckarter jckarter requested a review from a team as a code owner May 9, 2024 19:28
@jckarter
Copy link
Contributor Author

jckarter commented May 9, 2024

@swift-ci Please test

fatalError("bah!") // expected-error {{must consume 'self' before exiting method that discards self}}
return // expected-error {{must consume 'self' before exiting method that discards self}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious why you needed to change these tests? I assume this fix revealed a bug in pruned liveness that the discard checking relied on w.r.t. unreachable blocks?

Copy link
Contributor Author

@jckarter jckarter May 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests appear to previously be testing that an unreachable call like fatalError is treated as a function exit, which is wrong—fatalError never returns, and so the calling function is never really exited either. I needed to fix this because every force-unwrap introduces a branch with a trap and unreachable on the nil path, and if move checking tries to treat this as an exit, it will try to insert cleanups on the unreachable branch, which may not be valid because other cleanups on dependent accesses might still be active and we don't generally try to clean up on crash paths.

Since these tests are still exercising interesting combinations of control flow, I changed them to have a real function return instead of a trap so that the tests still provide coverage.

Like `?` or property access, `x!` can be borrowing, consuming, or mutated
through depending on the use site and the ownership of the base value.
Alter SILGen to emit `x!` as a borrowing operation when the result is only
used as a borrow. Fix the move-only checker not to treat the unreachable
branch as a dead path for values and try to destroy the value unnecessarily
and possibly out-of-order with cleanups on the value. Fixes rdar://127459955.
@jckarter jckarter force-pushed the forwarding-force-unwrap-6.0 branch from 1839a8b to ae767da Compare May 13, 2024 21:40
@jckarter
Copy link
Contributor Author

@swift-ci Please test

@jckarter
Copy link
Contributor Author

@swift-ci Please test Windows

@jckarter jckarter merged commit f42d619 into swiftlang:release/6.0 May 14, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants