Skip to content

Commit ae8f1aa

Browse files
committed
[AST] Allocate PlaceholderTypes in the correct arena
We shouldn't be allocating placeholders for type variables in the permanent arena, and we should be caching them such that equality works.
1 parent a8a0fa9 commit ae8f1aa

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

lib/AST/ASTContext.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ struct ASTContext::Implementation {
431431
llvm::DenseMap<Type, InOutType*> InOutTypes;
432432
llvm::DenseMap<std::pair<Type, void*>, DependentMemberType *>
433433
DependentMemberTypes;
434+
llvm::DenseMap<void *, PlaceholderType *> PlaceholderTypes;
434435
llvm::DenseMap<Type, DynamicSelfType *> DynamicSelfTypes;
435436
llvm::DenseMap<std::pair<EnumDecl*, Type>, EnumType*> EnumTypes;
436437
llvm::DenseMap<std::pair<StructDecl*, Type>, StructType*> StructTypes;
@@ -3125,8 +3126,27 @@ Type ErrorType::get(Type originalType) {
31253126

31263127
Type PlaceholderType::get(ASTContext &ctx, Originator originator) {
31273128
assert(originator);
3128-
return new (ctx, AllocationArena::Permanent)
3129+
3130+
auto hasTypeVariables = [&]() -> bool {
3131+
if (originator.is<TypeVariableType *>())
3132+
return true;
3133+
3134+
if (auto *depTy = originator.dyn_cast<DependentMemberType *>())
3135+
return depTy->hasTypeVariable();
3136+
3137+
return false;
3138+
}();
3139+
auto arena = hasTypeVariables ? AllocationArena::ConstraintSolver
3140+
: AllocationArena::Permanent;
3141+
3142+
auto &cache = ctx.getImpl().getArena(arena).PlaceholderTypes;
3143+
auto &entry = cache[originator.getOpaqueValue()];
3144+
if (entry)
3145+
return entry;
3146+
3147+
entry = new (ctx, arena)
31293148
PlaceholderType(ctx, originator, RecursiveTypeProperties::HasPlaceholder);
3149+
return entry;
31303150
}
31313151

31323152
BuiltinIntegerType *BuiltinIntegerType::get(BuiltinIntegerWidth BitWidth,

test/Constraints/rdar44770297.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,8 @@ func foo<T: P>(_: () throws -> T) -> T.A? { // expected-note {{where 'T' = 'Neve
88
fatalError()
99
}
1010

11-
let _ = foo() {fatalError()} & nil // expected-error {{global function 'foo' requires that 'Never' conform to 'P'}}
11+
let _ = foo() {fatalError()} & nil
12+
// expected-error@-1 {{global function 'foo' requires that 'Never' conform to 'P'}}
13+
// expected-error@-2 {{value of optional type 'Never.A?' must be unwrapped to a value of type 'Never.A'}}
14+
// expected-note@-3 {{coalesce using '??' to provide a default when the optional value contains 'nil'}}
15+
// expected-note@-4 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}

0 commit comments

Comments
 (0)