The constraint solver does not reliably give closures a function type
that includes `nonisolated(noncaller)`, even when the immediate context
requires a conversion to such a type. We were trying to work around this
in SILGen, but the peephole only kicked in if the types matched exactly,
so a contextual conversion that e.g. added `throws` was still emitting
the closure as `@concurrent`, which is of course the wrong semantics.
It's relatively easy to avoid all this by just rewriting the closure's
type to include `nonisolated(nonsending)` at a point where we can reliably
decide that, and then SILGen doesn't have to peephole anything for
correctness.
Fixes rdar://155313349
`_openExistential` is type-checked in a special way which
means that we need to explicitly inject `nonisolated(nonsending)`
isolation when forming a reference to this builtin.
(cherry picked from commit 358869ff54)
`withoutActuallyEscaping` is type-checked in a special way which
means that we need to explicitly inject `nonisolated(nonsending)`
isolation when forming a reference to this builtin.
(cherry picked from commit 48f4d7b688)
The reason why this failed is that concurrently to @xedin landing
79af04ccc4, I enabled
NonisolatedNonsendingByDefault on a bunch of other tests. That change broke the
test and so we needed to fix it.
This commit fixes a few issues that were exposed:
1. We do not propagate nonisolated(nonsending) into a closure if its inferred
context isolation is global actor isolated or if the closure captures an
isolated parameter. We previously just always inferred
nonisolated(nonsending). Unfortunately since we do not yet have capture
information in CSApply, this required us to put the isolation change into
TypeCheckConcurrency.cpp and basically have function conversions of the form:
```
(function_conversion_expr type="nonisolated(nonsending) () async -> Void"
(closure_expr type="() async -> ()" isolated_to_caller_isolation))
```
Notice how we have a function conversion to nonisolated(nonsending) from a
closure expr that has an isolation that is isolated_to_caller.
2. With this in hand, we found that this pattern caused us to first thunk a
nonisolated(nonsending) function to an @concurrent function and then thunk that
back to nonisolated(nonsending), causing the final function to always be
concurrent. I put into SILGen a peephole that recognizes this pattern and emits
the correct code.
3. With that in hand, we found that we were emitting nonisolated(nonsending)
parameters for inheritActorContext functions. This was then fixed by @xedin in
With all this in hand, closure literal isolation and all of the other RBI tests
with nonisolated(nonsending) enabled pass.
rdar://154969621
(cherry picked from commit 648bb8fe30)
Currently only declarations would get `nonisolated(nonsending)`
inferred if the upcoming flag is enabled, this changes extend
this to apply to asynchronous nonisolated function types as well.
Resolves: rdar://154808850
(cherry picked from commit bb0cd6f0a6)