This test ensures that the runtime correctly instantiates resilient conformances,
and that IRGen emits the correct metadata, allowing a conformance that was
compiled before a new requirement was added to present a default implementation
of this requirement.
For now, this runs with --no-backward-deployment, so we only test before/before,
before/after and after/after cases.
Getting after/before working is also an expected capability here, but requires
IRGen witness table emission to know which requirements were satisfied by
defaults, so that they can be dropped if they appear at the end of a witness
table. In turn, this requires serializing SILDefaultWitnessTables. This will
be added in a subsequent patch.
In addition to fixing the above case, I need to write additional tests and
possibly fix bugs related to more elaborate cases involving generics, as well as
default witnesses for properties and subscripts.
Even dynamically casting a generic parameter to a protocol type is only
guaranteed to succeed for conformances available at build time.
Since we can't express conditional availability of conformances yet,
this part of the test is useless, so redo it.
This comes with a fix for a null pointer dereference in _typeByName()
that would pop with foreign classes that do not have a
NominalTypeDescriptor.
Also, I decided to back out part of the change for now, where the
NominalTypeDescriptor references an accessor function instead of a
pattern, since this broke LLDB, which reaches into the pattern to
get the generic cache.
Soon we will split off the generic cache from the pattern, and at
that time we can change the NominalTypeDescriptor to point at the
cache. But for now, let's avoid needless churn in LLDB by keeping
that part of the setup unchanged.
Change conformance records to reference NominalTypeDescriptors instead of
metadata patterns for resilient or generic types.
For a resilient type, we don't know if the metadata is constant or not,
so we can't directly reference either constant metadata or the metadata
template.
Also, whereas previously NominalTypeDescriptors would point to the
metadata pattern, they now point to the metadata accessor function.
This allows the recently-added logic for instantiating concrete types
by name to continue working.
In turn, swift_initClassMetadata_UniversalStrategy() would reach into
the NominalTypeDescriptor to get the pattern out, so that its bump
allocator could be used to allocate ivar tables. Since the pattern is
no longer available this way, we have to pass it in as a parameter.
In the future, we will split off the read-write metadata cache entry
from the pattern; then swift_initClassMetadata_UniversalStrategy() can
just take a pointer to that, since it doesn't actually need anything
else from the pattern.
Since Clang doesn't guarantee alignment for function pointers, I had
to kill the cute trick that packed the NominalTypeKind into the low
bits of the relative pointer to the pattern; instead the kind is now
stored out of line. We could fix this by packing it with some other
field, or keep it this way in case we add new flags later.
Now that generic metadata is instantiated by calling accessor functions,
this change removes the last remaining place that metadata patterns were
referenced from outside the module they were defined in. Now, the layout
of the metadata pattern and the behavior of swift_getGenericMetadata()
is purely an implementation detail of generic metadata accessors.
This patch allows two previously-XFAIL'd tests to pass.
I'm going to add some more tests related to @_transparent shortly,
and it is important to verify that bodies of @_transparent functions
are serialized (at least in single-frontend mode, for now).
I realize this test is probably too specific, since in the future
we may sometimes choose not to inline @_transparent functions into
their callers, even if a serialized body is available; but this
will suffice for now.
We now test four setups, with the four {before, after}^2 runs of each:
a) Client adds conformance -vs- library adds public conformance -- fixed-layout struct
b) Client adds conformance -vs- library removes internal conformance -- fixed-layout struct
c) Client adds conformance -vs- library adds public conformance -- resilient struct
d) Client adds conformance -vs- library removes internal conformance -- resilient struct
The first two pass, but a) requires a hack to ensure we don't
directly reference conformance table, otherwise the 'after_before'
version doesn't link. I think the right idea here is to weakly
reference conformance tables where the deployment target is
lower than the availability of the conformance.
The second two are XFAIL'd until protocol conformance tables can
reference resilient types from other modules. This requires emitting
indirect metadata symbols, since the client doesn't know if the
resilient type's metadata is direct or a template, and the
conformance table cannot use the metadata accessor either.
These tests will also become important if we decide to revisit
synthesized accessors, and make them lazy again for structs.
This reverts commit 2b6ab633fc because it
at least breaks:
Swift :: stdlib/SequenceType.swift.gyb
and possibly also results in some or all of these failures:
Swift :: compiler_crashers/27944-swift-astvisitor.swift
Swift :: compiler_crashers/28200-swift-typebase-getdesugaredtype.swift
Swift :: stdlib/CollectionType.swift.gyb
Swift :: stdlib/MicroStdlib.swift
This fixes the issue that "SILGen: Correctly emit accessors synthesized to
witness protocol requirements" was meant to solve, but in a simpler way.
A better fix would be to first address the issue where @_transparent
function bodies are not serialized in some cases, and then only emit
synthesized accessors as needed, in the original version of this patch.
To fix the duplicate symbol issues, we would emit the synthesized
accessors with shared linkage, which would always work once serialized
bodies were available.
For resilient structs of course, we'll always need to emit accessors
anyway.
The test removes a public conformance, which is technically not resilient.
I will split up the test into two tests soon:
- client library adds conformance, library adds public conformance
- client library adds conformance, library removes *private* conformance