Ordinary base protocols use fixed-indexing to access the base index.
That means adding another base protocol to an existing protocol
can break the order of the entries, and thus clients, because we
otherwise order the base entires with TypeDecl::compare.
Reparentable protocols are meant to be resilient to that, so we
order them at the end of the base entries list, just before the
other resilient entries in the witness table.
This patch completes the picture, by having the reparentable
protocol entries be indexed resiliently, in the same manner as
associated conformances.
The difference is that we can skip the call to
`swift_getAssociatedConformanceWitness`
and compute the index directly by finding the distance of the
descriptors, because we know all base protocol witness table
entries are eagarly instantiated.
Using this distance protects us from the ordering problems
of entries among all of the reparentable base protocols.
resolves rdar://173409851
If an inheriting protocol IP declares a requirement that
exactly matches one in the reparentable protocol P, we cannot
consider it to be an override. They need to have independent
witness table entries in both IP and P.
Otherwise, reparenting IP would cause those overriding decls
to have witness table entries moved from IP to P, causing an
ABI break.
resolves rdar://171928937
We were walking the extensions of protocols in
requirement lowering and in getInheritedProtocols
to also count the @reparented entries in all
extensions. I had already seen some request
evaluator cycles triggered by this with objc
protocols, and it seems unnessecary as it's
actually a benefit to force people to write the
inheritance on the protocol itself.
This change forces you to write ``@reparented` relationships
on an extension of a protocol, rather than on the protocol
itself.
The ProtocolConformance needs to be associated with some
GenericContext and IRGen expects it to be an ExtensionDecl.
That environment defines under what conditions the conformance
exists. We also need to define witnesses for the new parent's
requirements in an extension anyway, so it's a natural fit.
The previous workaround for this was kind of awful, as it'd
require searching all the protocol's extensions and "guess"
which extension they want to represent the conformance. While
we could try to synthesize an extension, there's two
challenges there:
1. Due to SuppressedAssociatedTypes, it's not so simple to
synthesize an unconstrained ExtensionDecl.
2. We currently rely on same-type requirements to pin the
associated types to particular witnesses of those requirements
in the extension. So it's not purely unconstrained! For example,
```
extension Seq: @reparented BorrowSeq where Iter == MyIter {}
```
The constraints that are disallowed (but not yet diagnosed)
are conditional conformance requirements, as the default
conformance for a reparenting cannot depend on those.
Thus, it's better that programmers to specify the extension.
Their definition is fully visible to clients to be copied into them, and there isn't necessarily
a symbol for the property descriptor in the defining module, so it isn't necessary or desirable to
try to use a property descriptor with them. Trying to reference the descriptor leads to missing
symbol errors at load time when trying to use keypaths with older versions of the defining dylib,
which goes against the purpose of `@_alwaysEmitIntoClient` meaning "no ABI liabilities for the
defining module". Fixes rdar://94049160.
The ConformanceCandidate constructor would eagerly instantiate metadata for
all non-generic types in the conformance cache. This was not the intention
of the code though, because it can compare nominal type descriptors --
which are emitted statically -- for those types that have them, namely
everything except for foreign and Objective-C classes.
Change the order of two calls so that the lazy path has a chance to run.
This fixes a crash when type metadata uses weakly-linked symbols
which are not available, which can come up in backward deployment
scenarios.
Fixes <rdar://problem/59460603>.
We have to set the SILFunction's 'weakLinked' flag in the defining
module too, so that it can be serialized. Otherwise when we
deserialize it we are not weak linking calls to the function.
If the conforming type is generic, we have to treat the conformance as
resilient if it is defined outside of the current module.
This is because it can resiliently change from being non-dependent
to dependent.
@_fixed_layout classes have resilient vtables now, so we can add and
re-order methods.
Removing overrides is not legal though because they are subject to
devirtualization.
- We don't want to support changing a root class of a class, so don't
pretend that works. Some of these tests got removed recently in
d8104e7e43 but one still remained.
- For the tests that insert a non-root superclass in the inheritance
hierarchy, also test calling a method of the derived class. This
works now that we no longer hardcode vtable offsets and instead use
dispatch thunks.
We want removing a property override to be a resilient change, so
keypaths should not reference them, preferring to reference the
base declaration instead.
Instead of passing in a DeclContext, which we don't have when emitting a keypath
accessor, pass in a ModuleDecl and ResilienceExpansion.
Keypaths now work well enough in inlinable contexts that we can check in an
end-to-end resilience test.
Get the attribute working for more link entity kinds, which addresses
all the FIXME:s in the original test case.
Now the protocol resilience tests can be updated to use @_weakLinked
for all newly-added protocol requirements and default implementations.
This allows the tests to pass in the backward deployment test scenario
as well.
Eventually this will be based on availability instead of a special
attribute.
This completes <rdar://problem/29888071>.
The witness table for an empty, resilient protocol might need to be
instantiated, if a newer version of the protocol contains defaulted
associated type requirements. In such cases, we would either fail to
instantiate or assert in the runtime. Replace the assertion with a
proper check (to require instantiation in such cases) and cope with
filling in defaults even when the provided generic witness table has
no resilient witnesses.
For a resilient protocol that has defaulted associated types, emit
default associated conformance witnesses that compute associated
conformances based on that default witness.
This completes the implementation of resilience protocols that
add new, defaulted associated types, rdar://problem/44167982.
When an associated type witness has a default, record that as part of
the protocol and emit a default associated type metadata accessor into the
default witness table. This allows a defaulted associated type to be
added to a protocol resiliently.
This is another part of rdar://problem/44167982, but it’s still very
limiting because the new associated type cannot have any conformances.
Generic parameter references, which occur in generic requirement
metadata, were hardcoding associated type indices. Instead, use
relative references to associated type descriptors and perform the
index calculation at runtime.
Associated types can now be reordered resiliently (without relying on
sorting), which is the first main step toward rdar://problem/44167982.
With a few modifications:
- Changing computed get-only properties into 'let's breaks resilience in other ways we need to fix independent of key path resilience
- Fix the tests not to ask for impossible lib-before--client-after compatibility for changes that add API
Builds on 36eae9d4f6 to emit a message instead of just trapping
when a switch over a non-frozen enum ends up not matching anything.
If the enum is known to be an @objc enum, the message is
unexpected enum case 'MyEnum(rawValue: -42)'
and if it's anything else (a Swift enum, a tuple containing enums,
whatever), it's a more opaque
unexpected enum case while switching on value of type 'MyEnum'
The reason for this is to avoid calling String(describing:) or
String(reflecting:) an arbitrary value when the enum might conform to
CustomStringConvertible and therefore /itself/ have a switch that's
going to fall off the end. By handling plain @objc enums (using a
bitcast), we've at least covered the 90% case.
rdar://problem/37728359
In theory there could be a "fixed-layout" enum that's not exhaustive
but promises not to add any more cases with payloads, but we don't
need that distinction today.
(Note that @objc enums are still "fixed-layout" in the actual sense of
"having a compile-time known layout". There's just no special way to
spell that.)
We're okay with saying this is a binary-breaking change, and its
presence in these tests is interfering with testing other things.
rdar://problem/36932507
Since field offsets are now encoded after generic parameters, it
is useful to validate that using generic parameter metadata is now
more resilient in presence of new fields.
We don't want @_fixed_layout to apply to static properties, or you
get fun consequences like not being able to change static stored
properties defined in extensions of imported types to computed.