Consider the following piece of code and what the isolation is of the closure
literal passed to doSomething():
```swift
func doSomething(_ f: sending () -> ()) { ... }
@MyCustomActor
func foo() async {
doSomething {
// What is the isolation here?
}
}
```
In this case, the isolation of the closure is @MyCustomActor. This is because
non-Sendable closures are by default isolated to their current context (in this
case @MyCustomActor since foo is @MyCustomActor isolated). This is a problem
since
1. Our closure is a synchronous function that does not have the ability to hop
to MyCustomActor to run said code. This could result in a concurrency hole
caused by running the closure in doSomething() without hopping to
MyCustomActor's executor.
2. In Region Based Isolation, a closure that is actor isolated cannot be sent,
so we would immediately hit a region isolation error.
To fix this issue, by default, if a closure literal is passed as a sending
parameter, we make its isolation nonisolated. This ensures that it is
disconnected and can be transferred safely.
In the case of an async closure literal, we follow the same semantics, but we
add an additional wrinkle: we keep support of inheritActorIsolation. If one
marks an async closure literal with inheritActorIsolation, we allow for it to be
passed as a sendable parameter since it is actually Sendable under the hood.
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
There are a number of implicit conversions in Swift, such as to Optional
and to an existential, which are now possible for noncopyable types.
But all type casts are consuming operations for noncopyable types. So
it's confusing when a function that takes a borrowed argument of
optional type appears to be consuming:
```
func f(_ x: borrowing NC?) { ... }
let x = NC()
f(x)
f(x) // error!
```
So, rather than for people to write `x as T?` around all implicit
conversions, require them to write `consume x` around expressions
that will consume some lvalue. Since that makes it much more clear what
the consequences will be.
Expressions like `f(g())`, where you're passing an rvalue to the callee,
are not confusing. And those are exactly the expressions you're not
allowed to write `consume` for, anyway.
fixes rdar://127450418
TLDR: This makes it so that we always can parse sending/transferring but changes
the semantic language effects to be keyed on RegionBasedIsolation instead.
----
The key thing that makes this all work is that I changed all of the "special"
semantic changes originally triggered on *ArgsAndResults to now be triggered
based on RegionBasedIsolation being enabled. This makes a lot of sense since we
want these semantic changes specifically to be combined with the checkers that
RegionBasedIsolation turns on. As a result, even though this causes these two
features to always be enabled, we just parse it but we do not use it for
anything semantically.
rdar://128961672
We still only parse transferring... but this sets us up for adding the new
'sending' syntax by first validating that this internal change does not mess up
the current transferring impl since we want both to keep working for now.
rdar://128216574
As we do with references to initializable local lets, teach the type
checker to produce ASTs where member references to initializable
instance property lets (e.g., within an initializer) treat the `let`
as an lvalue and then immediately load.
This modeling addresses a source compatibility issue uncovered in
swift-syntax, where code that *technically* has a
use-before-definition on a `let` property in an initializer wasn't
diagnosed as such because the loaded value wasn't actually used for
anything.
Stored `let` properties of a struct, class, or actor permit
'inout' modification within the constructor body after they have been
initialized. Tentatively remove this rule, only allowing such `let`
properties to be initialized (assigned to) and not treated as `inout`.
Fixes rdar://127258363.
The issue here was that we inferred the contextual type of the `Mixer` call to be the following, inferred from the result type of the partial call to the initializer of `Mixer`
```
(bound_generic_struct_type decl="swift_ide_test.(file).Mixer@/Users/alex/src/swift/test/IDE/complete_parameter_pack_as_call_argument.swift:3:8"
(pack_type num_elements=1
(pack_expansion_type
(pattern=unresolved_type)
(count=unresolved_type))))
```
Technically, the contextual type that we should have here should be `Any` (from `print`) but getting that information out of the constraint system turns out to be quite hard. https://github.com/apple/swift/pull/72568 makes some improvements in this area but in general the constraint system does not contain enough information to figure out the contextual type of an arbitrary expression.
The important thing right now is that the unresolved type in here trips the constraint system over when comparing types of code completion results with the contextual type. To prevent the crash for now, reset the expected call type if the computed type contains an unresolved type.
rdar://124166587
Co-authored-by: Pavel Yaskevich <pyaskevich@apple.com>
We were incorrectly unwrapping too many levels of metatype, and
our ErasureExpr would end up with conformances for the instance
type and not the metatype itself.
In the old universe, this was not a problem, but now Any has two
protocol conformance members, so suddently this violated invariants.
This was a regression, introduced in 6027bf46a6.
Fixes rdar://125460667.
Some notes:
1. If the result is non-Sendable and we didn't infer something that is
transferring, we still emit the current sema error that says that one cannot
assign a non-Sendable value to an async let.
2. When region isolation is enabled, but transferring args and results are
disabled, we leave the async let semantics alone. This means that the async let
closure is still @Sendable and one cannot pass in non-Sendable values to it.
In #39612 we added subtyping for keypaths-as-functions, but during application
the implementation naively coerced the keypath expression itself to the
inferred supertype, resulting in erroneous results. This patch updates the
solution application logic to build the keypath-function conversion expression
based entirely on the 'natural' keypath type, only converting to the inferred
supertype at the end via the usual coerceToType machinery for function
conversions.
This is going to be used to determine whether the substitutions are
computed for `DistributedActorSystem::remoteCall` and adjust the
generic signature with witness conformance requirements.
The IDE's use isn't correct under noncopyable generics and only the
constraint solver uses it. It's a misleading method now that nearly
every archetype has Copyable/Escapable requirements.
Unify with `CTP_ReturnStmt`, and have the
SyntacticElementTarget carry the ReturnStmt for
regular type-checking, which we can use to record
implied returns.
Track the implied result exprs in the constraint
system, and allow arbitrary propagation of
implied results down if/switch expression
branches. This is required for allowing implied
results in non-single-expression closures.
Passing an isolated function value into an API that doesn't have full
static concurrency checking is unsafe and requires runtime checks
to make sure that function is always called in the expected context.
Unify the implementation between single-expression
and multi-statement closures. Because we're now
storing a contextual type for single expression
closure returns, update a code completion test to
bring its behavior inline with the multi-statement
case.
`adjustSelfTypeForMember` shouldn't load base if member reference
is a potential init accessor use, the proper use of `self` would
be determined during lowering of the `assign_or_init` instruction
and defensive load for `nonmutating` sets is unnecessary in this
case.