When a method is called with fewer than two parameter lists,
transform it into a fully-applied call by wrapping it in a
closure.
Eg,
Foo.bar => { self in { args... self.bar(args...) } }
foo.bar => { self in { args... self.bar(args...) } }(self)
super.bar => { args... in super.bar(args...) }
With this change, SILGen only ever sees fully-applied calls,
which will allow ripping out some code.
This new way of doing curry thunks fixes a long-standing bug
where unbound references to protocol methods did not work.
This is because such a reference must open the existential
*inside* the closure, after 'self' has been applied, whereas
the old SILGen implementation of curry thunks really wanted
the type of the method reference to match the opened type of
the method.
A follow-up cleanup will remove the SILGen curry thunk
implementation.
Fixes rdar://21289579 and https://bugs.swift.org/browse/SR-75.
We give special treatment to a capture of a value with dynamic 'Self'
type, by adding it at the end of the capture list. This ensures that
IRGen can recover the 'Self' metadata from this parameter if needed.
However, the code would crash with an assertion if there were multiple
captured values having the dynamic 'Self' type. This was slightly more
difficult to spell before SE-0068, but it was still possible if you
tried; now its completely trivial.
Fixes <https://bugs.swift.org/browse/SR-11928>, <rdar://problem/57823886>.
Previously we would emit an alloc_ref_dynamic followed by a call
of the initializing entry point when calling an @objc dynamic
initializer in a class.
However this is unnecessary now that the allocating entry point
does the right alloc_ref_dynamic.
This was partially implemented but the check looked at the lowered
types and not the AST types, and DynamicSelfType is erased at the
top level of a lowered type.
Also use the new mangling for reabstraction thunks with self, to
ensure we don't emit the same symbol with two different lowered
types.
Fixes <https://bugs.swift.org/browse/SR-10309>, <rdar://problem/49703441>.
If a closure uses DynamicSelfType but doesn't capture the 'self' value
itself, we would add a dummy metatype capture so that IRGen can recover
metadata.
Also do this if we do capture a value of DynamicSelfType, but mutably,
that is by address or by box, since IRGen doesn't know how to recover
the metadata in that case.
Fixes <rdar://problem/32288771>.
In a previous commit, I banned in the verifier any SILValue from producing
ValueOwnershipKind::Any in preparation for this.
This change arises out of discussions in between John, Andy, and I around
ValueOwnershipKind::Trivial. The specific realization was that this ownership
kind was an unnecessary conflation of the a type system idea (triviality) with
an ownership idea (@any, an ownership kind that is compatible with any other
ownership kind at value merge points and can only create). This caused the
ownership model to have to contort to handle the non-payloaded or trivial cases
of non-trivial enums. This is unnecessary if we just eliminate the any case and
in the verifier separately verify that trivial => @any (notice that we do not
verify that @any => trivial).
NOTE: This is technically an NFC intended change since I am just replacing
Trivial with Any. That is why if you look at the tests you will see that I
actually did not need to update anything except removing some @trivial ownership
since @any ownership is represented without writing @any in the parsed sil.
rdar://46294760
This is the last part of SILGen conditionalized on EnableSILOwnership being
set. It also (as you can tell from the diff) eliminates a bunch of code from the
tests.
rdar://29791263
Delay allocating the result buffer for an opened Self return until right before it's needed. When a mutating method is invoked on an existential, the Self type won't be opened until late, when the formal access to the mutable value begins. Fixes rdar://problem/43507711.
The SILGen testsuite consists of valid Swift code covering most language
features. We use these tests to verify that no unknown nodes are in the
file's libSyntax tree. That way we will (hopefully) catch any future
changes or additions to the language which are not implemented in
libSyntax.
I am going to leave in the infrastructure around this just in case. But there is
no reason to keep this in the tests themselves. I can always just revert this
and I don't think merge conflicts are likely due to previous work I did around
the tooling for this.
Now that we emit the callee at the right time, we no longer need
to force emit the 'self' argument source at +0 and possibly
convert it to +1 later.
This is NFC, except it means we end_borrow the self value a bit
sooner sometimes, which is a good thing.
This replaces the '[volatile]' flag. Now, class_method and
super_method are only used for vtable dispatch.
The witness_method instruction is still overloaded for use
with both ObjC protocol requirements and Swift protocol
requirements; the next step is to make it only mean the
latter, also using objc_method for ObjC protocol calls.
The specific exposed problem had to do with my using the same emission routine
for both lvalues using delegating init self (where we want formal accesses) and
for routines that wanted normal access to self. By splitting them the issue is
resolved.
As a benefit, I added a small peephole that I needed to add for my own purposes
(i.e. to maintain invariants), but that also incidentally improve codegen in
other places!
rdar://31521023
This will let me treat self during delegating initialization as an lvalue and
thus be emitted later without a scope. Thus I can simplify delegating
initialization slightly and land my argument scoping work.
rdar://33358110
Take a seat and pour yourself a beer because this is
going to get pretty intense.
Recall that class methods that return 'Self', have a
'self' type of @dynamic_self X or @dynamic_self X.Type,
for some class X, based on if the method is an instance
method or a static method.
The instance type of a metatype is not lowered, and we
preserve DynamicSelfType there. This is required for
correct behavior with the SIL optimizer.
For example if you specialize a function that contains a
'metatype $((T) -> Int, T).Type' SIL instruction or
some other metatype of a structural type containing a
generic parameter, we might end up with something like
'metatype $((@dynamic_self X) -> Int, X).Type'
after substitution, for some class 'X'. Note that the
second occurrence of 'X', is in "lowered position" so
the @dynamic_self did, indeed, get stripped away.
So while *values* of @dynamic_self type don't need to
carry the fact that they're @dynamic_self at the SIL
level, because Sema has inserted all the right casts.
Metatypes do though, because when lowering the 'metatype'
instruction, IRGen has to know to emit the type metadata
from the method's 'self' parameter, and not the static
metadata for the exact class type.
Essentially, 'metatype @dynamic_self X.Type' is
the same as 'value_metatype %self : X.Type', except that
the @dynamic_self type can appear inside other structural
types also, which is something we cannot write in the
AST.
This is all well and good, but when lowering a
SILFunctionType we erase @dynamic_self from the 'self'
parameter type because when you *call* such a function
from another function, you are not necessarily calling
it on your own 'self' value. And if you are, Sema
already emitted the right unchecked downcast there to
turn the result into the right type.
The problem is that the type of an argument (the value
"inside" the function) used to always be identical to
the type of the parameter (the type from "outside" the
function, in the SILFunctionType). Of course this
assumption is no longer correct for static methods,
where the 'self' argument should really have type
@dynamic_self X.Type, not X.Type.
A further complication is closure captures, whose types
can also contain @dynamic_self inside metatypes in other
structural types. We used to erase @dynamic_self from
these.
Both of these are wrong, because if you call a generic
function <T> (T.Type) -> () with a T := @dynamic_self X
substitution (recall that substitutions are written in
terms of AST types and not lowered types) and pass in
the 'self' argument, we would pass in a value of type
X.Type and not @dynamic_self X.Type.
There were similar issues with captures, with
additional complications from nested closures.
Fix all this by having SILGenProlog emit a downcast
to turn the X.Type argument into a value of type
@dynamic_self X.Type, and tweak capture lowering to
not erase @dynamic_self from capture types.
This fixes several cases that used to fail with
asserts in SILGenApply or the SIL verifier, in particular
the example outlined in <rdar://problem/31226650>,
where we would crash when calling a protocol extension
method from a static class method (oops!).
If you got this far and still follow along,
congratulations, you now know more about DynamicSelfType
than I do.
Instead of appending a character for each substitution, we now prefix the substitution with the repeat count, e.g.
AbbbbB -> A5B
The same is done for known-type substitutions, e.g.
SiSiSi -> S3i
This significantly shrinks mangled names which contain large lists of the same type, like
func foo(_ x: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int))
rdar://problem/30707433
We have a quirk where TypeBase::getSuperclass() on DynamicSelfType
returns the underlying class type, and not the superclass of the
underlying class type. As a result, we would emit a SuperRefExpr
whose type was the type of 'self' and not the type of 'super'.
Fixes <rdar://problem/30853768>.