@@ -557,8 +557,11 @@ struct ASTContext::Implementation {
557
557
llvm::FoldingSet<LayoutConstraintInfo> LayoutConstraints;
558
558
llvm::DenseMap<std::pair<OpaqueTypeDecl *, SubstitutionMap>,
559
559
GenericEnvironment *> OpaqueArchetypeEnvironments;
560
- llvm::DenseMap<OpenedExistentialKey, GenericEnvironment *>
561
- OpenedExistentialEnvironments;
560
+
561
+ llvm::DenseMap<CanType,
562
+ OpenedExistentialSignature> ExistentialSignatures;
563
+ llvm::DenseMap<OpenedExistentialKey,
564
+ GenericEnvironment *> OpenedExistentialEnvironments;
562
565
563
566
// / The set of function types.
564
567
llvm::FoldingSet<FunctionType> FunctionTypes;
@@ -6156,12 +6159,58 @@ ASTContext::getOpenedExistentialSignature(Type type, GenericSignature parentSig)
6156
6159
6157
6160
auto result = getImpl ().ExistentialSignatures .insert (
6158
6161
std::make_pair (key, genericSig));
6159
- assert (result.second );
6160
- (void ) result;
6162
+ ASSERT (result.second );
6161
6163
6162
6164
return genericSig;
6163
6165
}
6164
6166
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
+
6165
6214
CanGenericSignature
6166
6215
ASTContext::getOpenedElementSignature (CanGenericSignature baseGenericSig,
6167
6216
CanGenericTypeParamType shapeClass) {
0 commit comments