A protocol extension initializer creates a new instance of the
static type of Self at the call site.
However a convenience initializer in a class is expected to
initialize an instance of the dynamic type of the 'self' value,
because convenience initializers can be inherited by subclasses.
This means that when a convenience initializer delegates to a
protocol extension initializer, we have to substitute the
'Self' type in the protocol extension generic signature with
the DynamicSelfType, and not the static type.
Since the substitution is formed from the type of the 'self'
parameter in the class convenience initializer, the solution is
to change the type of 'self' in a class convenience initializer
to DynamicSelfType, just like we do for methods that return
'Self'.
This fixes cases where we allowed code to type check that
should not type check (if the protocol extension initializer
has 'Self' in contravariant position, and we pass in an
instance of the static type).
It also fixes a miscompile with valid code -- if the protocol
extension initializer was implemented by calling 'Self()',
it would again use the static type and not the dynamic type.
Note that the SILGen change is necessary because Sema now creates
CovariantReturnExprs that convert a static class type to
DynamicSelfType, but the latter lowers to the former at the
SIL level, so we have to peephole away unnecessary unchecked_ref_cast
instructions in this case.
Because this change breaks source compatibility, it is guarded
by a '-swift-version 5' check.
We already have a method on SILGenFunction with the exact signature that just
calls this private function. All other uses can be re-routed to the method on
SILGenFunction, allowing us to simplify the code.
If a local function is in generic context but does not capture
any generic parameters, it has a non-generic lowered type.
However we use substitutions from the AST when forming calls to
generic argument generators. In the AST, such local functions
always have generic types regardless of their captures.
As a result we would crash in this case.
Fixes <rdar://problem/33003280>.
Today, SILGenFunction::emitRValue assumes the caller will create any cleanup
scopes that are needed to cleanup side-effects relating to the rvalue
evaluation. The API also provides the ability for the caller to specify that a
+0 rvalues is an "ok" result. The API then tries to produce a +0 rvalue and
returns a +1 rvalue otherwise. These two properties create conflicting
requirements on the caller since the caller does not know whether or not it
should create a scope (if a +1 rvalue will be returned) or not (if a +0 rvalue
would be returned).
The key issue here is the optionality of returning a +0 rvalue. This change
begins to resolve this difference by creating two separate APIs that guarantee
to the caller whether or not a +0 or a +1 rvalue is returned and also creates
local scopes for the caller as appropriate. So by using these APIs, the caller
knows that the +0 or +1 rvalue that is returned has properly been put into the
caller scope. So the caller no longer needs to create its own scopes anymore.
emitPlusOneRValue is emitRValue except that it scopes the rvalue emission and
then *pushes* the produced rvalue through the scope. emitPlusZeroRValue is
currently a stub implementation that just calls emitPlusOneRValue and then
borrows the resulting +1 RValue in the outer scope, creating the +0 RValue that
was requested by the caller.
rdar://33358110
This is already an RValue invariant that used to be enforced upon RValue
construction. We put in a hack to work around a bug where that was not occuring
and changed RValue constructors to instead load stored objects when they needed
to. But the problem is that since then we have added more constructors that
provide other manners to create such an invalid RValue.
I added verification to many parts of RValue and exposed an additional verify
method that we can invoke at the end of emitRValue() eventually to verify our
invariants. This will give me the comfort to make that assumption in other parts
of SILGen without worry.
I also performed a small amount of cleanup of RValue construction.
rdar://33358110
just for pointer identity.
The current technique for deciding whether that's the case is *extremely*
hacky and need to be replaced with an attribute, but I'm reluctant to
take that on so late in the schedule. The hack is terrible but not too
hard to back out in the future. Anyone who names a method like this just
to get the magic behavior knows well that they are not on the side of
righteousness.
rdar://33265254
Now that we more tightly close formal accesses on lvalues, having LoadExpr and friends try to return a +0 loaded value is unsafe without deeper analysis, since the access will be closed immediately after the load and potentially free temporary memory that might be the only thing keeping the borrowed object alive. Fixes rdar://problem/32730865.
Erasing the block directly from its parent using bb->eraseFromParent() doesn't update SILGenFunction's internal state tracking the postmatter section of the function. Fixes SR-1333 | rdar://problem/33351098.
conversions that reverse an implicit conversion done to align
foreign declarations with their imported types.
For example, consider an Objective-C method that returns an NSString*:
- (nonnull NSString*) foo;
This will be imported into Swift as a method returning a String:
func foo() -> String
A call to this method will implicitly convert the result to String
behind the scenes. If the user then casts the result back to NSString*,
that would normally be compiled as an additional conversion. The
compiler cannot simply eliminate the conversion because that is not
necessarily semantically equivalent.
This peephole recognizes as-casts that immediately reverse a bridging
conversion as a special case and gives them special power to eliminate
both conversions. For example, 'foo() as NSString' will simply return
the original return value. In addition to call results, this also
applies to call arguments, property accesses, and subscript accesses.
ground work for the syntactic bridging peephole.
- Pass source and dest formal types to the bridging routines in addition
to the dest lowered type. The dest lowered type is still necessary
in order to handle non-standard abstraction patterns for the dest type.
- Change bridging abstraction patterns to store bridged formal types
instead of the formal type.
- Improve how SIL type lowering deals with import-as-member patterns.
- Fix some AST bugs where inadequate information was being stored in
various expressions.
- Introduce the idea of a converting SGFContext and use it to regularize
the existing id-as-Any conversion peephole.
- Improve various places in SILGen to emit directly into contexts.
The main thing here is that we create a cleanup that inserts the
end_borrow_argument. Once I merge end_borrow with end_borrow_argument, there
will only be one cleanup.
rdar://31880847
A ConcreteDeclRef to a nested function will include substitutions for its enclosing generic parameters, even if they aren't captured by use locally within the function. The assertion here is probably unnecessary since inconsistencies here should be caught by assertions elsewhere. Fixes SR-5023 | rdar://problem/32426540.
I missed this problem due to a missing test case in initializers.swift. In a
subsequent commit, I am going to add the rest of the missing cases with some
FileCheck tests for some of them. This is to ensure that the commit is easy to
review.
rdar://32539006
In anticipation of removing this bit, move it from the
recursive type property into TupleType - its only real
user. This necessitates uglifying a bit of logic in the
short term that used to speak broadly of materializability
to instead speak about LValues and Tuples of InOut values
independently.
through a few places.
This patch should be NFC for existing patterns, but it's preparing for
using SILGen's built-in bridging capabilities for more things.
It's particularly likely someone will try to type `\(foo)`, which looks like a string interpolation segment, outside of a string literal, so give that case a special diagnostic. Fixes rdar://problem/32315365.
A property imported from Objective-C, or marked in Swift with the `dynamic` keyword, doesn't have a vtable slot, so can't be identified that way. Use the ObjC selector as the unique identifier to ascribe equality to such components. Fixes rdar://problem/31768669. (While we're here, throw some more execution tests and a changelog note in.)
All we need to store is whether the SILDeclRef directly
references the declaration, or if it references a curry
thunk, and we already have an isCurried bit for that.
conversions and extend lifetimes over the call.
Apply this logic to string-to-pointer conversions as well as
array-to-pointer conversions.
Fix the AST verifier to not blow up on optional pointer conversions,
and make sure we SILGen them correctly. There's still an AST bug
here, but I'll fix that in a follow-up patch.