Today the ownership checker has two different behaviors on detecting an error:
1. In normal operating mode, it prints a message to stderr and asserts.
2. In testing mode, it prints a message to stderr and returns false.
This refactoring will allow me to add a third mode:
1. In optimization mode, it does not print a message and just returns false.
This will allow me to use the verifier in an early ARC optimization that I need
to prevent COW copies due to refactoring in SILGenPattern.
rdar://29870610
This commit changes how inline information is stored in SILDebugScope
from a tree to a linear chain of inlined call sites (similar to what
LLVM is using). This makes creating inlined SILDebugScopes slightly
more expensive, but makes lowering SILDebugScopes into LLVM metadata
much faster because entire inlined-at chains can now be cached. This
means that SIL is no longer preserve the inlining history (i.e., ((a
was inlined into b) was inlined into c) is represented the same as (a
was inlined into (b was inlined into c)), but this information was not
used by anyone.
On my late 2012 i7 iMac, this saves about 4 seconds when compiling the
RelWithDebInfo x86_64 swift standard library — or 40% of IRGen time.
rdar://problem/28311051
Previously we would drop all serialized SIL from partial swiftmodule
files generated while compiling source in non-WMO mode; all that was
missing was linking it in.
This adds a frontend flag, and a test; driver change is coming up
next.
Progress on <rdar://problem/18913977>.
This is already asserted by AllocBoxToStack and hinting at in other passes.
Rather than having the requirement be cargo-culted around, this commit just
reifies the requirement into an assert check.
LLVM r299341 removed the llvm::integerPart typedef and replaced it
with llvm::APInt::WordType. The integerPartWidth constant was replaced
by llvm::APInt::APINT_BITS_PER_WORD.
The new API is broken. Popping a generic context frees all
dependent type lowerings, so this function returns a pointer
to freed memory.
This reverts commit 24dfae0716.
Introduce a new runtime entry point,
`swift_objc_swift3ImplicitObjCEntrypoint`, which is called from any
Objective-C method that was generated due to `@objc` inference rules
that were removed by SE-0160. Aside from being a central place where
users can set a breakpoint to catch when this occurs, this operation
provides logging capabilities that can be enabled by setting the
environment variable SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT:
SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=0 (default): do not log
SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=1: log failed messages
SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=2: log failed messages with
backtrace
SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=3: log failed messages with
backtrace and abort the process.
The log messages look something like:
***Swift runtime: entrypoint -[t.MyClass foo] generated by
implicit @objc inference is deprecated and will be removed in
Swift 4
The existence of a shared_external function in itself is not
an error; it just means we deserialized a witness table or
vtable but did not need to deserialize a thunk.
However, a direct reference to such a function is an error,
because we should have deserialized the body in that case.
This fixes a crasher, but the SIL crashers are kind of silly
because the SIL parser does not try at all not to crash on
invalid input.
This fixes a crash when referencing partially-applied methods
from @_inlineable functions.
Also, curry thunks for private methods do not need shared
linkage; private is sufficient.
This code has been commented out for years, doesn't compile,
and when I changed it to compile it blew up building overlays.
I don't feel it adds any value to have it around so I'm
removing it.
This generalizes a hack where re-abstraction thunks become fragile on contact
with fragile functions.
The old policy was:
- [fragile] functions always serialized
- [reabstraction_thunk] transitively referenced from fragile always serialized
The new policy is:
- [serialized] functions always serialized
- [serializable] functions transitively referenced from serialized functions
are always serialized
- Most kinds of thunks can now be [serializable], allowing them to be shared
between serialized and non-serialized code without any issues, as long as the
body of the thunk is sufficiently "simple" (doesn't reference private
symbols or performs direct access to resilient types)
Also, add a third [serializable] state for functions whose bodies we
*can* serialize, but only do so if they're referenced from another
serialized function.
This will be used for bodies synthesized for imported definitions,
such as init(rawValue:), etc, and various thunks, but for now this
change is NFC.
This commit does a few things:
1. It uses SwitchEnumBuilder so we are not re-inventing any wheels.
2. Instead of hacking around not putting in a destroy for .None on the fail
pass, just *do the right thing* and recognize that we have a binary case enum
and in such a case, just emit code for the other case rather than use a default
case (meaning no cleanup on .none).
rdar://31145255
There's some new bug where IRGen can call requiresNewVTableEntry()
with a generic context pushed, which then goes to lower a function
type and can try to push another context, causing an assert.
I don't have a test case handy and I want to rip out the push/pop
crap soon anyway, so kick the can down the road, borrow some more
money at 20% interest and party hard with a stack.
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().
- Property defined in constrained extension of a class
- Subscript defined in a constrained extension with non-canonical index type
Fixes <rdar://problem/31222187>.
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 fixes the "AST type changed, override is ABI compatible" case,
which enables the test cases previously marked with 'FIXME' in
vtable_thunks_reabstraction to pass.
Flesh out TypeConverter::requiresNewVTableEntry() and add tests
to (hopefully) exercise this support.
A few cases marked with FIXME still fail; looks like SILGenApply
is still not using the correct formal types for class method calls.