Skip to content

Commit 97be042

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 91209d4 commit 97be042

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
@@ -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;
@@ -3124,8 +3125,27 @@ Type ErrorType::get(Type originalType) {
31243125

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

31313151
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)