@@ -520,6 +520,8 @@ struct ASTContext::Implementation {
520520 MetatypeRepresentation::Last_MetatypeRepresentation) + 1 ,
521521 " Use std::pair for MetatypeTypes and ExistentialMetatypeTypes." );
522522
523+ using OpenedExistentialKey = std::pair<SubstitutionMap, UUID>;
524+
523525 llvm::DenseMap<Type, ErrorType *> ErrorTypesWithOriginal;
524526 llvm::FoldingSet<TypeAliasType> TypeAliasTypes;
525527 llvm::FoldingSet<TupleType> TupleTypes;
@@ -555,6 +557,8 @@ struct ASTContext::Implementation {
555557 llvm::FoldingSet<LayoutConstraintInfo> LayoutConstraints;
556558 llvm::DenseMap<std::pair<OpaqueTypeDecl *, SubstitutionMap>,
557559 GenericEnvironment *> OpaqueArchetypeEnvironments;
560+ llvm::DenseMap<OpenedExistentialKey, GenericEnvironment *>
561+ OpenedExistentialEnvironments;
558562
559563 // / The set of function types.
560564 llvm::FoldingSet<FunctionType> FunctionTypes;
@@ -606,8 +610,6 @@ struct ASTContext::Implementation {
606610 void dump (llvm::raw_ostream &out) const ;
607611 };
608612
609- using OpenedExistentialKey = std::pair<SubstitutionMap, UUID>;
610-
611613 llvm::DenseMap<ModuleDecl*, ModuleType*> ModuleTypes;
612614 llvm::DenseMap<std::pair<unsigned , unsigned >, GenericTypeParamType *>
613615 GenericParamTypes;
@@ -620,8 +622,6 @@ struct ASTContext::Implementation {
620622 llvm::DenseMap<BuiltinIntegerWidth, BuiltinIntegerType*> IntegerTypes;
621623 llvm::FoldingSet<BuiltinVectorType> BuiltinVectorTypes;
622624 llvm::FoldingSet<DeclName::CompoundDeclName> CompoundNames;
623- llvm::DenseMap<OpenedExistentialKey, GenericEnvironment *>
624- OpenedExistentialEnvironments;
625625 llvm::DenseMap<UUID, GenericEnvironment *> OpenedElementEnvironments;
626626 llvm::FoldingSet<IndexSubset> IndexSubsets;
627627 llvm::FoldingSet<AutoDiffDerivativeFunctionIdentifier>
@@ -866,7 +866,6 @@ void ASTContext::Implementation::dump(llvm::raw_ostream &os) const {
866866 SIZE_AND_BYTES (SILBlockStorageTypes);
867867 SIZE_AND_BYTES (SILMoveOnlyWrappedTypes);
868868 SIZE_AND_BYTES (IntegerTypes);
869- SIZE_AND_BYTES (OpenedExistentialEnvironments);
870869 SIZE_AND_BYTES (OpenedElementEnvironments);
871870 SIZE_AND_BYTES (ForeignRepresentableCache);
872871 SIZE (SearchPathsSet);
@@ -3128,7 +3127,6 @@ size_t ASTContext::getTotalMemory() const {
31283127 // getImpl().BuiltinVectorTypes ?
31293128 // getImpl().GenericSignatures ?
31303129 // getImpl().CompoundNames ?
3131- getImpl ().OpenedExistentialEnvironments .getMemorySize () +
31323130 getImpl ().Permanent .getTotalMemory ();
31333131
31343132 Size += getSolverMemory ();
@@ -3165,7 +3163,9 @@ size_t ASTContext::Implementation::Arena::getTotalMemory() const {
31653163 llvm::capacity_in_bytes (StructTypes) +
31663164 llvm::capacity_in_bytes (ClassTypes) +
31673165 llvm::capacity_in_bytes (ProtocolTypes) +
3168- llvm::capacity_in_bytes (DynamicSelfTypes);
3166+ llvm::capacity_in_bytes (DynamicSelfTypes) +
3167+ OpaqueArchetypeEnvironments.getMemorySize () +
3168+ OpenedExistentialEnvironments.getMemorySize ();
31693169 // FunctionTypes ?
31703170 // UnboundGenericTypes ?
31713171 // BoundGenericTypes ?
@@ -3212,6 +3212,7 @@ void ASTContext::Implementation::Arena::dump(llvm::raw_ostream &os) const {
32123212 SIZE (ParameterizedProtocolTypes);
32133213 SIZE (LayoutConstraints);
32143214 SIZE_AND_BYTES (OpaqueArchetypeEnvironments);
3215+ SIZE_AND_BYTES (OpenedExistentialEnvironments);
32153216 SIZE (FunctionTypes);
32163217 SIZE (NormalConformances);
32173218 SIZE (SelfConformances);
@@ -5316,26 +5317,39 @@ Type OpaqueTypeArchetypeType::get(
53165317 return env->getOrCreateArchetypeFromInterfaceType (interfaceType);
53175318}
53185319
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+
53195334CanTypeWrapper<OpenedArchetypeType> OpenedArchetypeType::getNew (
53205335 GenericEnvironment *environment, Type interfaceType,
53215336 ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
53225337 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>(
53325343 conformsTo.size (),
53335344 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);
53365349
53375350 return CanOpenedArchetypeType (::new (mem) OpenedArchetypeType (
5338- environment, interfaceType, conformsTo, superclass, layout));
5351+ environment, interfaceType, conformsTo, superclass, layout,
5352+ properties));
53395353}
53405354
53415355CanTypeWrapper<OpenedArchetypeType>
@@ -5560,25 +5574,24 @@ GenericEnvironment *
55605574GenericEnvironment::forOpenedExistential (
55615575 Type existential, SubstitutionMap subs, UUID uuid) {
55625576 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 ();
55725582
55735583 auto &ctx = existential->getASTContext ();
55745584
5585+ auto properties = getOpenedArchetypeProperties (subs);
5586+ auto arena = getArena (properties);
5587+
55755588 auto key = std::make_pair (subs, uuid);
55765589
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);
55805593
5581- if (found != openedExistentialEnvironments .end ()) {
5594+ if (found != environments .end ()) {
55825595 auto *existingEnv = found->second ;
55835596 assert (existingEnv->getOpenedExistentialType ()->isEqual (existential));
55845597 assert (existingEnv->getOuterSubstitutions () == subs);
@@ -5601,7 +5614,7 @@ GenericEnvironment::forOpenedExistential(
56015614 auto *genericEnv =
56025615 new (mem) GenericEnvironment (signature, existential, subs, uuid);
56035616
5604- openedExistentialEnvironments [key] = genericEnv;
5617+ environments [key] = genericEnv;
56055618
56065619 return genericEnv;
56075620}
0 commit comments