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.
Changes:
* Terminate all namespaces with the correct closing comment.
* Make sure argument names in comments match the corresponding parameter name.
* Remove redundant get() calls on smart pointers.
* Prefer using "override" or "final" instead of "virtual". Remove "virtual" where appropriate.
The substitution only replaces archetypes with abstract generic parameters, so no conformance lookup is necessary, and we can provide a "lookup" callback now that just vends abstract conformances.
(Ideally, we'd be able to do this for mapTypeIntoContext too, but we run into problems with generic signatures with same-type constraints on associated types with protocol requirements. Mapping `t_0_0.AssocType` into such a context will require conformance lookup for the concrete type replacement, since same-type Requirements don't preserve the conformances that satisfy the protocol requirements for the same-type relationship.)
The purpose of this change is to test if the new mangling is equivalent to the old mangling.
Both mangling strings are created, de-mangled and checked if the de-mangle trees are equivalent.
This was made redundant by typed boxes, and the type operand was already removed from textual SIL, but the field was never removed from the instruction's in memory representation. It becomes wrong in the face of compound boxes with layout.
Keep in mind that these are approximations that will not impact correctness
since in all cases I ensured that the SIL will be the same after the
OwnershipModelEliminator has run. The cases that I was unsure of I commented
with SEMANTIC ARC TODO. Once we have the verifier any confusion that may have
occurred here will be dealt with.
rdar://28685236
I am removing these usages of this API since it conflicts with SILGen's want to
hold onto copy_value return values for ownership propagation purposes. If any of
the copy_value are folded, the reference that SILGen holds onto will be
invalid.
rdar://28685236
Reimplement the witness matching logic used for generic requirements
so that it properly models the expectations required of the witness,
then captures the results in the AST. The new approach has a number of
advantages over the existing hacks:
* The constraint solver no longer requires hacks to try to tangle
together the innermost archetypes from the requirement with the
outer archetypes of the context of the protocol
conformance. Instead, we create a synthetic set of archetypes that
describes the requirement as it should be matched against
witnesses. This eliminates the infamous 'SelfTypeVar' hack.
* The type checker no longer records substitutions involving a weird
mix of archetypes from different contexts (see above), so it's
actually plausible to reason about the substitutions of a witness. A
new `Witness` class contains the declaration, substitutions, and all
other information required to interpret the witness.
* SILGen now uses the substitution information for witnesses when
building witness thunks, rather than computing all of it from
scratch. ``substSelfTypeIntoProtocolRequirementType()` is now gone
(absorbed into the type checker, and improved from there), and the
witness-thunk emission code is simpler. A few other bits of SILGen
got simpler because the substitutions can now be trusted.
* Witness matching and thunk generation involving generic requirements
and nested generics now works, based on some work @slavapestov was
already doing in this area.
* The AST verifier can now verify the archetypes that occur in witness substitutions.
* Although it's not in this commit, the `Witness` structure is
suitable for complete (de-)serialization, unlike the weird mix of
archetypes previously present.
Fixes rdar://problem/24079818 and cleans up an area that's been messy
and poorly understood for a very, very long time.
Today, loads and stores are treated as having @unowned(unsafe) ownership
semantics. This leaves the user to specify ownership changes on the loaded or
stored value independently of the load/store by inserting ARC operations. With
the change to Semantic SIL, this will no longer be true. Instead loads, stores
have ownership semantics that one must reason about such as copy, take, and
trivial.
This change moves us closer to that world by eliminating the default
OwnershipQualification argument from create{Load,Store}. This means that the
compiler developer cannot ignore reasoning about the ownership semantics of the
memory operation that they are creating.
Operationally, this is a NFC change since I have just gone through the compiler
and updated all places where we create loads, stores to pass in the former
default argument ({Load,Store}OwnershipQualifier::Unqualified), to
SILBuilder::create{Load,Store}(...). For now, one can just do that in situations
where one needs to create loads/stores, but over time, I am going to tighten the
semantics up via the verifier.
rdar://28685236
Fixes rdar://problem/28873860, where we would miscompile when lightweight generic classes were extended to conform to Swift protocols because we tried to emit parameters for the class's generic parameters for the witness entry points. Prevent this by lowering the witness into a pseudogeneric function in SILGen, and teaching IRGen to do the right thing for a witness with pseudogeneric parameters.
Sema produces a weird mix of requirement and witness archetypes when
it builds witness substitutions. Instead of hacking around this in
SILGen, just build new archetypes, since we already have to use an
ArchetypeBuilder to get the correct generic signature on the interface
type.
Then, we just have to map the witnessSubs provided by Sema to use our
new archetypes.
This unblocks some work on generic inlining.
Fixes <rdar://problem/28765006>.
Sugared GenericTypeParamTypes point to GenericTypeParamDecls,
allowing the name of the parameter as written by the user to be
recovered. Canonical GenericTypeParamTypes on the other hand
only store a depth and index, without referencing the original
declaration.
When printing SIL, we wish to output the original generic parameter
names, even though SIL only uses canonical types. Previously,
we used to accomplish this by mapping the generic parameter to an
archetype and printing the name of the archetype. This was not
adequate if multiple generic parameters mapped to the same
archetype, or if a generic parameter was mapped to a concrete type.
The new approach preserves the original sugared types in the
GenericEnvironment, adding a new GenericEnvironment::getSugaredType()
method.
There are also some other assorted simplifications made possible
by this.
Unfortunately this makes GenericEnvironments use a bit more memory,
however I have more improvements coming that will offset the gains,
in addition to making substitution lists smaller also.
This particular flag should only be used in rare cases where we don't
want to know about failures, but instead want to get some
partially-formed type. Only very specific parts of the type checker
need this (associated type inference), and code completion relies on
it for slightly-better results.
This would manifest as crashes in IRGen when bridging a block
taking another block in generic context.
- When emitting a re-abstraction thunk, make it pseudogeneric if
its parent function is pseudogeneric. This ensures we don't
try to get runtime type metadata when it doesn't exist.
- Mangle pseudogeneric-ness of a reabstraction thunk correctly.
Otherwise we could emit thunks with different signatures under
the same mangling.
- Only set the pseudogeneric attribute if the thunk has a generic
signature, since otherwise the mangling is no longer unique.
Fixes <rdar://problem/27718566>.
SILType substitutions are still done with the old form, and until
BoundGenericTypes hold conformances, we still have to pass around
a ModuleDecl in a few places we really shouldn't, but one step
at a time.
This patch is rather large, since it was hard to make this change
incrementally, but most of the changes are mechanical.
Now that we have a lighter-weight data structure in the AST for mapping
interface types to archetypes and vice versa, use that in SIL instead of
a GenericParamList.
This means that when serializing a SILFunction body, we no longer need to
serialize references to archetypes from other modules.
Several methods used for forming substitutions can now be moved from
GenericParamList to GenericEnvironment.
Also, GenericParamList::cloneWithOuterParameters() and
GenericParamList::getEmpty() can now go away, since they were only used
when SILGen-ing witness thunks.
Finally, when printing generic parameters with identical names, the
SIL printer used to number them from highest depth to lowest, by
walking generic parameter lists starting with the innermost one.
Now, ambiguous generic parameters are numbered from lowest depth
to highest, by walking the generic signature, which means test
output in one of the SILGen tests has changed.
One minor revision: this lifts the proposed restriction against
overriding a non-open method with an open one. On reflection,
that was inconsistent with the existing rule permitting non-public
methods to be overridden with public ones. The restriction on
subclassing a non-open class with an open class remains, and is
in fact consistent with the existing access rule.
What I've implemented here deviates from the current proposal text
in the following ways:
- I had to introduce a FunctionArrowPrecedence to capture the parsing
of -> in expression contexts.
- I found it convenient to continue to model the assignment property
explicitly.
- The comparison and casting operators have historically been
non-associative; I have chosen to preserve that, since I don't
think this proposal intended to change it.
- This uses the precedence group names and higherThan/lowerThan
as agreed in discussion.
There are many places where we do the 'if inside a protocol, get the
Self type parameter, otherwise, use the declared type' dance.
We actually have really handy utility methods that encapsulate this,
so let's use them more.
This made call sites confusing to read because it doesn't actually
check if the function already exists.
Also fix some minor formatting issues. This came up while I was working
on a fix for a bug that turned out to not be a bug.
Also, mark witness thunks for [fragile] witnesses as [fragile].
This allows us to serialize the witness table, as well as any thunks
for witnesses declared @_transparent and @inline(__always).
This is only used in the verifier, to ensure that default witness
thunks are suffiently visible.
Also this patch removes the asserts enforcing that only resilient
protocols have a default witness table. This will change in an
upcoming patch, and in this patch is necessary for the test to work.
Don't hardcode linkage of default witness thunks, addressing a FIXME.
This will allow us to emit default witness thunks for requirements of
internal protocols, too.
Don't hardcode linkage of default implementations of materializeForSet
to public, addressing a FIXME.
This will allow us to emit default witness thunks for requirements of
internal protocols, too.
Previously we would emit two types of MaterializeForSet implementations
in SILGen:
- materializeForSet for a concrete storage declaration
- materializeForSet witness thunk in a conformance
This refactoring decouples the code from taking a conformance, which is
needed for two new types of materializeForSet that we need:
- materializeForSet witness thunk in a default witness table -- this is
necessary in order to be able to resiliently add storage requirements
with default implementations to protocols
- materializeForSet vtable thunk -- this is necessary to fix a missing
re-abstraction case with overriding storage in a subclass
This patch brings us closer to implementing these two. For default
implementations, we still have an issue in that the materializeForSet
has a different "generic signature abstraction pattern" in concrete
and default witnesses, so default and concrete witnesses for
materializeForSet are currently ABI-incompatible because the type
metadata for the storage is passed differently to the callback.