@@ -414,7 +414,8 @@ struct ASTContext::Implementation {
414414 llvm::FoldingSet<BoundGenericType> BoundGenericTypes;
415415 llvm::FoldingSet<ProtocolCompositionType> ProtocolCompositionTypes;
416416 llvm::FoldingSet<LayoutConstraintInfo> LayoutConstraints;
417- llvm::FoldingSet<OpaqueTypeArchetypeType> OpaqueArchetypes;
417+ llvm::DenseMap<std::pair<OpaqueTypeDecl *, SubstitutionMap>,
418+ GenericEnvironment *> OpaqueArchetypeEnvironments;
418419
419420 // / The set of function types.
420421 llvm::FoldingSet<FunctionType> FunctionTypes;
@@ -4280,77 +4281,62 @@ DependentMemberType *DependentMemberType::get(Type base,
42804281 return known;
42814282}
42824283
4283- OpaqueTypeArchetypeType *
4284- OpaqueTypeArchetypeType::get (OpaqueTypeDecl *Decl, unsigned ordinal,
4285- SubstitutionMap Substitutions) {
4286- auto opaqueParamType = Decl->getOpaqueGenericParams ()[ordinal];
4287-
4288- // TODO: We could attempt to preserve type sugar in the substitution map.
4289- // Currently archetypes are assumed to be always canonical in many places,
4290- // though, so doing so would require fixing those places.
4291- Substitutions = Substitutions.getCanonical ();
4292-
4293- llvm::FoldingSetNodeID id;
4294- Profile (id, Decl, ordinal, Substitutions);
4295-
4296- auto &ctx = Decl->getASTContext ();
4297-
4284+ // / Compute the recursive type properties of an opaque type archetype.
4285+ static RecursiveTypeProperties getOpaqueTypeArchetypeProperties (
4286+ SubstitutionMap subs) {
42984287 // An opaque type isn't contextually dependent like other archetypes, so
42994288 // by itself, it doesn't impose the "Has Archetype" recursive property,
43004289 // but the substituted types might. A disjoint "Has Opaque Archetype" tracks
43014290 // the presence of opaque archetypes.
43024291 RecursiveTypeProperties properties =
43034292 RecursiveTypeProperties::HasOpaqueArchetype;
4304- for (auto type : Substitutions .getReplacementTypes ()) {
4293+ for (auto type : subs .getReplacementTypes ()) {
43054294 properties |= type->getRecursiveProperties ();
43064295 }
4307-
4296+ return properties;
4297+ }
4298+
4299+ OpaqueTypeArchetypeType *OpaqueTypeArchetypeType::getNew (
4300+ GenericEnvironment *environment, Type interfaceType,
4301+ ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
4302+ LayoutConstraint layout) {
4303+ auto properties = getOpaqueTypeArchetypeProperties (
4304+ environment->getOpaqueSubstitutions ());
43084305 auto arena = getArena (properties);
4309-
4310- llvm::FoldingSet<OpaqueTypeArchetypeType> &set
4311- = ctx.getImpl ().getArena (arena).OpaqueArchetypes ;
4312-
4313- {
4314- void *insertPos; // Discarded because the work below may invalidate the
4315- // insertion point inside the folding set
4316- if (auto existing = set.FindNodeOrInsertPos (id, insertPos)) {
4317- return existing;
4318- }
4319- }
4320-
4321- auto reqs = Decl->getOpaqueInterfaceGenericSignature ()
4322- ->getLocalRequirements (opaqueParamType);
4323- auto superclass = reqs.superclass ;
4324- #if !DO_IT_CORRECTLY
4325- // Ad-hoc substitute the generic parameters of the superclass.
4326- // If we correctly applied the substitutions to the generic signature
4327- // constraints above, this would be unnecessary.
4328- if (superclass && superclass->hasTypeParameter ()) {
4329- superclass = superclass.subst (Substitutions);
4330- }
4331- #endif
4306+ auto size = OpaqueTypeArchetypeType::totalSizeToAlloc<
4307+ ProtocolDecl *, Type, LayoutConstraint>(
4308+ conformsTo.size (), superclass ? 1 : 0 , layout ? 1 : 0 );
4309+ ASTContext &ctx = interfaceType->getASTContext ();
4310+ auto mem = ctx.Allocate (size, alignof (OpaqueTypeArchetypeType), arena);
4311+ return ::new (mem)
4312+ OpaqueTypeArchetypeType (environment, properties, interfaceType,
4313+ conformsTo, superclass, layout);
4314+ }
4315+
4316+ Type OpaqueTypeArchetypeType::get (
4317+ OpaqueTypeDecl *Decl, unsigned ordinal, SubstitutionMap Substitutions) {
4318+ // TODO: We could attempt to preserve type sugar in the substitution map.
4319+ // Currently archetypes are assumed to be always canonical in many places,
4320+ // though, so doing so would require fixing those places.
4321+ Substitutions = Substitutions.getCanonical ();
43324322
4333- auto mem = ctx.Allocate (
4334- OpaqueTypeArchetypeType::totalSizeToAlloc<ProtocolDecl *, Type, LayoutConstraint>(
4335- reqs.protos .size (), superclass ? 1 : 0 , reqs.layout ? 1 : 0 ),
4336- alignof (OpaqueTypeArchetypeType),
4337- arena);
4323+ auto &ctx = Decl->getASTContext ();
43384324
4339- auto newOpaque = ::new (mem)
4340- OpaqueTypeArchetypeType (Decl, Substitutions, properties, opaqueParamType,
4341- reqs.protos , superclass, reqs.layout );
4325+ // Look for an opaque archetype environment in the appropriate arena.
4326+ auto properties = getOpaqueTypeArchetypeProperties (Substitutions);
4327+ auto arena = getArena (properties);
4328+ auto &environments
4329+ = ctx.getImpl ().getArena (arena).OpaqueArchetypeEnvironments ;
4330+ GenericEnvironment *env = environments[{Decl, Substitutions}];
43424331
4343- // Look up the insertion point in the folding set again in case something
4344- // invalidated it above.
4345- {
4346- void *insertPos;
4347- auto existing = set.FindNodeOrInsertPos (id, insertPos);
4348- (void )existing;
4349- assert (!existing && " race to create opaque archetype?!" );
4350- set.InsertNode (newOpaque, insertPos);
4332+ // Create the environment if it's missing.
4333+ if (!env) {
4334+ env = GenericEnvironment::forOpaqueType (Decl, Substitutions, arena);
4335+ environments[{Decl, Substitutions}] = env;
43514336 }
43524337
4353- return newOpaque;
4338+ auto opaqueParamType = Decl->getOpaqueGenericParams ()[ordinal];
4339+ return env->getOrCreateArchetypeFromInterfaceType (opaqueParamType);
43544340}
43554341
43564342CanOpenedArchetypeType OpenedArchetypeType::get (Type existential,
@@ -4411,15 +4397,11 @@ GenericEnvironment *OpenedArchetypeType::getGenericEnvironment() const {
44114397 if (Environment)
44124398 return Environment;
44134399
4414- auto thisType = Type ( const_cast <OpenedArchetypeType*>(this ) );
4400+ auto thisType = const_cast <OpenedArchetypeType*>(this );
44154401 auto &ctx = thisType->getASTContext ();
44164402 // Create a generic environment to represent the opened type.
44174403 auto signature = ctx.getOpenedArchetypeSignature (Opened);
4418- auto *env = GenericEnvironment::getIncomplete (signature);
4419- env->addMapping (signature.getGenericParams ().front ().getPointer (), thisType);
4420- Environment = env;
4421-
4422- return env;
4404+ return GenericEnvironment::forOpenedExistential (signature, thisType);
44234405}
44244406
44254407CanType OpenedArchetypeType::getAny (Type existential) {
@@ -4575,9 +4557,43 @@ GenericEnvironment *GenericEnvironment::getIncomplete(
45754557
45764558 // Allocate and construct the new environment.
45774559 unsigned numGenericParams = signature.getGenericParams ().size ();
4578- size_t bytes = totalSizeToAlloc<Type>(numGenericParams);
4560+ size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap, Type>(
4561+ 0 , 0 , numGenericParams);
4562+ void *mem = ctx.Allocate (bytes, alignof (GenericEnvironment));
4563+ return new (mem) GenericEnvironment (signature, Kind::Normal);
4564+ }
4565+
4566+ // / Create a new generic environment for an opened archetype.
4567+ GenericEnvironment *GenericEnvironment::forOpenedExistential (
4568+ GenericSignature signature, const OpenedArchetypeType *type) {
4569+ auto &ctx = signature->getASTContext ();
4570+
4571+ // Allocate and construct the new environment.
4572+ unsigned numGenericParams = signature.getGenericParams ().size ();
4573+ size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap, Type>(
4574+ 0 , 0 , numGenericParams);
45794575 void *mem = ctx.Allocate (bytes, alignof (GenericEnvironment));
4580- return new (mem) GenericEnvironment (signature);
4576+ auto env = new (mem) GenericEnvironment (signature, Kind::OpenedExistential);
4577+ env->addMapping (
4578+ signature.getGenericParams ().front (),
4579+ Type (const_cast <OpenedArchetypeType *>(type)));
4580+ return env;
4581+ }
4582+
4583+ // / Create a new generic environment for an opaque type with the given set of
4584+ // / outer substitutions.
4585+ GenericEnvironment *GenericEnvironment::forOpaqueType (
4586+ OpaqueTypeDecl *opaque, SubstitutionMap subs, AllocationArena arena) {
4587+ auto &ctx = opaque->getASTContext ();
4588+
4589+ // Allocate and construct the new environment.
4590+ auto signature = opaque->getOpaqueInterfaceGenericSignature ();
4591+ unsigned numGenericParams = signature.getGenericParams ().size ();
4592+ size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap, Type>(
4593+ 1 , 1 , numGenericParams);
4594+ void *mem = ctx.Allocate (bytes, alignof (GenericEnvironment), arena);
4595+ auto env = new (mem) GenericEnvironment (GenericSignature (), opaque, subs);
4596+ return env;
45814597}
45824598
45834599void DeclName::CompoundDeclName::Profile (llvm::FoldingSetNodeID &id,
0 commit comments