This includes a bunch of fixes. It is not exhaustive but fit my time boxed time
period I set aside to look at this today.
A quick non-exhaustive list:
1. I removed unnecessary verify-additional-prefix lines.
2. Split tests with typechecker error and non-typechecker error components.
3. Removed complete- lines that we used when testing w/without send
non sednable.
4. Translated complete-and-tns- lines to be just complete- since they are just
testing strict-concurrency=complete and we are not testing complete without
send non sendable anymore.
Replaces generic `expression is 'async' but is not marked with 'await`
diagnostic with a tailed one for cases where there is an access to an
actor-isolated value outside of its actor without `await` keyword.
This makes the diagnostics for async and sync contexts consistent
and actually identifies a problem instead of simply pointing out
the solution.
Resolves: rdar://151720646
This matches send non sendable but importantly also makes it clear that we are
talking about something that doesn't conform to the Sendable protocol which is
capitalized.
rdar://151802975
This never belonged in ActorIsolationRequest since it fits perfectly in the
attribute checker. This also simplifies the logic before I add code to
getIsolationFromAttribute to handle ExecutionAttribute.
the async self-isolated actor initializer case.
Fixes rdar://138394497, a bug where we didn't set up isolation correctly for
an async parameter-isolated initializer, but also probably a non-trivial number
of other latent differences between initializers and normal functions.
Instead, use the `%target-swift-5.1-abi-triple` substitution to compile the tests
for deployment to the minimum OS versions required for use of _Concurrency APIs.
- Don't attempt to insert fixes if there are restrictions present, they'd inform the failures.
Inserting fixes too early doesn't help the solver because restriction matching logic would
record the same fixes.
- Adjust impact of the fixes.
Optional conversions shouldn't impact the score in any way because
they are not the source of the issue.
- Look through one level of optional when failure is related to optional injection.
The diagnostic is going to be about underlying type, so there is no reason to print
optional on right-hand side.
Specifically:
I changed the main error message to focus on the closure and that the closure
is being accessed concurrently.
If we find that we captured a value that is the actual isolation source, we
emit that the capture is actually actor isolated.
If the captured value is in the same region as the isolated value but is not
isolated, we instead say that the value is accessible from *-isolated code or
code within the current task.
If we find multiple captures and we do not which is the actual value that was
in the same region before we formed the partial apply, we just emit a note on
the captures saying that the closure captures the value.
I changed the diagnostics from using the phrase "task-isolated" to use some
variant of accessible to code in the current task.
The idea is that in all situations we provide a breadcrumb that the user can
start investigating rather than just saying that the closure is "task-isolated".
From a preconcurrency perspective, I made it so that we apply the preconcurrency
behavior of all of the captures. This means that if one of the captures is
preconcurrency, we apply the preconcurrency restriction to the closure. This is
one step towards making it so that preconcurrency applies at the region level...
we just are not completely there yet.
rdar://133798044
We are already using this routine in other parts of TransferNonSendable to
ensure that we look through common insts that SILGen inserts that do not change
the actual underlying actor instance that we are using. In this case, I added
support for casts, optional formation, optional extraction, existential ref
initialization.
As an example of where this came up is the following test case where we fail to
look through an init_existential_ref.
```swift
public actor MyActor {
private var intDict: [Int: Int] = [:]
public func test() async {
await withTaskGroup(of: Void.self) { taskGroup in
for (_, _) in intDict {}
await taskGroup.waitForAll() // Isolation merge failure happens here
}
}
}
```
I also added the ability to at the SIL level actual test out this merge
condition using the analysis test runner. I used this to validate that this
functionality works as expected in a precise way.
rdar://130113744
This marker protocol isn't useful for abstracting over actors and distributed
actors because it doesn't have any runtime requirements, so there's no way
to switch to the given actor. Instead, you should use `isolated (any Actor)?`
parameters, and the compiler will compute a local actor value from a
distributed actor using `DistributedActor.asLocalActor`.
I added a disable flag -disable-region-based-isolation-with-strict-concurrency
so that we do not need to update the current tests. It is only available when
asserts are enabled to ensure users cannot use it.
rdar://125918028
Not quite NFC because apparently the representation bleeds into what's
accepted in some situations where we're supposed to be warning about
conflicts and then making an arbitrary choice. But what we're doing
is nonsense, so we definitely need to break behavior here.
This is setting up for isolated(any) and isolated(caller). I tried
to keep that out of the patch as much as possible, though.
values.
Teach ActorIsolation that a `nil` isolated argument is statically nonisolated,
and a reference to GlobalActor.shared statically has global actor isolation.
This change also models arbitrary actor instance isolation using VarDecls
when possible, which allows comparing two ActorIsolation values that may
represent different actor instances. Previously, ActorIsolation was
modeled only by storing the nominal actor type and the parameter index,
so the actor isolation value for two different actors was considered
to be equal. Now, the nominal actor type is only used for isolated `self`
in cases where there is no implicit self parameter decl, such as for
stored properties.
We were missing a check for conformance to `Actor` or `DistributedActor`
when an isolated parameter's type is a generic parameter.
Previously, if you used a generic parameter constrained to just `AnyActor`,
you'd crash the compiler in LowerHopToExecutor because it doesn't know
how to obtain the executor for such a value. Since `AnyActor` has no
`unownedExecutor` requirement, there's no way to get the executor without
emitting code to do dynamic casts down to `Actor` or `DistributedActor`.
Rather than have the compiler silently emit dynamic casting, I figured
it's best to ban it. This forces people to either do the dynamic casts
themselves, or use one of the more specific types to constrain their
parameter.
For other generic parameters, we would silently treat the function
as though it is nonisolated (i.e., as if the `isolated` wasn't written
on the parameter at all).
resolves rdar://109059544
This means that:
1. In test cases where minimal is the default (swift 5 without
-warn-concurrency), I added RUN lines for targeted, complete, and complete +
sns.
2. In test cases where complete is the default (swift 6, -warn-concurrency,
specified complete with -strict-concurrency), I added a send non-sendable run
line.
In each of these cases, I added additional expected-* lines as appropriate so
the tests can compile in each mode successfully.
Isolation checking for calls had two separate implementation places:
one that looked at the declaration being called (for member
declarations) and one that worked on the actual call expression. Unify
on the latter implementation, which is more general and has access to
the specific call arguments. Improve diagnostics here somewher so we
don't regress in that area.
This refactoring shouldn't change the actual semantics, but it makes
upcoming semantic changes easier.
This covers function types, closures, and function declarations:
- only one `isolated` parameter
- no global-actor + `isolated` parameter
- no `nonisolated` + `isolated`.
all diagnostics are warnings until Swift 6