The thunk's parameter needs the @in_guaranteed convention if it's a
const reference parameter. However, that convention wasn't being used
because clang importer was removing the const reference from the
type and SILGen was computing the type of the parameter based on the
type without const reference.
This commit fixes the bug by passing the clang function type to
SILDeclRef so that it can be used to compute the correct thunk type.
This fixes a crash when a closure is passed to a C function taking a
pointer to a function that has a const reference struct parameter.
This recommits e074426 with fixes to
serialization/deserialization of function types. The fixes prevent clang
types of functions from being dropped during serialization.
rdar://131321096
In Embedded Swift, witness method lookup is done from specialized witness tables.
For this to work, the type of witness_method must be specialized as well.
Otherwise the method call would be done with wrong parameter conventions (indirect instead of direct).
This requires two major changes.
The first is that we need to teach SILGen that the isolation of an initializer
is essentially dynamic (as far as SILGen is concerned) --- that it needs to emit
code in order to get the isolation reference. To make this work, I needed to
refactor how we store the expected executor of a function so that it's not
always a constant value; instead, we'll need to emit code that DI will lower
properly. Fortunately, I can largely build on top of the work that Doug previously
did to support #isolation in these functions. The SIL we emit here around delegating
initializer calls is not ideal --- the breadcrumb hop ends up jumping to the
generic executor, and then DI actually emits the hop to the actor. This is a little
silly, but it's hard to eliminate without special-casing the self-rebinding, which
honestly we should consider rather than the weirdly global handling of that in
SILGen today. The optimizer should eliminate this hop pretty reliably, at least.
The second is that we need to teach DI to handle the pattern of code we get in
delegating initializers, where the builtin actually has to be passed the self var
rather than a class reference. This is because we don't *have* a class reference
that's consistently correct in these cases. This ended up being a fairly
straightforward generalization.
I also taught the hop_to_executor optimizer to skip over the initialization of
the default-actor header; there are a lot of simple cases where we still do emit
the prologue generic-executor hop, but at least the most trivial case is handled.
To do this better, we'd need to teach this bit of the optimizer that the properties
of self can be stored to in an initializer prior to the object having escaped, and
we don't have that information easily at hand, I think.
Fixes rdar://87485045.
For now this will only be used for HopToMainActorIfNeeded thunks. I am creating
this now since in the past there has only been one option for creating
thunks... to create the thunk in SILGen using SILGenThunk. This code is hard to
test and there is a lot of it. By using an instruction here we get a few benefits:
1. We decouple SILGen from needing to generate new kinds of thunks. This means
that SILGenThunk does not need to expand to handle more thunks.
2. All thunks implemented via ThunkInst will be easy to test in a decoupled way
with SIL tests.
3. Even though this stabilizes the patient, we still have many thunks in SILGen
and various parts of the compiler. Over time, we can swap to this model,
allowing us to hopefully eventually delete SILGenThunk.
As the optimizer uses more and more AST stuff, it's now time to create an "AST" module.
Initially it defines following AST datastructures:
* declarations: `Decl` + derived classes
* `Conformance`
* `SubstitutionMap`
* `Type` and `CanonicalType`
Some of those were already defined in the SIL module and are now moved to the AST module.
This change also cleans up a few things:
* proper definition of `NominalTypeDecl`-related APIs in `SIL.Type`
* rename `ProtocolConformance` to `Conformance`
* use `AST.Type`/`AST.CanonicalType` instead of `BridgedASTType` in SIL and the Optimizer
The thunk's parameter needs the @in_guaranteed convention if it's a
const reference parameter. However, that convention wasn't being used
because clang importer was removing the const reference from the
type and SILGen was computing the type of the parameter based on the
type without const reference.
This commit fixes the bug by passing the clang function type to
SILDeclRef so that it can be used to compute the correct thunk type.
This fixes a crash when a closure is passed to a C function taking a
pointer to a function that has a const reference struct parameter.
rdar://131321096
The main change here is to associate a witness table with a `ProtocolConformance` instead of a `RootProtocolConformance`.
A `ProtocolConformance` is the base class and can be a `RootProtocolConformance` or a `SpecializedProtocolConformance`.
* add missing APIs
* bridge the entries as values and not as pointers
* add lookup functions in `Context`
* make WitnessTable.Entry.Kind enum cases lower case
Motivated by need for protocol-based dynamic dispatch, which hasn't been possible in Embedded Swift due to a full ban on existentials. This lifts that restriction but only for class-bound existentials: Class-bound existentials are already (even in desktop Swift) much more lightweight than full existentials, as they don't need type metadata, their containers are typically 2 words only (reference + wtable pointer), don't incur copies (only retains+releases).
Included in this PR:
[x] Non-generic class-bound existentials, executable tests for those.
[x] Extension methods on protocols and using those from a class-bound existential.
[x] RuntimeEffects now differentiate between Existential and ExistentialClassBound.
[x] PerformanceDiagnostics don't flag ExistentialClassBound in Embedded Swift.
[x] WTables are generated in IRGen when needed.
Left for follow-up PRs:
[ ] Generic classes support
The reason why is that we want to distinguish inbetween SILFunction's that are
marked as unspecified by SILGen and those that are parsed from textual SIL that
do not have any specified isolation. This will make it easier to write nice
FileCheck tests against SILGen output on what is the inferred isolation for
various items.
NFCI.
The "buffer ID" in a SourceFile, which is used to find the source file's
contents in the SourceManager, has always been optional. However, the
effectively every SourceFile actually does have a buffer ID, and the
vast majority of accesses to this information dereference the optional
without checking.
Update the handful of call sites that provided `nullopt` as the buffer
ID to provide a proper buffer instead. These were mostly unit tests
and testing programs, with a few places that passed a never-empty
optional through to the SourceFile constructor.
Then, remove optionality from the representation and accessors. It is
now the case that every SourceFile has a buffer ID, simplying a bunch
of code.
The generality of the `AvailabilityContext` name made it seem like it
encapsulates more than it does. Really it just augments `VersionRange` with
additional set algebra operations that are useful for availability
computations. The `AvailabilityContext` name should be reserved for something
pulls together more than just a single version.
It is a way to indicate to the compiler that the line can't be reached.
On some configurations, it does happen to trap, as desired. Use a
function that always traps, since that's the intent.