From 09bb346b037ceb789f7d917371998fa1db3b2b51 Mon Sep 17 00:00:00 2001 From: Hamish Knight Date: Mon, 17 Jul 2023 17:32:46 +0100 Subject: [PATCH] [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 --- lib/Sema/CSSyntacticElement.cpp | 21 +++++++++++++++++++++ test/Constraints/rdar112264204.swift | 15 +++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 test/Constraints/rdar112264204.swift diff --git a/lib/Sema/CSSyntacticElement.cpp b/lib/Sema/CSSyntacticElement.cpp index 26465899c3d..9ca79e476fd 100644 --- a/lib/Sema/CSSyntacticElement.cpp +++ b/lib/Sema/CSSyntacticElement.cpp @@ -275,6 +275,27 @@ public: } } } + + // FIXME: We can see UnresolvedDeclRefExprs here because we don't walk into + // patterns when running preCheckExpression, since we don't resolve patterns + // until CSGen. We ought to consider moving pattern resolution into + // pre-checking, which would allow us to pre-check patterns normally. + if (auto *declRef = dyn_cast(expr)) { + auto name = declRef->getName(); + auto loc = declRef->getLoc(); + if (name.isSimpleName() && loc.isValid()) { + auto *varDecl = + dyn_cast_or_null(ASTScope::lookupSingleLocalDecl( + CS.DC->getParentSourceFile(), name.getFullName(), loc)); + if (varDecl) { + if (auto varType = CS.getTypeIfAvailable(varDecl)) { + SmallPtrSet typeVars; + varType->getTypeVariables(typeVars); + Vars.insert(typeVars.begin(), typeVars.end()); + } + } + } + } return Action::Continue(expr); } diff --git a/test/Constraints/rdar112264204.swift b/test/Constraints/rdar112264204.swift new file mode 100644 index 00000000000..68768df0774 --- /dev/null +++ b/test/Constraints/rdar112264204.swift @@ -0,0 +1,15 @@ +// RUN: %target-typecheck-verify-swift + +// rdar://112264204: Make sure we can type-check this. +func foo(_ fn: (Int) -> Void) {} + +func bar(_ x: Int) { + foo { [x] y in + switch y { + case x: + () + default: + () + } + } +}