Skip to content

Commit 09bb346

Browse files
committed
[CS] Walk UnresolvedDeclRefExprs in UnresolvedVarCollector
This matches what we do in VarRefCollector, and is needed because we currently delay the pre-checking of patterns due to the fact that we don't resolve them until CSGen. We ought to consider changing this, but until then, adjust the logic here to ensure we properly connect an ExprPattern that references an outer var with any type variables it may involve. rdar://112264204
1 parent aad2b6e commit 09bb346

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

lib/Sema/CSSyntacticElement.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,27 @@ class UnresolvedVarCollector : public ASTWalker {
275275
}
276276
}
277277
}
278+
279+
// FIXME: We can see UnresolvedDeclRefExprs here because we don't walk into
280+
// patterns when running preCheckExpression, since we don't resolve patterns
281+
// until CSGen. We ought to consider moving pattern resolution into
282+
// pre-checking, which would allow us to pre-check patterns normally.
283+
if (auto *declRef = dyn_cast<UnresolvedDeclRefExpr>(expr)) {
284+
auto name = declRef->getName();
285+
auto loc = declRef->getLoc();
286+
if (name.isSimpleName() && loc.isValid()) {
287+
auto *varDecl =
288+
dyn_cast_or_null<VarDecl>(ASTScope::lookupSingleLocalDecl(
289+
CS.DC->getParentSourceFile(), name.getFullName(), loc));
290+
if (varDecl) {
291+
if (auto varType = CS.getTypeIfAvailable(varDecl)) {
292+
SmallPtrSet<TypeVariableType *, 4> typeVars;
293+
varType->getTypeVariables(typeVars);
294+
Vars.insert(typeVars.begin(), typeVars.end());
295+
}
296+
}
297+
}
298+
}
278299
return Action::Continue(expr);
279300
}
280301

test/Constraints/rdar112264204.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// rdar://112264204: Make sure we can type-check this.
4+
func foo(_ fn: (Int) -> Void) {}
5+
6+
func bar(_ x: Int) {
7+
foo { [x] y in
8+
switch y {
9+
case x:
10+
()
11+
default:
12+
()
13+
}
14+
}
15+
}

0 commit comments

Comments
 (0)