Skip to content

Commit fed705d

Browse files
committed
[CSClosure] Account for partially resolved inner parameter types
It is possible that contextual type of a parameter has been assigned to an anonymous of named argument early, to facilitate closure type checking. Such a type can have type variables inside e.g. ```swift func test<T>(_: (UnsafePointer<T>) -> Void) {} test { ptr in ... } ``` Type variable representing `ptr` in the body of this closure would be bound to `UnsafePointer<$T>` in this case, where `$T` is a type variable for a generic parameter `T`.
1 parent 8867a8d commit fed705d

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

lib/Sema/CSClosure.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,36 @@ class TypeVariableRefFinder : public ASTWalker {
3838
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
3939
if (auto *DRE = dyn_cast<DeclRefExpr>(expr)) {
4040
if (auto type = CS.getTypeIfAvailable(DRE->getDecl())) {
41-
if (auto *typeVar = type->getAs<TypeVariableType>())
41+
// The logic below is handling not-yet resolved parameter
42+
// types referenced in the body e.g. `$0` or `x`.
43+
if (auto *typeVar = type->getAs<TypeVariableType>()) {
4244
referencedVars.insert(typeVar);
45+
46+
// It is possible that contextual type of a parameter
47+
// has been assigned to an anonymous of named argument
48+
// early, to facilitate closure type checking. Such a
49+
// type can have type variables inside e.g.
50+
//
51+
// func test<T>(_: (UnsafePointer<T>) -> Void) {}
52+
//
53+
// test { ptr in
54+
// ...
55+
// }
56+
//
57+
// Type variable representing `ptr` in the body of
58+
// this closure would be bound to `UnsafePointer<$T>`
59+
// in this case, where `$T` is a type variable for a
60+
// generic parameter `T`.
61+
auto simplifiedTy =
62+
CS.getFixedTypeRecursive(typeVar, /*wantRValue=*/false);
63+
64+
if (!simplifiedTy->isEqual(typeVar) &&
65+
simplifiedTy->hasTypeVariable()) {
66+
SmallPtrSet<TypeVariableType *, 4> typeVars;
67+
simplifiedTy->getTypeVariables(typeVars);
68+
referencedVars.insert(typeVars.begin(), typeVars.end());
69+
}
70+
}
4371
}
4472
}
4573

0 commit comments

Comments
 (0)