@@ -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;
@@ -618,7 +622,6 @@ struct ASTContext::Implementation {
618
622
llvm::DenseMap<BuiltinIntegerWidth, BuiltinIntegerType*> IntegerTypes;
619
623
llvm::FoldingSet<BuiltinVectorType> BuiltinVectorTypes;
620
624
llvm::FoldingSet<DeclName::CompoundDeclName> CompoundNames;
621
- llvm::DenseMap<UUID, GenericEnvironment *> OpenedExistentialEnvironments;
622
625
llvm::DenseMap<UUID, GenericEnvironment *> OpenedElementEnvironments;
623
626
llvm::FoldingSet<IndexSubset> IndexSubsets;
624
627
llvm::FoldingSet<AutoDiffDerivativeFunctionIdentifier>
@@ -863,7 +866,6 @@ void ASTContext::Implementation::dump(llvm::raw_ostream &os) const {
863
866
SIZE_AND_BYTES (SILBlockStorageTypes);
864
867
SIZE_AND_BYTES (SILMoveOnlyWrappedTypes);
865
868
SIZE_AND_BYTES (IntegerTypes);
866
- SIZE_AND_BYTES (OpenedExistentialEnvironments);
867
869
SIZE_AND_BYTES (OpenedElementEnvironments);
868
870
SIZE_AND_BYTES (ForeignRepresentableCache);
869
871
SIZE (SearchPathsSet);
@@ -3125,7 +3127,6 @@ size_t ASTContext::getTotalMemory() const {
3125
3127
// getImpl().BuiltinVectorTypes ?
3126
3128
// getImpl().GenericSignatures ?
3127
3129
// getImpl().CompoundNames ?
3128
- getImpl ().OpenedExistentialEnvironments .getMemorySize () +
3129
3130
getImpl ().Permanent .getTotalMemory ();
3130
3131
3131
3132
Size += getSolverMemory ();
@@ -3162,7 +3163,9 @@ size_t ASTContext::Implementation::Arena::getTotalMemory() const {
3162
3163
llvm::capacity_in_bytes (StructTypes) +
3163
3164
llvm::capacity_in_bytes (ClassTypes) +
3164
3165
llvm::capacity_in_bytes (ProtocolTypes) +
3165
- llvm::capacity_in_bytes (DynamicSelfTypes);
3166
+ llvm::capacity_in_bytes (DynamicSelfTypes) +
3167
+ OpaqueArchetypeEnvironments.getMemorySize () +
3168
+ OpenedExistentialEnvironments.getMemorySize ();
3166
3169
// FunctionTypes ?
3167
3170
// UnboundGenericTypes ?
3168
3171
// BoundGenericTypes ?
@@ -3209,6 +3212,7 @@ void ASTContext::Implementation::Arena::dump(llvm::raw_ostream &os) const {
3209
3212
SIZE (ParameterizedProtocolTypes);
3210
3213
SIZE (LayoutConstraints);
3211
3214
SIZE_AND_BYTES (OpaqueArchetypeEnvironments);
3215
+ SIZE_AND_BYTES (OpenedExistentialEnvironments);
3212
3216
SIZE (FunctionTypes);
3213
3217
SIZE (NormalConformances);
3214
3218
SIZE (SelfConformances);
@@ -5295,7 +5299,7 @@ OpaqueTypeArchetypeType *OpaqueTypeArchetypeType::getNew(
5295
5299
ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
5296
5300
LayoutConstraint layout) {
5297
5301
auto properties = getOpaqueTypeArchetypeProperties (
5298
- environment->getOpaqueSubstitutions ());
5302
+ environment->getOuterSubstitutions ());
5299
5303
auto arena = getArena (properties);
5300
5304
auto size = OpaqueTypeArchetypeType::totalSizeToAlloc<
5301
5305
ProtocolDecl *, Type, LayoutConstraint>(
@@ -5313,26 +5317,39 @@ Type OpaqueTypeArchetypeType::get(
5313
5317
return env->getOrCreateArchetypeFromInterfaceType (interfaceType);
5314
5318
}
5315
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
+
5316
5334
CanTypeWrapper<OpenedArchetypeType> OpenedArchetypeType::getNew (
5317
5335
GenericEnvironment *environment, Type interfaceType,
5318
5336
ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
5319
5337
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>(
5329
5343
conformsTo.size (),
5330
5344
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);
5333
5349
5334
5350
return CanOpenedArchetypeType (::new (mem) OpenedArchetypeType (
5335
- environment, interfaceType, conformsTo, superclass, layout));
5351
+ environment, interfaceType, conformsTo, superclass, layout,
5352
+ properties));
5336
5353
}
5337
5354
5338
5355
CanTypeWrapper<OpenedArchetypeType>
@@ -5353,7 +5370,7 @@ CanOpenedArchetypeType OpenedArchetypeType::get(CanType existential,
5353
5370
5354
5371
auto *genericEnv =
5355
5372
GenericEnvironment::forOpenedExistential (
5356
- existential, GenericSignature (), *knownID);
5373
+ existential, SubstitutionMap (), *knownID);
5357
5374
5358
5375
// Map the interface type into that environment.
5359
5376
auto result = genericEnv->mapTypeIntoContext (interfaceType)
@@ -5508,10 +5525,11 @@ GenericEnvironment *GenericEnvironment::forPrimary(GenericSignature signature) {
5508
5525
5509
5526
// Allocate and construct the new environment.
5510
5527
unsigned numGenericParams = signature.getGenericParams ().size ();
5511
- size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
5528
+ size_t bytes = totalSizeToAlloc<SubstitutionMap,
5529
+ OpaqueEnvironmentData,
5512
5530
OpenedExistentialEnvironmentData,
5513
5531
OpenedElementEnvironmentData, Type>(
5514
- 0 , 0 , 0 , numGenericParams);
5532
+ 0 , 0 , 0 , 0 , numGenericParams);
5515
5533
void *mem = ctx.Allocate (bytes, alignof (GenericEnvironment));
5516
5534
return new (mem) GenericEnvironment (signature);
5517
5535
}
@@ -5537,10 +5555,11 @@ GenericEnvironment *GenericEnvironment::forOpaqueType(
5537
5555
// Allocate and construct the new environment.
5538
5556
auto signature = opaque->getOpaqueInterfaceGenericSignature ();
5539
5557
unsigned numGenericParams = signature.getGenericParams ().size ();
5540
- size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
5558
+ size_t bytes = totalSizeToAlloc<SubstitutionMap,
5559
+ OpaqueEnvironmentData,
5541
5560
OpenedExistentialEnvironmentData,
5542
5561
OpenedElementEnvironmentData, Type>(
5543
- 1 , 0 , 0 , numGenericParams);
5562
+ 1 , 1 , 0 , 0 , numGenericParams);
5544
5563
void *mem = ctx.Allocate (bytes, alignof (GenericEnvironment), arena);
5545
5564
env = new (mem) GenericEnvironment (signature, opaque, subs);
5546
5565
@@ -5553,46 +5572,49 @@ GenericEnvironment *GenericEnvironment::forOpaqueType(
5553
5572
// / Create a new generic environment for an opened archetype.
5554
5573
GenericEnvironment *
5555
5574
GenericEnvironment::forOpenedExistential (
5556
- Type existential, GenericSignature parentSig , UUID uuid) {
5575
+ Type existential, SubstitutionMap subs , UUID uuid) {
5557
5576
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 ();
5567
5582
5568
5583
auto &ctx = existential->getASTContext ();
5569
5584
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);
5573
5593
5574
- if (found != openedExistentialEnvironments .end ()) {
5594
+ if (found != environments .end ()) {
5575
5595
auto *existingEnv = found->second ;
5576
5596
assert (existingEnv->getOpenedExistentialType ()->isEqual (existential));
5577
- assert (existingEnv->getOpenedExistentialParentSignature (). getPointer () == parentSig. getPointer () );
5597
+ assert (existingEnv->getOuterSubstitutions () == subs );
5578
5598
assert (existingEnv->getOpenedExistentialUUID () == uuid);
5579
5599
5580
5600
return existingEnv;
5581
5601
}
5582
5602
5603
+ auto parentSig = subs.getGenericSignature ().getCanonicalSignature ();
5583
5604
auto signature = ctx.getOpenedExistentialSignature (existential, parentSig);
5584
5605
5585
5606
// Allocate and construct the new environment.
5586
5607
unsigned numGenericParams = signature.getGenericParams ().size ();
5587
- size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
5608
+ size_t bytes = totalSizeToAlloc<SubstitutionMap,
5609
+ OpaqueEnvironmentData,
5588
5610
OpenedExistentialEnvironmentData,
5589
5611
OpenedElementEnvironmentData, Type>(
5590
- 0 , 1 , 0 , numGenericParams);
5612
+ 1 , 0 , 1 , 0 , numGenericParams);
5591
5613
void *mem = ctx.Allocate (bytes, alignof (GenericEnvironment));
5592
5614
auto *genericEnv =
5593
- new (mem) GenericEnvironment (signature, existential, parentSig , uuid);
5615
+ new (mem) GenericEnvironment (signature, existential, subs , uuid);
5594
5616
5595
- openedExistentialEnvironments[uuid ] = genericEnv;
5617
+ environments[key ] = genericEnv;
5596
5618
5597
5619
return genericEnv;
5598
5620
}
@@ -5621,11 +5643,12 @@ GenericEnvironment::forOpenedElement(GenericSignature signature,
5621
5643
// Allocate and construct the new environment.
5622
5644
unsigned numGenericParams = signature.getGenericParams ().size ();
5623
5645
unsigned numOpenedParams = signature.getInnermostGenericParams ().size ();
5624
- size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
5646
+ size_t bytes = totalSizeToAlloc<SubstitutionMap,
5647
+ OpaqueEnvironmentData,
5625
5648
OpenedExistentialEnvironmentData,
5626
5649
OpenedElementEnvironmentData,
5627
5650
Type>(
5628
- 0 , 0 , 1 , numGenericParams + numOpenedParams);
5651
+ 1 , 0 , 0 , 1 , numGenericParams + numOpenedParams);
5629
5652
void *mem = ctx.Allocate (bytes, alignof (GenericEnvironment));
5630
5653
auto *genericEnv = new (mem) GenericEnvironment (signature,
5631
5654
uuid, shapeClass,
0 commit comments