[CS] Connect isolated conjunctions to referenced VarDecls

Currently we only consider ParamDecls, but isolated
conjunctions can reference external VarDecls too.

This fixes a spurious "cannot reference invalid declaration"
error when the result builder transform is disabled
in the test case rdar104687668.swift. It also fixes
the attached test case, where an if expression
references a pattern var in a for loop.

rdar://105080067
This commit is contained in:
Hamish Knight
2023-02-06 14:25:13 +00:00
parent a490db377a
commit 6c4b3daa23
2 changed files with 12 additions and 6 deletions

View File

@@ -227,24 +227,24 @@ private:
}
};
/// Find any references to not yet resolved outer closure parameters
/// used in the body of the inner closure. This is required because
/// Find any references to not yet resolved outer VarDecls (including closure
/// parameters) used in the body of the inner closure. This is required because
/// isolated conjunctions, just like single-expression closures, have
/// to be connected to type variables they are going to use, otherwise
/// they'll get placed in a separate solver component and would never
/// produce a solution.
class UnresolvedClosureParameterCollector : public ASTWalker {
class UnresolvedVarCollector : public ASTWalker {
ConstraintSystem &CS;
llvm::SmallSetVector<TypeVariableType *, 4> Vars;
public:
UnresolvedClosureParameterCollector(ConstraintSystem &cs) : CS(cs) {}
UnresolvedVarCollector(ConstraintSystem &cs) : CS(cs) {}
PreWalkResult<Expr *> walkToExprPre(Expr *expr) override {
if (auto *DRE = dyn_cast<DeclRefExpr>(expr)) {
auto *decl = DRE->getDecl();
if (isa<ParamDecl>(decl)) {
if (isa<VarDecl>(decl)) {
if (auto type = CS.getTypeIfAvailable(decl)) {
if (auto *typeVar = type->getAs<TypeVariableType>()) {
Vars.insert(typeVar);
@@ -342,7 +342,7 @@ static void createConjunction(ConstraintSystem &cs,
isIsolated = true;
}
UnresolvedClosureParameterCollector paramCollector(cs);
UnresolvedVarCollector paramCollector(cs);
for (const auto &entry : elements) {
ASTNode element = std::get<0>(entry);

View File

@@ -0,0 +1,6 @@
// RUN: %target-typecheck-verify-swift
// rdar://105080067 - This isn't currently allowed but make sure we don't
// emit a spurious "cannot reference invalid declaration" error.
for b in [true] where if b { true } else { false } {}
// expected-error@-1 {{'if' may only be used as expression in return, throw, or as the source of an assignment}}