Use the lvalue mechanism to build opaque formal accesses so that they
nest properly with writebacks. Don't put a cleanup on the lvalue because
that creates a double destroy. Fixes rdar://124362085.
All non-trivial values which correspond to `VarDecl`s must be marked
appropriately so that they can be found by the relevant checker. Here,
values with none ownership are marked.
Suppose you have an exhaustive switch statement which matches all the cases of
a Swift enum defined in a different module named `External`:
```
import External
var e: External.SomeEnum = //...
switch e {
case .a: break
}
```
If `External` is compiled with library evolution and `SomeEnum` is not frozen,
then the compiler will warn:
```
warning: switch covers known cases, but 'SomeEnum' may have additional unknown values
```
You add an `@unknown default` to the switch to resolve this warning. Now
suppose in another build configuration, `External` is built _without_ library
evolution. The compiler will complain about the unreachability of the default
case:
```
warning: Default will never be executed
```
These contradictory compiler diagnostics encourage the developer to change the
code in a way that will cause a diagnostic in the other configuration.
Developers should have the tools to address all warning diagnostics in a
reasonable fashion and this is a case where the compiler makes that especially
difficult. Given that writing `@unknown default` instead of `default` is a very
intentional action that would be the result of addressing the library evolution
configuration, it seems reasonable to suppress the `Default will never be
executed` diagnostic.
We've been building up this exponential explosion of task-creation
builtins because it's not currently possible to overload builtins.
As long as all of the operands are scalar, though, it's pretty easy
to peephole optional injections in IRGen, which means we can at
least just use a single builtin in SIL and then break it apart in
IRGen to decide which options to set.
I also eliminated the metadata argument, which can easily be recreated
from the substitutions. I also added proper verification for the builtin,
which required (1) getting `@Sendable` right more consistently and (2)
updating a bunch of tests checking for things that are not actually
valid, like passing a function that returns an Int directly.
First, and I really should've checked this, but global actors do not
require `shared` to return `Self`; adjust the logic to propagate the
right formal type to the erasure logic.
Second, handle attempts to erase the isolation of something isolated to
a distributed actor using the magic Actor conformance that Doug added.
This only works when the actor is local, but it shouldn't be difficult to
enforce that we only attempt to erase isolation what that's true --- we
need to prevent partial application of distributed actors, and we need to
disallow explicit isolated captures of distributed actors when we're not
currently isolated to it. Otherwise, it's not possible to get an
@isolated(any) function value with an isolation that isn't the current
function's isolation, which means it always has to be local.
Fixed rdar://123734019
If the value being moved was a trivial value of a nontrivial type (like nil
for Optional<T>) then the lifetime checker would complain that there was
no `destroy_value` ending the consumed value's lifetime. Partial fix
for #71608.
For years, optimizer engineers have been hitting a common bug caused by passes
assuming all SILValues have a parent function only to be surprised by SILUndef.
Generally we see SILUndef not that often so we see this come up later in
testing. This patch eliminates that problem by making SILUndef uniqued at the
function level instead of the module level. This ensures that it makes sense for
SILUndef to have a parent function, eliminating this possibility since we can
define an API to get its parent function.
rdar://123484595
We do this by pushing the conversion down to the emission of the
closure expression, then teaching closure emission to apply the isolation
to the closure. Ideally, we combine the isolation along with the rest of
the conversion peephole, but if necessary, we make sure we emit the
isolation.
Following up from #71795, we must borrow the base of any non-copyable
`borrowing`/`nonmutating` accessor, and we want to borrow the base
of any accessor appearing in a `borrow` expr. Fixes#71606.
a closure expression, then don't actually do it. The long term plan is
to actually do this, which should just be a matter of taking some of the
code out of reabstraction thunk emission and using it in prolog/epilog/return
emission. In the short term, the goal is just to get the conversion
information down to the closure emitter so that we can see that we're
erasing into an `@isolated(any)` type and then actually erase the
closure's isolation properly instead of relying on type-based erasure,
which can't handle parameter/capture isolation correctly.
It's not thread safe and can cause false alarms in case multiple modules exist in different threads. E.g. when building swiftmodules from interfaces.
The leaking check is not important anymore because the builder APIs enforce that instructions are not leaking.
I.e. it's not possible to create an instruction without inserting it into a basic block. Also, it's not possible to remove an instruction from a block without deleting it.
rdar://122169263
We want to preserve the borrow scope during switch dispatch so that move-only
checking doesn't try to analyze destructures or consumes out of it. SILGen
should mark anywhere that's a potential possibility with its own marker so that
it gets borrow checked independently.