This is largely a matter of changing the main loop over subst
params in TranslateArguments to use the generators I added,
then plugging back into the general reabstraction infrastructure.
Because we don't have pack coroutines, we're kind of stuck in
the code generation for pack reabstraction: we have to write
+1 r-values into a temporary tuple and then write those tuple
element addresses into the output pack. It's not great. We
also have lifetime problems with things like non-escaping
closures --- we have that problem outside of reabstraction
thunks, too.
Other than that glaring problem, I'm feeling relatively good
about the code here. It's missing some peepholes, but it should
work. But that that's not to say that arity reabstraction works
in general; my attempts to test it have been exposing some
problems elsewhere, and in particular the closure case crashes,
which is really bad. But this gets a few more things working,
and this PR is quite large already.
- SILPackType carries whether the elements are stored directly
in the pack, which we're not currently using in the lowering,
but it's probably something we'll want in the final ABI.
Having this also makes it clear that we're doing the right
thing with substitution and element lowering. I also toyed
with making this a scalar type, which made it necessary in
various places, although eventually I pulled back to the
design where we always use packs as addresses.
- Pack boundaries are a core ABI concept, so the lowering has
to wrap parameter pack expansions up as packs. There are huge
unimplemented holes here where the abstraction pattern will
need to tell us how many elements to gather into the pack,
but a naive approach is good enough to get things off the
ground.
- Pack conventions are related to the existing parameter and
result conventions, but they're different on enough grounds
that they deserve to be separated.
This attribute indicates that the given SILFunction has to be
added to "accessible functions" section and could be looked up
at runtime using a special API.
When opaque values are enabled, when yielding a value with an indirect
convention, a value whose type's category is "object" must be yielded.
Previously, if a value's type was loadable, an attempt was made to yield
a value whose type's category was "address". Here, that's fixed.
Additionally, handling for trivial types yielded via @in_guaranteed is
added.
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`
The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.
rdar://102362022
These still get verified as part of SILGenModule's verification during
SILGenModule's destructor. But moving this earlier catches the error earlier and
makes it easier to debug any SIL issues immediately in the debugger rather than
having to backtrack from the SILGenModule's destructor.
A function can be actor instance-isolated to one of its parameters.
Make sure that this is reflected in ActorIsolation, so such a function
doesn't get a different actor isolation.
These will never appear in the source language, but can arise
after substitution when the original type is a tuple type with
a pack expansion type.
Two examples:
- original type: (Int, T...), substitution T := {}
- original type: (T...), substitution T := {Int}
We need to model these correctly to maintain invariants.
Callers that previously used to rely on TupleType::get()
returning a ParenType now explicitly check for the one-element
case instead.
Andy some time ago already created the new API but didn't go through and update
the old occurences. I did that in this PR and then deprecated the old API. The
tree is clean, so I could just remove it, but I decided to be nicer to
downstream people by deprecating it first.
[Distributed] generic and inner test; without one edge case
[Distributed] fix distributed_thunk test; unsure about those extra hops, could remove later
[Distributed] Remove type pretending in getSILFunctionType; it is not needed
It seems our constant replacement in the earlier phases is enough, and
we don't need this trick at all.
[Distributed] Use thunk when calling cross-actor on DA protocols
When referring to a `@preconcurrency` function as a value, use the normal
type for the initial declaration reference and then introduce an
appropriate function conversion expression to the adjusted type.
Fixes more issues related to rdar://94597323.
When a distributed-actor-isolated witness is provided for a
non-distributed-actor-isolated requirement, always hop to the
distributed thunk.
While here, mark distributed thunks as being `final`, to ensure that
we always statically call them vs. trying to retrieve them from the
vtable (since they aren't in the vtable).
When a synchronous, actor-isolated declaration witnesses an
asynchronous, not-similarly-isolated requirement, emit an actor hop
within the witness thunk to ensure that we properly enter the context
of the actor.
Fixes#58517 / rdar://92881539.
This ensures that opened archetypes always inherit any outer generic parameters from the context in which they reside. This matters because class bounds may bind generic parameters from these outer contexts, and without the outer context you can wind up with ill-formed generic environments like
<τ_0_0, where τ_0_0 : C<T>, τ_0_0 : P>
Where T is otherwise unbound because there is no entry for it among the generic parameters of the environment's associated generic signature.
Clients can explicitly ask for the opened existential type on the archetype's generic environment,
or use `getExistentialType` to obtain a specific archetype's upper bounds.
Async functions are now expected to set ExpectedExecutor in their
prologue (and, generally, immediately hop to it). I updated the
prologue code for a bunch of function emission, most of which was
uninteresting. Top-level code was not returning to the main
executor, which is now fixed; fortunately, we weren't assuming
that we were on the main executor yet.
We had some code that only kicked in when an ExpectedExecutor
wasn't set which made us capture the current executor before
a hop and then return to it later. This code has been removed;
there's no situation in which save-and-return is the semantically
correct thing to do given the possibility of hop optimization.
I suspect it could also have led to crashes if the current
executor is being kept alive only because it's currently running
code. If we ever add async functions that are supposed to inherit
their caller's executor, we should have the caller pass the right
executor down to it.
This is the first half of SE-0338; the second, sendability
enforcement, is much more complicated, and Doug has volunteered
to do it.
Fixes rdar://79284465, as well as some tests that were XFAILed
on Windows.
There are three major changes here:
1. The addition of "SILFunctionTypeRepresentation::CXXMethod".
2. C++ methods are imported with their members *last*. Then the arguments are switched when emitting the IR for an application of the function.
3. Clang decls are now marked as foreign witnesses.
These are all steps towards being able to have C++ protocol conformance.
This cleans up 90 instances of this warning and reduces the build spew
when building on Linux. This helps identify actual issues when
building which can get lost in the stream of warning messages. It also
helps restore the ability to build the compiler with gcc.