This method was not distinguishing in between in_guaranteed and in
parameters. This would cause the curry thunk where this is used to not copy
in_guaranteed parameters before passing in the parameter to the
partial_apply. This can not affect +1 code since the curry thunk will always
have self at +1.
I also refactored code in:
1. SILGenPoly.
2. SILGenProlog.
3. SILGenConstructor.
to use this function instead of their own reimplementations of the same thing.
This should be NFC for +1 code and is tested by test updates when +0 is enabled.
rdar://34222540
This patch both makes debug variable information it optional on
alloc_stack and alloc_box instructions, and forced variable
information on debug_value and debug_value_addr instructions. The
change of the interface uncovered a plethora of bugs in SILGen,
SILTransform, and IRGen's LoadableByAddress pass.
Most importantly this fixes the previously commented part of the
DebugInfo/local-vars.swift.gyb testcase.
rdar://problem/37720555
We need to deallocate the copy we created in the temporary location.
... and properly forward cleanup after inserting a convert_function
instruction. This didn't come up before because closures where consumed
by the ultimate apply in the chain and no compensating destroy was
neccessary.
SR-5441
rdar://33255593
We need to borrow guaranteed values with sil ownership and need to
distinguish between @callee_guaranteed and other context conventions in
a few places.
SR-5441
rdar://33255593
Also, begin to pass around base types instead of raw InOutType types. Ideally, only Sema needs to deal with them, but this means that a bunch of callers need to unwrap any inouts that might still be lying around before forming these types.
Multiple parts of the compiler were slicing, dicing, or just dropping these flags. Because I intend to use them for the new function type representation, I need them to be preserved all across the compiler. As a first pass, this stubs in what will eventually be structural rules as asserts and tracks down all callers of consequence to conform to the new invariants.
This is temporary.
In anticipation of future attributes, and perhaps the ability to
declare lvalues with specifiers other than 'let' and 'var', expand
the "isLet" bit into a more general "specifier" field.
Now that methods are the only case where we have a function
with multiple parameter lists, we can remove the logic for
forwarding captures (methods cannot have captures), and
simplify what remains to only deal with the case of a single
'self' argument being curried.
I've fixed a few bugs recently where I had to switch
a getCanonicalType() call to instead use the stronger
GenericSignature::getCanonicalTypeInContext().
Avoid the 'if (genericSig = ...)' dance by adding a new
form of TypeBase::getCanonicalType() which takes a
signature, and if it's null, just falls back to the
standard getCanonicalType().
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.
This is useful to discover when a specific cleanup is being eliminated while
debugging. The implementation is compiled out when assertions are disabled.
rdar://29791263
When lowering closures, we avoid capturing the enclosing generic context when possible. However, the generic context may still be necessary to canonicalize types mentioned inside the closure, such as when an associated type is referred to that is same-typed to a concrete type. Fixes rdar://problem/30254048.
This fixes an issue where a same-type constraint making an
associated type into a tuple would lead to a crash, because
of confusion about whether it should be passed as a single
value or an exploded tuple.
Fixes <rdar://problem/30199401>.
Separate formal lowered types from SIL types.
The SIL type of an argument will depend on the SIL module's conventions.
The module conventions are determined by the SIL stage and LangOpts.
Almost NFC, but specialized manglings are broken incidentally as a result of
fixes to the way passes handle book-keeping of aruments. The mangler is fixed in
the subsequent commit.
Otherwise, NFC is intended, but quite possible do to rewriting the logic in many
places.
This is dead code and can be re-added if it is needed. Right now though there
really isnt a ValueOwnershipKind that corresponds to deallocating and I do not
want to add a new ValueOwnershipKind for dead code.
If a generic parameter was substituted for Self, we have to be careful
to not erase Self.Type down to a concrete metatype.
Also, teach the devirtualizer that a metatype of Self type does not
have an exact static type.
- The DeclContext versions of these methods have equivalents
on the DeclContext class; use them instead.
- The GenericEnvironment versions of these methods are now
static methods on the GenericEnvironment class. Note that
these are not made redundant by the instance methods on
GenericEnvironment, since the static methods can also be
called with a null GenericEnvironment, in which case they
just assert that the type is fully concrete.
- Remove some unnecessary #includes of ArchetypeBuilder.h
and GenericEnvironment.h. Now changes to these files
result in a lot less recompilation.
We preserve the current behavior of assuming Any ownership always and use
default arguments to hide this change most of the time. There are asserts now in
the SILBasicBlock::{create,replace,insert}{PHI,Function}Argument to ensure that
the people can only create SILFunctionArguments in entry blocks and
SILPHIArguments in non-entry blocks. This will ensure that the code in tree
maintains the API distinction even if we are not using the full distinction in
between the two.
Once the verifier is finished being upstreamed, I am going to audit the
createPHIArgument cases for the proper ownership. This is b/c I will be able to
use the verifier to properly debug the code. At that point, I will also start
serializing/printing/parsing the ownershipkind of SILPHIArguments, but lets take
things one step at a time and move incrementally.
In the process, I also discovered a CSE bug. I am not sure how it ever worked.
Basically we replace an argument with a new argument type but return the uses of
the old argument to refer to the old argument instead of a new argument.
rdar://29671437
Officially kick SILBoxType over to be "nominal" in its layout, with generic layouts structurally parameterized only by formal types. Change SIL to lower a capture to a nongeneric box when possible, or a box capturing the enclosing generic context when necessary.
After recent changes, this asserts on all decls that are not VarDecls,
so we can just enforce that statically now. Interestingly, this turns
up some dead code which would have asserted immediately if called.
Also, replace AnyFunctionRef::getType() with
AnyFunctionRef::getInterfaceType(), since the old
AnyFunctionRef::getType() would just assert when called on
a Decl.