@@ -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;
@@ -618,7 +622,6 @@ struct ASTContext::Implementation {
618622 llvm::DenseMap<BuiltinIntegerWidth, BuiltinIntegerType*> IntegerTypes;
619623 llvm::FoldingSet<BuiltinVectorType> BuiltinVectorTypes;
620624 llvm::FoldingSet<DeclName::CompoundDeclName> CompoundNames;
621- llvm::DenseMap<UUID, GenericEnvironment *> OpenedExistentialEnvironments;
622625 llvm::DenseMap<UUID, GenericEnvironment *> OpenedElementEnvironments;
623626 llvm::FoldingSet<IndexSubset> IndexSubsets;
624627 llvm::FoldingSet<AutoDiffDerivativeFunctionIdentifier>
@@ -863,7 +866,6 @@ void ASTContext::Implementation::dump(llvm::raw_ostream &os) const {
863866 SIZE_AND_BYTES (SILBlockStorageTypes);
864867 SIZE_AND_BYTES (SILMoveOnlyWrappedTypes);
865868 SIZE_AND_BYTES (IntegerTypes);
866- SIZE_AND_BYTES (OpenedExistentialEnvironments);
867869 SIZE_AND_BYTES (OpenedElementEnvironments);
868870 SIZE_AND_BYTES (ForeignRepresentableCache);
869871 SIZE (SearchPathsSet);
@@ -3125,7 +3127,6 @@ size_t ASTContext::getTotalMemory() const {
31253127 // getImpl().BuiltinVectorTypes ?
31263128 // getImpl().GenericSignatures ?
31273129 // getImpl().CompoundNames ?
3128- getImpl ().OpenedExistentialEnvironments .getMemorySize () +
31293130 getImpl ().Permanent .getTotalMemory ();
31303131
31313132 Size += getSolverMemory ();
@@ -3162,7 +3163,9 @@ size_t ASTContext::Implementation::Arena::getTotalMemory() const {
31623163 llvm::capacity_in_bytes (StructTypes) +
31633164 llvm::capacity_in_bytes (ClassTypes) +
31643165 llvm::capacity_in_bytes (ProtocolTypes) +
3165- llvm::capacity_in_bytes (DynamicSelfTypes);
3166+ llvm::capacity_in_bytes (DynamicSelfTypes) +
3167+ OpaqueArchetypeEnvironments.getMemorySize () +
3168+ OpenedExistentialEnvironments.getMemorySize ();
31663169 // FunctionTypes ?
31673170 // UnboundGenericTypes ?
31683171 // BoundGenericTypes ?
@@ -3209,6 +3212,7 @@ void ASTContext::Implementation::Arena::dump(llvm::raw_ostream &os) const {
32093212 SIZE (ParameterizedProtocolTypes);
32103213 SIZE (LayoutConstraints);
32113214 SIZE_AND_BYTES (OpaqueArchetypeEnvironments);
3215+ SIZE_AND_BYTES (OpenedExistentialEnvironments);
32123216 SIZE (FunctionTypes);
32133217 SIZE (NormalConformances);
32143218 SIZE (SelfConformances);
@@ -5295,7 +5299,7 @@ OpaqueTypeArchetypeType *OpaqueTypeArchetypeType::getNew(
52955299 ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
52965300 LayoutConstraint layout) {
52975301 auto properties = getOpaqueTypeArchetypeProperties (
5298- environment->getOpaqueSubstitutions ());
5302+ environment->getOuterSubstitutions ());
52995303 auto arena = getArena (properties);
53005304 auto size = OpaqueTypeArchetypeType::totalSizeToAlloc<
53015305 ProtocolDecl *, Type, LayoutConstraint>(
@@ -5313,26 +5317,39 @@ Type OpaqueTypeArchetypeType::get(
53135317 return env->getOrCreateArchetypeFromInterfaceType (interfaceType);
53145318}
53155319
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+
53165334CanTypeWrapper<OpenedArchetypeType> OpenedArchetypeType::getNew (
53175335 GenericEnvironment *environment, Type interfaceType,
53185336 ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
53195337 LayoutConstraint layout) {
5320- // FIXME: It'd be great if all of our callers could submit interface types.
5321- // But the constraint solver submits archetypes when e.g. trying to issue
5322- // checks against members of existential types.
5323- // assert((!superclass || !superclass->hasArchetype())
5324- // && "superclass must be interface type");
5325- auto arena = AllocationArena::Permanent;
5326- ASTContext &ctx = interfaceType->getASTContext ();
5327- void *mem = ctx.Allocate (
5328- 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>(
53295343 conformsTo.size (),
53305344 superclass ? 1 : 0 ,
5331- layout ? 1 : 0 ),
5332- alignof (OpenedArchetypeType), arena);
5345+ layout ? 1 : 0 );
5346+
5347+ ASTContext &ctx = interfaceType->getASTContext ();
5348+ void *mem = ctx.Allocate (size, alignof (OpenedArchetypeType), arena);
53335349
53345350 return CanOpenedArchetypeType (::new (mem) OpenedArchetypeType (
5335- environment, interfaceType, conformsTo, superclass, layout));
5351+ environment, interfaceType, conformsTo, superclass, layout,
5352+ properties));
53365353}
53375354
53385355CanTypeWrapper<OpenedArchetypeType>
@@ -5353,7 +5370,7 @@ CanOpenedArchetypeType OpenedArchetypeType::get(CanType existential,
53535370
53545371 auto *genericEnv =
53555372 GenericEnvironment::forOpenedExistential (
5356- existential, GenericSignature (), *knownID);
5373+ existential, SubstitutionMap (), *knownID);
53575374
53585375 // Map the interface type into that environment.
53595376 auto result = genericEnv->mapTypeIntoContext (interfaceType)
@@ -5508,10 +5525,11 @@ GenericEnvironment *GenericEnvironment::forPrimary(GenericSignature signature) {
55085525
55095526 // Allocate and construct the new environment.
55105527 unsigned numGenericParams = signature.getGenericParams ().size ();
5511- size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
5528+ size_t bytes = totalSizeToAlloc<SubstitutionMap,
5529+ OpaqueEnvironmentData,
55125530 OpenedExistentialEnvironmentData,
55135531 OpenedElementEnvironmentData, Type>(
5514- 0 , 0 , 0 , numGenericParams);
5532+ 0 , 0 , 0 , 0 , numGenericParams);
55155533 void *mem = ctx.Allocate (bytes, alignof (GenericEnvironment));
55165534 return new (mem) GenericEnvironment (signature);
55175535}
@@ -5537,10 +5555,11 @@ GenericEnvironment *GenericEnvironment::forOpaqueType(
55375555 // Allocate and construct the new environment.
55385556 auto signature = opaque->getOpaqueInterfaceGenericSignature ();
55395557 unsigned numGenericParams = signature.getGenericParams ().size ();
5540- size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
5558+ size_t bytes = totalSizeToAlloc<SubstitutionMap,
5559+ OpaqueEnvironmentData,
55415560 OpenedExistentialEnvironmentData,
55425561 OpenedElementEnvironmentData, Type>(
5543- 1 , 0 , 0 , numGenericParams);
5562+ 1 , 1 , 0 , 0 , numGenericParams);
55445563 void *mem = ctx.Allocate (bytes, alignof (GenericEnvironment), arena);
55455564 env = new (mem) GenericEnvironment (signature, opaque, subs);
55465565
@@ -5553,46 +5572,49 @@ GenericEnvironment *GenericEnvironment::forOpaqueType(
55535572// / Create a new generic environment for an opened archetype.
55545573GenericEnvironment *
55555574GenericEnvironment::forOpenedExistential (
5556- Type existential, GenericSignature parentSig , UUID uuid) {
5575+ Type existential, SubstitutionMap subs , UUID uuid) {
55575576 assert (existential->isExistentialType ());
5558- // FIXME: Opened archetypes can't be transformed because the
5559- // the identity of the archetype has to be preserved. This
5560- // means that simplifying an opened archetype in the constraint
5561- // system to replace type variables with fixed types is not
5562- // yet supported. For now, assert that an opened archetype never
5563- // contains type variables to catch cases where type variables
5564- // would be applied to the type-checked AST.
5565- assert (!existential->hasTypeVariable () &&
5566- " 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 ();
55675582
55685583 auto &ctx = existential->getASTContext ();
55695584
5570- auto &openedExistentialEnvironments =
5571- ctx.getImpl ().OpenedExistentialEnvironments ;
5572- auto found = openedExistentialEnvironments.find (uuid);
5585+ auto properties = getOpenedArchetypeProperties (subs);
5586+ auto arena = getArena (properties);
5587+
5588+ auto key = std::make_pair (subs, uuid);
5589+
5590+ auto &environments =
5591+ ctx.getImpl ().getArena (arena).OpenedExistentialEnvironments ;
5592+ auto found = environments.find (key);
55735593
5574- if (found != openedExistentialEnvironments .end ()) {
5594+ if (found != environments .end ()) {
55755595 auto *existingEnv = found->second ;
55765596 assert (existingEnv->getOpenedExistentialType ()->isEqual (existential));
5577- assert (existingEnv->getOpenedExistentialParentSignature (). getPointer () == parentSig. getPointer () );
5597+ assert (existingEnv->getOuterSubstitutions () == subs );
55785598 assert (existingEnv->getOpenedExistentialUUID () == uuid);
55795599
55805600 return existingEnv;
55815601 }
55825602
5603+ auto parentSig = subs.getGenericSignature ().getCanonicalSignature ();
55835604 auto signature = ctx.getOpenedExistentialSignature (existential, parentSig);
55845605
55855606 // Allocate and construct the new environment.
55865607 unsigned numGenericParams = signature.getGenericParams ().size ();
5587- size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
5608+ size_t bytes = totalSizeToAlloc<SubstitutionMap,
5609+ OpaqueEnvironmentData,
55885610 OpenedExistentialEnvironmentData,
55895611 OpenedElementEnvironmentData, Type>(
5590- 0 , 1 , 0 , numGenericParams);
5612+ 1 , 0 , 1 , 0 , numGenericParams);
55915613 void *mem = ctx.Allocate (bytes, alignof (GenericEnvironment));
55925614 auto *genericEnv =
5593- new (mem) GenericEnvironment (signature, existential, parentSig , uuid);
5615+ new (mem) GenericEnvironment (signature, existential, subs , uuid);
55945616
5595- openedExistentialEnvironments[uuid ] = genericEnv;
5617+ environments[key ] = genericEnv;
55965618
55975619 return genericEnv;
55985620}
@@ -5621,11 +5643,12 @@ GenericEnvironment::forOpenedElement(GenericSignature signature,
56215643 // Allocate and construct the new environment.
56225644 unsigned numGenericParams = signature.getGenericParams ().size ();
56235645 unsigned numOpenedParams = signature.getInnermostGenericParams ().size ();
5624- size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
5646+ size_t bytes = totalSizeToAlloc<SubstitutionMap,
5647+ OpaqueEnvironmentData,
56255648 OpenedExistentialEnvironmentData,
56265649 OpenedElementEnvironmentData,
56275650 Type>(
5628- 0 , 0 , 1 , numGenericParams + numOpenedParams);
5651+ 1 , 0 , 0 , 1 , numGenericParams + numOpenedParams);
56295652 void *mem = ctx.Allocate (bytes, alignof (GenericEnvironment));
56305653 auto *genericEnv = new (mem) GenericEnvironment (signature,
56315654 uuid, shapeClass,
0 commit comments