@@ -520,6 +520,8 @@ struct ASTContext::Implementation {
520
520
MetatypeRepresentation::Last_MetatypeRepresentation) + 1 ,
521
521
" Use std::pair for MetatypeTypes and ExistentialMetatypeTypes." );
522
522
523
+ using OpenedExistentialKey = std::pair<SubstitutionMap, UUID>;
524
+
523
525
llvm::DenseMap<Type, ErrorType *> ErrorTypesWithOriginal;
524
526
llvm::FoldingSet<TypeAliasType> TypeAliasTypes;
525
527
llvm::FoldingSet<TupleType> TupleTypes;
@@ -555,6 +557,8 @@ struct ASTContext::Implementation {
555
557
llvm::FoldingSet<LayoutConstraintInfo> LayoutConstraints;
556
558
llvm::DenseMap<std::pair<OpaqueTypeDecl *, SubstitutionMap>,
557
559
GenericEnvironment *> OpaqueArchetypeEnvironments;
560
+ llvm::DenseMap<OpenedExistentialKey, GenericEnvironment *>
561
+ OpenedExistentialEnvironments;
558
562
559
563
// / The set of function types.
560
564
llvm::FoldingSet<FunctionType> FunctionTypes;
@@ -606,8 +610,6 @@ struct ASTContext::Implementation {
606
610
void dump (llvm::raw_ostream &out) const ;
607
611
};
608
612
609
- using OpenedExistentialKey = std::pair<SubstitutionMap, UUID>;
610
-
611
613
llvm::DenseMap<ModuleDecl*, ModuleType*> ModuleTypes;
612
614
llvm::DenseMap<std::pair<unsigned , unsigned >, GenericTypeParamType *>
613
615
GenericParamTypes;
@@ -620,8 +622,6 @@ struct ASTContext::Implementation {
620
622
llvm::DenseMap<BuiltinIntegerWidth, BuiltinIntegerType*> IntegerTypes;
621
623
llvm::FoldingSet<BuiltinVectorType> BuiltinVectorTypes;
622
624
llvm::FoldingSet<DeclName::CompoundDeclName> CompoundNames;
623
- llvm::DenseMap<OpenedExistentialKey, GenericEnvironment *>
624
- OpenedExistentialEnvironments;
625
625
llvm::DenseMap<UUID, GenericEnvironment *> OpenedElementEnvironments;
626
626
llvm::FoldingSet<IndexSubset> IndexSubsets;
627
627
llvm::FoldingSet<AutoDiffDerivativeFunctionIdentifier>
@@ -866,7 +866,6 @@ void ASTContext::Implementation::dump(llvm::raw_ostream &os) const {
866
866
SIZE_AND_BYTES (SILBlockStorageTypes);
867
867
SIZE_AND_BYTES (SILMoveOnlyWrappedTypes);
868
868
SIZE_AND_BYTES (IntegerTypes);
869
- SIZE_AND_BYTES (OpenedExistentialEnvironments);
870
869
SIZE_AND_BYTES (OpenedElementEnvironments);
871
870
SIZE_AND_BYTES (ForeignRepresentableCache);
872
871
SIZE (SearchPathsSet);
@@ -3128,7 +3127,6 @@ size_t ASTContext::getTotalMemory() const {
3128
3127
// getImpl().BuiltinVectorTypes ?
3129
3128
// getImpl().GenericSignatures ?
3130
3129
// getImpl().CompoundNames ?
3131
- getImpl ().OpenedExistentialEnvironments .getMemorySize () +
3132
3130
getImpl ().Permanent .getTotalMemory ();
3133
3131
3134
3132
Size += getSolverMemory ();
@@ -3165,7 +3163,9 @@ size_t ASTContext::Implementation::Arena::getTotalMemory() const {
3165
3163
llvm::capacity_in_bytes (StructTypes) +
3166
3164
llvm::capacity_in_bytes (ClassTypes) +
3167
3165
llvm::capacity_in_bytes (ProtocolTypes) +
3168
- llvm::capacity_in_bytes (DynamicSelfTypes);
3166
+ llvm::capacity_in_bytes (DynamicSelfTypes) +
3167
+ OpaqueArchetypeEnvironments.getMemorySize () +
3168
+ OpenedExistentialEnvironments.getMemorySize ();
3169
3169
// FunctionTypes ?
3170
3170
// UnboundGenericTypes ?
3171
3171
// BoundGenericTypes ?
@@ -3212,6 +3212,7 @@ void ASTContext::Implementation::Arena::dump(llvm::raw_ostream &os) const {
3212
3212
SIZE (ParameterizedProtocolTypes);
3213
3213
SIZE (LayoutConstraints);
3214
3214
SIZE_AND_BYTES (OpaqueArchetypeEnvironments);
3215
+ SIZE_AND_BYTES (OpenedExistentialEnvironments);
3215
3216
SIZE (FunctionTypes);
3216
3217
SIZE (NormalConformances);
3217
3218
SIZE (SelfConformances);
@@ -5316,26 +5317,39 @@ Type OpaqueTypeArchetypeType::get(
5316
5317
return env->getOrCreateArchetypeFromInterfaceType (interfaceType);
5317
5318
}
5318
5319
5320
+ // / Compute the recursive type properties of an opaque type archetype.
5321
+ static RecursiveTypeProperties getOpenedArchetypeProperties (SubstitutionMap subs) {
5322
+ // An opaque type isn't contextually dependent like other archetypes, so
5323
+ // by itself, it doesn't impose the "Has Archetype" recursive property,
5324
+ // but the substituted types might. A disjoint "Has Opaque Archetype" tracks
5325
+ // the presence of opaque archetypes.
5326
+ RecursiveTypeProperties properties =
5327
+ RecursiveTypeProperties::HasOpenedExistential;
5328
+ for (auto type : subs.getReplacementTypes ()) {
5329
+ properties |= type->getRecursiveProperties ();
5330
+ }
5331
+ return properties;
5332
+ }
5333
+
5319
5334
CanTypeWrapper<OpenedArchetypeType> OpenedArchetypeType::getNew (
5320
5335
GenericEnvironment *environment, Type interfaceType,
5321
5336
ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
5322
5337
LayoutConstraint layout) {
5323
- // FIXME: It'd be great if all of our callers could submit interface types.
5324
- // But the constraint solver submits archetypes when e.g. trying to issue
5325
- // checks against members of existential types.
5326
- // assert((!superclass || !superclass->hasArchetype())
5327
- // && "superclass must be interface type");
5328
- auto arena = AllocationArena::Permanent;
5329
- ASTContext &ctx = interfaceType->getASTContext ();
5330
- void *mem = ctx.Allocate (
5331
- OpenedArchetypeType::totalSizeToAlloc<ProtocolDecl *,Type,LayoutConstraint>(
5338
+ auto properties = getOpenedArchetypeProperties (
5339
+ environment->getOuterSubstitutions ());
5340
+ auto arena = getArena (properties);
5341
+ auto size = OpenedArchetypeType::totalSizeToAlloc<
5342
+ ProtocolDecl *, Type, LayoutConstraint>(
5332
5343
conformsTo.size (),
5333
5344
superclass ? 1 : 0 ,
5334
- layout ? 1 : 0 ),
5335
- alignof (OpenedArchetypeType), arena);
5345
+ layout ? 1 : 0 );
5346
+
5347
+ ASTContext &ctx = interfaceType->getASTContext ();
5348
+ void *mem = ctx.Allocate (size, alignof (OpenedArchetypeType), arena);
5336
5349
5337
5350
return CanOpenedArchetypeType (::new (mem) OpenedArchetypeType (
5338
- environment, interfaceType, conformsTo, superclass, layout));
5351
+ environment, interfaceType, conformsTo, superclass, layout,
5352
+ properties));
5339
5353
}
5340
5354
5341
5355
CanTypeWrapper<OpenedArchetypeType>
@@ -5560,25 +5574,24 @@ GenericEnvironment *
5560
5574
GenericEnvironment::forOpenedExistential (
5561
5575
Type existential, SubstitutionMap subs, UUID uuid) {
5562
5576
assert (existential->isExistentialType ());
5563
- // FIXME: Opened archetypes can't be transformed because the
5564
- // the identity of the archetype has to be preserved. This
5565
- // means that simplifying an opened archetype in the constraint
5566
- // system to replace type variables with fixed types is not
5567
- // yet supported. For now, assert that an opened archetype never
5568
- // contains type variables to catch cases where type variables
5569
- // would be applied to the type-checked AST.
5570
- assert (!existential->hasTypeVariable () &&
5571
- " opened existentials containing type variables cannot be simplified" );
5577
+
5578
+ // TODO: We could attempt to preserve type sugar in the substitution map.
5579
+ // Currently archetypes are assumed to be always canonical in many places,
5580
+ // though, so doing so would require fixing those places.
5581
+ subs = subs.getCanonical ();
5572
5582
5573
5583
auto &ctx = existential->getASTContext ();
5574
5584
5585
+ auto properties = getOpenedArchetypeProperties (subs);
5586
+ auto arena = getArena (properties);
5587
+
5575
5588
auto key = std::make_pair (subs, uuid);
5576
5589
5577
- auto &openedExistentialEnvironments =
5578
- ctx.getImpl ().OpenedExistentialEnvironments ;
5579
- auto found = openedExistentialEnvironments .find (key);
5590
+ auto &environments =
5591
+ ctx.getImpl ().getArena (arena). OpenedExistentialEnvironments ;
5592
+ auto found = environments .find (key);
5580
5593
5581
- if (found != openedExistentialEnvironments .end ()) {
5594
+ if (found != environments .end ()) {
5582
5595
auto *existingEnv = found->second ;
5583
5596
assert (existingEnv->getOpenedExistentialType ()->isEqual (existential));
5584
5597
assert (existingEnv->getOuterSubstitutions () == subs);
@@ -5601,7 +5614,7 @@ GenericEnvironment::forOpenedExistential(
5601
5614
auto *genericEnv =
5602
5615
new (mem) GenericEnvironment (signature, existential, subs, uuid);
5603
5616
5604
- openedExistentialEnvironments [key] = genericEnv;
5617
+ environments [key] = genericEnv;
5605
5618
5606
5619
return genericEnv;
5607
5620
}
0 commit comments