@@ -432,6 +432,7 @@ struct ASTContext::Implementation {
432432 llvm::DenseMap<Type, InOutType*> InOutTypes;
433433 llvm::DenseMap<std::pair<Type, void *>, DependentMemberType *>
434434 DependentMemberTypes;
435+ llvm::DenseMap<void *, PlaceholderType *> PlaceholderTypes;
435436 llvm::DenseMap<Type, DynamicSelfType *> DynamicSelfTypes;
436437 llvm::DenseMap<std::pair<EnumDecl*, Type>, EnumType*> EnumTypes;
437438 llvm::DenseMap<std::pair<StructDecl*, Type>, StructType*> StructTypes;
@@ -1801,9 +1802,8 @@ bool ASTContext::hadError() const {
18011802
18021803// / Retrieve the arena from which we should allocate storage for a type.
18031804static AllocationArena getArena (RecursiveTypeProperties properties) {
1804- bool hasTypeVariable = properties.hasTypeVariable ();
1805- return hasTypeVariable ? AllocationArena::ConstraintSolver
1806- : AllocationArena::Permanent;
1805+ return properties.isSolverAllocated () ? AllocationArena::ConstraintSolver
1806+ : AllocationArena::Permanent;
18071807}
18081808
18091809void ASTContext::addSearchPath (StringRef searchPath, bool isFramework,
@@ -3119,15 +3119,43 @@ Type ErrorType::get(Type originalType) {
31193119 void *mem = ctx.Allocate (sizeof (ErrorType) + sizeof (Type),
31203120 alignof (ErrorType), arena);
31213121 RecursiveTypeProperties properties = RecursiveTypeProperties::HasError;
3122- if (originalProperties.hasTypeVariable ())
3123- properties |= RecursiveTypeProperties::HasTypeVariable;
3122+
3123+ // We need to preserve the solver allocated bit, to ensure any wrapping
3124+ // types are solver allocated too.
3125+ if (originalProperties.isSolverAllocated ())
3126+ properties |= RecursiveTypeProperties::SolverAllocated;
3127+
31243128 return entry = new (mem) ErrorType (ctx, originalType, properties);
31253129}
31263130
31273131Type PlaceholderType::get (ASTContext &ctx, Originator originator) {
31283132 assert (originator);
3129- return new (ctx, AllocationArena::Permanent)
3130- PlaceholderType (ctx, originator, RecursiveTypeProperties::HasPlaceholder);
3133+
3134+ auto originatorProps = [&]() -> RecursiveTypeProperties {
3135+ if (auto *tv = originator.dyn_cast <TypeVariableType *>())
3136+ return tv->getRecursiveProperties ();
3137+
3138+ if (auto *depTy = originator.dyn_cast <DependentMemberType *>())
3139+ return depTy->getRecursiveProperties ();
3140+
3141+ return RecursiveTypeProperties ();
3142+ }();
3143+ auto arena = getArena (originatorProps);
3144+
3145+ auto &cache = ctx.getImpl ().getArena (arena).PlaceholderTypes ;
3146+ auto &entry = cache[originator.getOpaqueValue ()];
3147+ if (entry)
3148+ return entry;
3149+
3150+ RecursiveTypeProperties properties = RecursiveTypeProperties::HasPlaceholder;
3151+
3152+ // We need to preserve the solver allocated bit, to ensure any wrapping
3153+ // types are solver allocated too.
3154+ if (originatorProps.isSolverAllocated ())
3155+ properties |= RecursiveTypeProperties::SolverAllocated;
3156+
3157+ entry = new (ctx, arena) PlaceholderType (ctx, originator, properties);
3158+ return entry;
31313159}
31323160
31333161BuiltinIntegerType *BuiltinIntegerType::get (BuiltinIntegerWidth BitWidth,
@@ -3986,7 +4014,7 @@ isAnyFunctionTypeCanonical(ArrayRef<AnyFunctionType::Param> params,
39864014static RecursiveTypeProperties
39874015getGenericFunctionRecursiveProperties (ArrayRef<AnyFunctionType::Param> params,
39884016 Type result) {
3989- static_assert (RecursiveTypeProperties::BitWidth == 16 ,
4017+ static_assert (RecursiveTypeProperties::BitWidth == 17 ,
39904018 " revisit this if you add new recursive type properties" );
39914019 RecursiveTypeProperties properties;
39924020
@@ -4646,7 +4674,7 @@ CanSILFunctionType SILFunctionType::get(
46464674 void *mem = ctx.Allocate (bytes, alignof (SILFunctionType));
46474675
46484676 RecursiveTypeProperties properties;
4649- static_assert (RecursiveTypeProperties::BitWidth == 16 ,
4677+ static_assert (RecursiveTypeProperties::BitWidth == 17 ,
46504678 " revisit this if you add new recursive type properties" );
46514679 for (auto ¶m : params)
46524680 properties |= param.getInterfaceType ()->getRecursiveProperties ();
0 commit comments