Type annotations for instruction operands are omitted, e.g.
```
%3 = struct $S(%1, %2)
```
Operand types are redundant anyway and were only used for sanity checking in the SIL parser.
But: operand types _are_ printed if the definition of the operand value was not printed yet.
This happens:
* if the block with the definition appears after the block where the operand's instruction is located
* if a block or instruction is printed in isolation, e.g. in a debugger
The old behavior can be restored with `-Xllvm -sil-print-types`.
This option is added to many existing test files which check for operand types in their check-lines.
a closure expression, then don't actually do it. The long term plan is
to actually do this, which should just be a matter of taking some of the
code out of reabstraction thunk emission and using it in prolog/epilog/return
emission. In the short term, the goal is just to get the conversion
information down to the closure emitter so that we can see that we're
erasing into an `@isolated(any)` type and then actually erase the
closure's isolation properly instead of relying on type-based erasure,
which can't handle parameter/capture isolation correctly.
patterns) in argument positions in reabstraction thunks.
Most of the difficulty in this work continues to center around
(1) trying to reuse as much code as possible between the parameter
and result paths and (2) propagating ownership information as
necessary throughout the code. I did my best to assert the preconditions
and postconditions here, but undoubtedly I'm missing cases. Some
simplicity here is still eluding me here.
This patch necessarily changes quite a bit of the code used in
non-variadic paths. I tried to avoid doing things that I knew would
be risky, like optimizing copies. I did fail in a few places: e.g.
we should now generate significantly better code when erasing to
Optional<Any>, just because the code was oddly poorly-factored before.
You can see the effect on the function_conversion test case.
The old syntax was
@opened("UUID") constraintType
Where constraintType was the right hand side of a conformance requirement.
This would always create an archetype where the interface type was `Self`,
so it couldn't cope with member types of opened existential types.
Member types of opened existential types is now a thing with SE-0309, so
this lack of support prevented writing SIL test cases using this feature.
The new syntax is
@opened("UUID", constraintType) interfaceType
The interfaceType is a type parameter rooted in an implicit `Self`
generic parameter, which is understood to be the underlying type of the
existential.
Fixes rdar://problem/93771238.
The main point of this change is to make sure that a shared function always has a body: both, in the optimizer pipeline and in the swiftmodule file.
This is important because the compiler always needs to emit code for a shared function. Shared functions cannot be referenced from outside the module.
In several corner cases we missed to maintain this invariant which resulted in unresolved-symbol linker errors.
As side-effect of this change we can drop the shared_external SIL linkage and the IsSerializable flag, which simplifies the serialization and linkage concept.
This change separates out the formation of the generic signature and
substitutions for a SIL substituted function type as a pre-pass
before doing the actual function type lowering. The only input we
really need to form this signature is the original abstraction pattern
that a type is being lowered against, and pre-computing it should make
the code less side-effecty and confusing. It also allows us to handle
generic nominal types in a more robust way; we transfer over all of
the nominal type requirements to the generalized generic signature,
then when recursively visiting the bindings, we same-type-constrain
the generic parameters used in those requirements to the newly-generalized
generic arguments. This ensures that the minimized signature preserves
any non-trivial requirements imposed by the nominal type, such as
conditional conformances on its type arguments, same-type constraints
among associated types, etc.
This approach does lead to less-than-optimal generalized generic
signatures getting generated, since nominal type generic arguments
get same-type-bound either to other generic arguments or fixed to
concrete types almost always. It would be useful to do a minimization
pass on the final generic signature to eliminate these unnecessary
generic arguments, but that can be done in a follow-up PR.
If a type variable doesn't have any "direct" bindings let's not
consider it as viable to be attempted next. Such type variables
are helps purely to accommodate transitive binding inference
for other members of subtype chain.
Resolves: rdar://problem/66234725
In order to allow this, I've had to rework the syntax of substituted function types; what was previously spelled `<T> in () -> T for <X>` is now spelled `@substituted <T> () -> T for <X>`. I think this is a nice improvement for readability, but it did require me to churn a lot of test cases.
Distinguishing the substitutions has two chief advantages over the existing representation. First, the semantics seem quite a bit clearer at use points; the `implicit` bit was very subtle and not always obvious how to use. More importantly, it allows the expression of generic function types that must satisfy a particular generic abstraction pattern, which was otherwise impossible to express.
As an example of the latter, consider the following protocol conformance:
```
protocol P { func foo() }
struct A<T> : P { func foo() {} }
```
The lowered signature of `P.foo` is `<Self: P> (@in_guaranteed Self) -> ()`. Without this change, the lowered signature of `A.foo`'s witness would be `<T> (@in_guaranteed A<T>) -> ()`, which does not preserve information about the conformance substitution in any useful way. With this change, the lowered signature of this witness could be `<T> @substituted <Self: P> (@in_guaranteed Self) -> () for <A<T>>`, which nicely preserves the exact substitutions which relate the witness to the requirement.
When we adopt this, it will both obviate the need for the special witness-table conformance field in SILFunctionType and make it far simpler for the SILOptimizer to devirtualize witness methods. This patch does not actually take that step, however; it merely makes it possible to do so.
As another piece of unfinished business, while `SILFunctionType::substGenericArgs()` conceptually ought to simply set the given substitutions as the invocation substitutions, that would disturb a number of places that expect that method to produce an unsubstituted type. This patch only set invocation arguments when the generic type is a substituted type, which we currently never produce in type-lowering.
My plan is to start by producing substituted function types for accessors. Accessors are an important case because the coroutine continuation function is essentially an implicit component of the function type which the current substitution rules simply erase the intended abstraction of. They're also used in narrower ways that should exercise less of the optimizer.
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>.
I also removed the -verify-sil-ownership flag in favor of a disable flag
-disable-sil-ownership-verifier. I used this on only two tests that still need
work to get them to pass with ownership, but whose problems are well understood,
small corner cases. I am going to fix them in follow on commits. I detail them
below:
1. SILOptimizer/definite_init_inout_super_init.swift. This is a test case where
DI is supposed to error. The only problem is that we crash before we error since
the code emitting by SILGen to trigger this error does not pass ownership
invariants. I have spoken with JoeG about this and he suggested that I fix this
earlier in the compiler. Since we do not run the ownership verifier without
asserts enabled, this should not affect compiler users. Given that it has
triggered DI errors previously I think it is safe to disable ownership here.
2. PrintAsObjC/extensions.swift. In this case, the signature generated by type
lowering for one of the thunks here uses an unsafe +0 return value instead of
doing an autorelease return. The ownership checker rightly flags this leak. This
is going to require either an AST level change or a change to TypeLowering. I
think it is safe to turn this off since it is such a corner case that it was
found by a test that has nothing to do with it.
rdar://43398898
I have been meaning to do this change for a minute, but kept on putting it off.
This describes what is actually happening and is a better name for the option.
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
Protocol name mangling didn’t always go through a path that allowed the use
of standard substitutions. Enable standard substitutions for protocol name
manglings where they make sense.
Removes ~277k from the standard library binary size.
In general, SILGen assumes that only +1 values are "forwarded" into memory. This
is because we want any value that is stored in memory to not be dependent on
other values and for the forwarded object to be able to maintain its own
liveness. So this assert was correct to fire.
The specific test case that exposed this issue is:
What happened here is that we needed to reabstract a loadable value into an
existential and tried to maximally abstract it and thus store it into
memory. The That code was never updated to make sure the value was at +1. So we
would store a guaranteed value into memory and hope that whereever we stored it
doesn't escape the current function. In this case, I believe that we would be
safe... but past returns are not indicators of future results.
rdar://40773543
SR-7858
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.
Otherwise, the plus_zero_* tests will have plus_zero_* as a module name, causing
massive FileCheck problems.
The reason why I am doing it with the main tests is so that I can use it when
syncing branches/etc.
radar://34222540
Fix collection subtyping relation in function argument position
by emiting special re-abstraction thunk with collection upcast.
Resolves: rdar://problem/35702810
For Swift 3 / 4:
Deprecate the spelling "ImplicitlyUnwrappedOptional", emitting a warning
and suggesting "!" in places where they are allowed according to
SE-0054.
In places where SE-0054 disallowed IUOs but we continued to accept them
in previous compilers, emit a warning suggesting "Optional" or "?" as
an alternative depending on context and treat the IUO as an Optional,
noting this in the diagnostic.
For Swift 5:
Treat "ImplicitlyUnwrappedOptional" as an error, suggesting
"!" in places where they are allowed by SE-0054.
In places where SE-0054 disallowed IUOs, emit an error suggestion
"Optional" or "?" as an alternative depending on context.
* [runtime] Clean up symbols in error machinery.
* [runtime] Clean up symbols in Foundation overlay.
* [runtime] Clean up symbols in collections and hashing.
* [runtime] Remove symbol controls from the Linux definition of swift_allocError.
* [tests] Add more stub functions for tests that link directly to the runtime.