Lazy-load the eraser of @_typeEraser where possible

Type erasure requires a circular construction by its very nature:

@_typeEraser(AnyProto)
protocol Proto { /**/ }
public struct AnyProto : Proto {}

If we eagerly resolve AnyProto, the chain of resolution steps that
deserialization must make goes a little something like this:

Lookup(Proto)
    -> Deserialize(@_typeEraser(AnyProto))
    -> Lookup(AnyProto)
    -> DeserializeInheritedStuff(AnyProto)
    -> Lookup(Proto)

This cycle could be broken if the order of incremental inputs was
such that we had already cached the lookup of Proto.

Resolve this cycle in any case by suspending the deserialization of the
type eraser until the point it's demanded by adding
ResolveTypeEraserTypeRequest.

rdar://61270195
This commit is contained in:
Robert Widmann
2020-04-03 13:57:11 -07:00
parent 172d57fa93
commit 27b211c1f9
16 changed files with 192 additions and 30 deletions

View File

@@ -882,6 +882,9 @@ public:
loadDynamicallyReplacedFunctionDecl(const DynamicReplacementAttr *DRA,
uint64_t contextData) override;
virtual Type loadTypeEraserType(const TypeEraserAttr *TRA,
uint64_t contextData) override;
virtual void finishNormalConformance(NormalProtocolConformance *conformance,
uint64_t contextData) override;