@@ -557,8 +557,11 @@ struct ASTContext::Implementation {
557557 llvm::FoldingSet<LayoutConstraintInfo> LayoutConstraints;
558558 llvm::DenseMap<std::pair<OpaqueTypeDecl *, SubstitutionMap>,
559559 GenericEnvironment *> OpaqueArchetypeEnvironments;
560- llvm::DenseMap<OpenedExistentialKey, GenericEnvironment *>
561- OpenedExistentialEnvironments;
560+
561+ llvm::DenseMap<CanType,
562+ OpenedExistentialSignature> ExistentialSignatures;
563+ llvm::DenseMap<OpenedExistentialKey,
564+ GenericEnvironment *> OpenedExistentialEnvironments;
562565
563566 // / The set of function types.
564567 llvm::FoldingSet<FunctionType> FunctionTypes;
@@ -6156,12 +6159,58 @@ ASTContext::getOpenedExistentialSignature(Type type, GenericSignature parentSig)
61566159
61576160 auto result = getImpl ().ExistentialSignatures .insert (
61586161 std::make_pair (key, genericSig));
6159- assert (result.second );
6160- (void ) result;
6162+ ASSERT (result.second );
61616163
61626164 return genericSig;
61636165}
61646166
6167+ OpenedExistentialSignature
6168+ ASTContext::getOpenedExistentialSignature (Type type) {
6169+ assert (type->isExistentialType ());
6170+
6171+ if (auto existential = type->getAs <ExistentialType>())
6172+ type = existential->getConstraintType ();
6173+
6174+ const CanType constraint = type->getCanonicalType ();
6175+
6176+ // The constraint type might contain type variables.
6177+ auto properties = constraint->getRecursiveProperties ();
6178+ auto arena = getArena (properties);
6179+
6180+ // Check the cache.
6181+ const auto &sigs = getImpl ().getArena (arena).ExistentialSignatures ;
6182+ auto found = sigs.find (constraint);
6183+ if (found != sigs.end ())
6184+ return found->second ;
6185+
6186+ OpenedExistentialSignature existentialSig;
6187+
6188+ // Generalize the existential type, to move type variables and primary
6189+ // archetypes into the substitution map.
6190+ auto gen = ExistentialTypeGeneralization::get (constraint);
6191+ existentialSig.Shape = gen.Shape ->getCanonicalType ();
6192+ existentialSig.Generalization = gen.Generalization ;
6193+
6194+ // Now, we have an existential type written with type parameters only.
6195+ // Open the generalization signature by adding a new generic parameter
6196+ // for `Self`.
6197+ auto parentSig = gen.Generalization .getGenericSignature ();
6198+ existentialSig.OpenedSig =
6199+ getOpenedExistentialSignature (gen.Shape , parentSig);
6200+
6201+ // Stash the `Self` type.
6202+ existentialSig.SelfType =
6203+ OpenedArchetypeType::getSelfInterfaceTypeFromContext (parentSig, *this )
6204+ ->getCanonicalType ();
6205+
6206+ // Cache the result.
6207+ auto result = getImpl ().getArena (arena).ExistentialSignatures .insert (
6208+ std::make_pair (constraint, existentialSig));
6209+ ASSERT (result.second );
6210+
6211+ return existentialSig;
6212+ }
6213+
61656214CanGenericSignature
61666215ASTContext::getOpenedElementSignature (CanGenericSignature baseGenericSig,
61676216 CanGenericTypeParamType shapeClass) {
0 commit comments