Attempting to conform an actor to a global actor isolated protocol
creates a clash in isolation when members are accessed so, let's
detect and diagnose that.
Resolves: rdar://75849035
Actor inheritance was removed in the second revision of SE-0306. Remove
the ability to inherit actors.
Note that this doesn't fully eliminate all vestigates of inheritance
from actors. There are simplifications that need to be performed
still, e.g., there's no need to distinguish
designated/convenience/required initializers. That will follow.
This new attribute can be used on parameters of `@Sendable async` type
to indicate that the closures arguments passed to such parameters
should inherit the actor context where they are formed, which is not
the normal behavior for `@Sendable` closures.
Another part of rdar://76927008.
Updated the tests for non-global-actor protected deinit.
We can't access main-actor synchronous functions, main-actor static
properties, but can access non-static main-actor stored properties in
the deinit.
Check actor isolation of calls to functions with global-actor-qualified
type. This closes a pre-existing loophole where a value of
global-actor-qualified function type could be called from any context.
Paired with this, references to global-actor-qualified function
declarations will get global-actor-qualified function type whenever
they are referenced within an experience, i.e., whenever we form a
value of that type. Such references can occur anywhere (one does not
need to be on the actor), and carrying the global actor along with the
function type ensures that they can only be called from the right
actor. For example:
@MainActor func onlyOnMainActor() { ... }
func callIt(_ fn: @MainActor () -> Void) {
fn() // error: not on the main actor, so cannot synchronously call
// this wasn't previously diagnosed
}
func passIt() {
callIt(onlyOnMainActor) // okay to pass the function
// used to be an error
}
While here, fix up some broken substitution logic for
global-actor-qualified function types and "override" actor isolation.
This allows programs to target older OSes while using Concurrency behind an availability check. When targeting older OSes, the symbols are weak-linked and the compiler will require the use of Concurrency features to be guarded by an availability check.
rdar://75850003
Remove the heuristic that escaping closures cannot be actor-isolated.
This is in line with the long term plan for actor isolation, but opens
up some holes in the short term because Sendable closures are not enforced
throughout the Swift ecosystem.
One significant effect of this change is that we will now, statically,
fail to detect many cases where actor isolation can be broken.
Rather than restricting inference of global actors to instance members,
as we do for actor types, infer global actors for all value members,
which also includes static variables and methods, initializers, and
destructors.
Initializers within a global-actor-isolated type are not inferred to
be global-actor-isolated themselves, because that isn't generally what
one wants: usually, you want to be able to create an instance of
the type by calling the initializer from somewhere.
Within such initializers, allow access to the stored properties on
"self" regardless.
Fixes rdar://75450300.
The Actor protocol is used only to describe actors. When a protocol's
Self type conforms to the actor protocol, any instance declarations on
the protocol or extensions thereof are considered to be actor-isolated
to 'self'.
Because the instance requirements of such a protocol are
actor-isolated to 'self', they can be witnessed by actor-isolated
instance declarations on an actor type. For example:
```swift
protocol P: Actor {
func f() // okay, actor-isolated to self
}
extension P {
func g() { f() } // okay, actor-islated to self
}
actor MyActor: P {
func f() { } // okay, witnesses actor-isolated requirement
}
```
when an expression that would be validly considered implicitly-async appears
within a sync context, we try to be a bit more specific about the problem
being that it's a sync context.
We now mark some DeclRefExpr and LookupExprs as implicitly async
during typechecking, depending on whether they appear in a context
that is only performing a read / get operation, and whether they
are cross-actor operations.
also resolves rdar://72403401 by improving the error messages
(no more vague "'await' in async context" when its clearly a call!)
We weren't allowing implicit "async" promotions for cross-actor references
from functions defined within an actor that were @actorIndependent
or part of a global actor. Ensure we do promotion there.
... and because these lead to misleading diagnostics in a lot of places,
don't do implicit "async" promotion if we're not in an async context
already. We still need to improve the diagnostics here.
The declaration context of an explicitly-captured value is the context
of the original, captured declaration itself... not the closure in which
the value is captured. Account for this in data race checking, by tracking
the effective capture context for such variables. This eliminates some
erroneous complains about accesses to explicitly-captured variables in
concurrent code.
Part of rdar://74281361.
Allow an asynchronous closure to be annotated with a global actor,
which isolates it to that actor. For example:
```swift
Task.runDetached { @MainActor in
// runs on main actor
}
```
The actor isolation checker wasn't checking that tap expressions weren't
incorrectly using actor-isolated state. As a result, we could read actor
isolated state anywhere we wanted to. This was most prominent in string
interpolations.
We're not quite ready to commit to the flow-sensitive check that would
allow a concurrent function to read from a mutable local capture so
long as the captured variable wasn't changed after the point of
capture. Put it behind a flag and implement the more restrictive rule
(no access to mutable local captures in concurrent code). We can relax
it later.
This patch updates the `actor class` spelling to `actor` in almost all
of the tests. There are places where I verify that we sanely handle
`actor` as an attribute though. These include:
- test/decl/class/actor/basic.swift
- test/decl/protocol/special/Actor.swift
- test/SourceKit/CursorInfo/cursor_info_concurrency.swift
- test/attr/attr_objc_async.swift
- test/ModuleInterface/actor_protocol.swift
Initializers are actor-isolated when they are part of an actor or have
a global actor. However, uses of actor initializers need to be treated
as cross-actor references so we proper `ConcurrentValue` checking for
values passed into the initializer.
Fixes rdar://74064751.
Replace the existing warning about any access to a local variable from
concurrently-executing code with a more tailored error:
concurrently-executing code may read a mutable varable, but cannot
modify it. This is safe so long as we either always do by-value
captures in concurrent closures or we ensure that no mutation of that
variable can occur after the point of capture.
We'll follow up with one of those. For now... be careful out there.
Since we're promoting this to an error, narrow it down to concurrent
closures and local functions, dropping the assumption that escaping
closures "may execute concurrently."
Concurrent functions need to be actor-independent because they wouldn't
ever be safe to run concurrently while isolated on an actor. This
allows us to elimate the "may execute concurrently with" check related
to actor isolation, which is a cleaner overall story.
Make sure that we check the isolation of the context in which a reference
to `self` is made, rather than the context in which `self` is declared,
when checking whether we are within actor-isolated code. This ensures
that we report errors as actor-isolation errors rather than falling
back to the "may execute concurrently with" checking.