-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[6.2] Allow passing MutableSpan 'inout' without an experimental feature. #81657
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@swift-ci test |
This adds a new lifetime inference rule, loosening the requirement for @Lifetime annotations even when the experimental LifetimeDependence mode is enabled. Additionally, it enables this new inference rule even when the experimental mode is disabled. All other inference rules continue to require the experimental feature. The rule is: If a function or method has a single inout non-Escapable parameter other than 'self' and has no other non-Escapable parameters including 'self', then infer a single @Lifetime(copy) dependency on the inout parameter from its own incoming value. This supports the common case in which the user of a non-Escapable type, such as MutableSpan, wants to modify the span's contents without modifying the span value itself. It should be possible to use MutableSpan this way without requiring any knowledge of lifetime annotations. The tradeoff is that it makes authoring non-Escapable types less safe. For example, a MutableSpan method could update the underlying unsafe pointer and forget to declare a dependence on the incoming pointer. Disallowing other non-Escapable parameters rules out the easy mistake of programmers attempting to trivially reassign the inout parameter. There's is no way to rule out the possibility that they derive another non-Escapable value from an Escapable parameteter. So users can still write the following: func reassign(s: inout MutableSpan<Int>, a: [Int]) { s = a.mutableSpan } The 'reassign' declaration will type check, but it's implementation will diagnose a lifetime error on 's'. Fixes rdar://150557314 ([nonescapable] Declaration of inout MutableSpan parameter requires LifetimeDependence experimental feature) (cherry picked from commit dbcba01)
When reporting the declarations that lead to a cycle, we end up printing an extra "through reference here" on the function declaration: class C2: C1, P { | |- note: through reference here | `- note: through reference here 15 | // expected-note@-1 2{{through reference here}} 16 | override func run(a: A) {} | | | `- note: while resolving type 'A' | | `- note: through reference here | |- error: circular reference | |- note: through reference here | `- note: through reference here (cherry picked from commit b71cc44)
Evaluating LifetimeDependence changes the order that the declarations are diagnosed. Fix this test output by flipping the order of two declarations. The new order actually makes more sense to me. (cherry picked from commit c40fd2a)
6afec87
to
818b38b
Compare
@swift-ci test |
tbkka
approved these changes
May 21, 2025
Windows: |
@swift-ci test windows |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
This adds a new lifetime inference rule, loosening the requirement for @Lifetime
annotations even when the experimental LifetimeDependence mode is
enabled. Additionally, it enables this new inference rule even when the
experimental mode is disabled. All other inference rules continue to require the
experimental feature. The rule is:
If a function or method has a single inout non-Escapable parameter other than
'self' and has no other non-Escapable parameters including 'self', then infer a
single @Lifetime(copy) dependency on the inout parameter from its own incoming
value.
This supports the common case in which the user of a non-Escapable type,
such as MutableSpan, wants to modify the span's contents without modifying
the span value itself. It should be possible to use MutableSpan this way
without requiring any knowledge of lifetime annotations. The tradeoff is
that it makes authoring non-Escapable types less safe. For example, a
MutableSpan method could update the underlying unsafe pointer and forget to
declare a dependence on the incoming pointer.
Disallowing other non-Escapable parameters rules out the easy mistake of
programmers attempting to trivially reassign the inout parameter. There's
is no way to rule out the possibility that they derive another
non-Escapable value from an Escapable parameteter. So users can still write
the following:
The 'reassign' declaration will type check, but it's implementation will
diagnose a lifetime error on 's'.
Fixes rdar://150557314 ([nonescapable] Declaration of inout MutableSpan
parameter requires LifetimeDependence experimental feature)
(cherry picked from commit dbcba01)
main PR: #81656
--- CCC ---
Explanation: Enable limited lifetime inference when the experimental LifetimeDependence feature is disabled. This is necessary for MutableSpan usability. Otherwise, it is impossible to pass the mutable span into a function and mutate its elements!
Radar/SR Issue: rdar://150557314 ([nonescapable] Declaration of inout MutableSpan
parameter requires LifetimeDependence experimental feature)
main PR: #81656
Risks: (1) this runs a small amount of type checking code now by default that was previously guarded by a feature flag. This only affects usage od
~Escapable
types. (2) this triggers the declaration checker in an arbitrarily different order which can slightly change the diagnostic output for invalid declarations.Testing: I added unit tests for both pass and fail diagnostics both with and without the exerimental feature.
Reviewer: Doug Gregor