@@ -430,6 +430,7 @@ struct ASTContext::Implementation {
430430 llvm::DenseMap<Type, InOutType*> InOutTypes;
431431 llvm::DenseMap<std::pair<Type, void *>, DependentMemberType *>
432432 DependentMemberTypes;
433+ llvm::DenseMap<void *, PlaceholderType *> PlaceholderTypes;
433434 llvm::DenseMap<Type, DynamicSelfType *> DynamicSelfTypes;
434435 llvm::DenseMap<std::pair<EnumDecl*, Type>, EnumType*> EnumTypes;
435436 llvm::DenseMap<std::pair<StructDecl*, Type>, StructType*> StructTypes;
@@ -1811,9 +1812,8 @@ bool ASTContext::hadError() const {
18111812
18121813// / Retrieve the arena from which we should allocate storage for a type.
18131814static AllocationArena getArena (RecursiveTypeProperties properties) {
1814- bool hasTypeVariable = properties.hasTypeVariable ();
1815- return hasTypeVariable ? AllocationArena::ConstraintSolver
1816- : AllocationArena::Permanent;
1815+ return properties.isSolverAllocated () ? AllocationArena::ConstraintSolver
1816+ : AllocationArena::Permanent;
18171817}
18181818
18191819void ASTContext::addSearchPath (StringRef searchPath, bool isFramework,
@@ -3117,15 +3117,43 @@ Type ErrorType::get(Type originalType) {
31173117 void *mem = ctx.Allocate (sizeof (ErrorType) + sizeof (Type),
31183118 alignof (ErrorType), arena);
31193119 RecursiveTypeProperties properties = RecursiveTypeProperties::HasError;
3120- if (originalProperties.hasTypeVariable ())
3121- properties |= RecursiveTypeProperties::HasTypeVariable;
3120+
3121+ // We need to preserve the solver allocated bit, to ensure any wrapping
3122+ // types are solver allocated too.
3123+ if (originalProperties.isSolverAllocated ())
3124+ properties |= RecursiveTypeProperties::SolverAllocated;
3125+
31223126 return entry = new (mem) ErrorType (ctx, originalType, properties);
31233127}
31243128
31253129Type PlaceholderType::get (ASTContext &ctx, Originator originator) {
31263130 assert (originator);
3127- return new (ctx, AllocationArena::Permanent)
3128- PlaceholderType (ctx, originator, RecursiveTypeProperties::HasPlaceholder);
3131+
3132+ auto originatorProps = [&]() -> RecursiveTypeProperties {
3133+ if (auto *tv = originator.dyn_cast <TypeVariableType *>())
3134+ return tv->getRecursiveProperties ();
3135+
3136+ if (auto *depTy = originator.dyn_cast <DependentMemberType *>())
3137+ return depTy->getRecursiveProperties ();
3138+
3139+ return RecursiveTypeProperties ();
3140+ }();
3141+ auto arena = getArena (originatorProps);
3142+
3143+ auto &cache = ctx.getImpl ().getArena (arena).PlaceholderTypes ;
3144+ auto &entry = cache[originator.getOpaqueValue ()];
3145+ if (entry)
3146+ return entry;
3147+
3148+ RecursiveTypeProperties properties = RecursiveTypeProperties::HasPlaceholder;
3149+
3150+ // We need to preserve the solver allocated bit, to ensure any wrapping
3151+ // types are solver allocated too.
3152+ if (originatorProps.isSolverAllocated ())
3153+ properties |= RecursiveTypeProperties::SolverAllocated;
3154+
3155+ entry = new (ctx, arena) PlaceholderType (ctx, originator, properties);
3156+ return entry;
31293157}
31303158
31313159BuiltinIntegerType *BuiltinIntegerType::get (BuiltinIntegerWidth BitWidth,
@@ -3943,7 +3971,7 @@ isAnyFunctionTypeCanonical(ArrayRef<AnyFunctionType::Param> params,
39433971static RecursiveTypeProperties
39443972getGenericFunctionRecursiveProperties (ArrayRef<AnyFunctionType::Param> params,
39453973 Type result) {
3946- static_assert (RecursiveTypeProperties::BitWidth == 15 ,
3974+ static_assert (RecursiveTypeProperties::BitWidth == 16 ,
39473975 " revisit this if you add new recursive type properties" );
39483976 RecursiveTypeProperties properties;
39493977
@@ -4604,7 +4632,7 @@ CanSILFunctionType SILFunctionType::get(
46044632 void *mem = ctx.Allocate (bytes, alignof (SILFunctionType));
46054633
46064634 RecursiveTypeProperties properties;
4607- static_assert (RecursiveTypeProperties::BitWidth == 15 ,
4635+ static_assert (RecursiveTypeProperties::BitWidth == 16 ,
46084636 " revisit this if you add new recursive type properties" );
46094637 for (auto ¶m : params)
46104638 properties |= param.getInterfaceType ()->getRecursiveProperties ();
0 commit comments