-
Notifications
You must be signed in to change notification settings - Fork 186
Add discussion of global actor isolation inference. [SE-0316] #371
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
base: main
Are you sure you want to change the base?
Conversation
This change adds documentation for isolation inference from class inheritance, overridden methods, and protocol conformances.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made some suggestions for reframing the sentences to use active voice to make it clear the compiler is the bit doing the inferring in these scenarios. Structurally, this introduces 3 patterns to look for - the 3rd being a "contextual" - but I wasn't super clear on how that tied into the 2 subheadings beneath.
And I asked a couple questions in the review about the logic and what was possible that didn't seem entirely spelled out to me, but I may be misunderstanding.
If a superclass is isolated to a global actor, the global actor is | ||
inferred on subclasses. For example, the code below has a main-actor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a superclass is isolated to a global actor, the global actor is | |
inferred on subclasses. For example, the code below has a main-actor | |
If a superclass is isolated to a global actor, the compiler infers global actor isolation for its subclasses. | |
For example, the code below has a main-actor |
Reframing to active voice - "the compiler" doing the inferring.
Global actor isolation is also inferred from individual overridden | ||
methods. For example, the following code isolates one method of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Global actor isolation is also inferred from individual overridden | |
methods. For example, the following code isolates one method of the | |
The compiler also infers global actor isolation on methods a subclass overrides. | |
For example, the following code isolates one method of the |
Reframing to active voice - "the compiler" doing the inferring.
I know we're in the section on global actors, but a question - If the super class method is declared nonisolated
- does that also flow down to the overridden method? Can the developer choose another isolation method for the override?
Now, the `Switch` type itself does not have inferred isolation. The | ||
`toggle` method inside `Switch` is isolated to the main actor, because | ||
the protocol requirement that it implements is isolated to the main actor. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now, the `Switch` type itself does not have inferred isolation. The | |
`toggle` method inside `Switch` is isolated to the main actor, because | |
the protocol requirement that it implements is isolated to the main actor. | |
The `Switch` type itself does not have inferred isolation. The | |
`toggle` method inside `Switch` is isolated to the main actor, because | |
the protocol requirement that it implements is isolated to the main actor. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is so helpful, thank you! I have some questions below.
} | ||
``` | ||
|
||
In the above example, `Togglable` and all of its requirements |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first example says “Vehicle and all of its methods and properties are isolated to the main actor”. This one says “all of its requirements”. After reading the next example, I think (?) that all of Switch’s methods and properties are also isolated to the main actor? Is that right? If so I find the first wording very helpful and clearer and I think it would help to use it here as well. If not, perhaps that fact could be made clearer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used the language "methods and properties" when talking about concrete types and "requirements" when talking about protocols. But you're right that I should state that when @MainActor
is inferred on Switch
, all of its methods and properties become isolated to the main actor too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, yeah I think that’s really helpful because it’s changing more than just the requirements.
|
||
extension Switch: Togglable { | ||
mutating func toggle() { | ||
isOn.toggle() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this example the function toggle
is isolated to the main actor but isOn
is not isolated to the main actor, is it? And if that’s the case, isn’t it not allowed to use it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this example, isOn
is nonisolated
, which is fine to access from a main actor isolated method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, is that because you can only access the toggle function if your Switch is currently living in the main actor and thus any access to isOn would necessarily be on the main actor as well? I always forget about that. Very cool.
is the subject performing inference.
I also think there's a meta discussion about whether inference rules belong in the Language Guide. I think we are long over due for a section in the Language Reference on concurrency, and we'll need that regardless of whether we want this change in the guide. I am happy to start working on a concurrency and data-race safety chapter for the Language Reference! If you have thoughts on this, I'd love to hear them: https://forums.swift.org/t/rfc-documentation-for-isolation-inference-from-classes-and-protocols-se-0316/80343/3 |
mutating func toggle() | ||
} | ||
|
||
struct Switch: Togglable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this shouldn’t have Togglable here right? Just in the extension?
struct Switch: Togglable { | |
struct Switch { |
|
||
extension Switch: Togglable { | ||
mutating func toggle() { | ||
isOn.toggle() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, is that because you can only access the toggle function if your Switch is currently living in the main actor and thus any access to isOn would necessarily be on the main actor as well? I always forget about that. Very cool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One sentence felt really odd to read, so I made a suggestion, but otherwise the changes for active voice were super useful to me. Thank you!
If a superclass has global actor isolation, Swift infers that global actor | ||
on subclasses. For example, the code below has a main-actor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a superclass has global actor isolation, Swift infers that global actor | |
on subclasses. For example, the code below has a main-actor | |
If a superclass has global actor isolation, Swift infers the global actor isolation applies to subclasses. | |
For example, the code below has a main-actor |
I found the sentence a little awkward to read, and I think this aligns with what you're saying. Please double check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: "...infers that the global actor isolation applies to subclasses..." or "...infers the global actor isolation to apply to subclasses..."
This change adds documentation for isolation inference from class inheritance, overridden methods, and protocol conformances.
These rules are buried in old proposal documents, and they deserve documentation in TSPL, especially because they can be difficult to reason about. These rules were originally added in SE-0316.
This does not cover all cases of actor isolation inference; the rules for isolation inference of closures needs to be covered, but I think that belongs in the
Sendable
section because it's based on whether or not a closure type can be called from outside the current concurrency context.I started an RFC thread on the forums about this change here: https://forums.swift.org/t/rfc-documentation-for-isolation-inference-from-classes-and-protocols-se-0316/80343.