Skip to content

Commit 95f8121

Browse files
authored
[5.3] [CS] Connect closure to referenced vars (#31313)
[5.3] [CS] Connect closure to referenced vars
2 parents 08e5969 + 5ef7645 commit 95f8121

File tree

2 files changed

+27
-15
lines changed

2 files changed

+27
-15
lines changed

lib/Sema/CSGen.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2741,16 +2741,19 @@ namespace {
27412741
auto *locator = CS.getConstraintLocator(closure);
27422742
auto closureType = CS.createTypeVariable(locator, TVO_CanBindToNoEscape);
27432743

2744-
// Collect any references to closure parameters whose types involve type
2745-
// variables from the closure, because there will be a dependency on
2746-
// those type variables once we have generated constraints for the
2747-
// closure body.
2748-
struct CollectParameterRefs : public ASTWalker {
2744+
// Collect any variable references whose types involve type variables,
2745+
// because there will be a dependency on those type variables once we have
2746+
// generated constraints for the closure body. This includes references
2747+
// to other closure params such as in `{ x in { x }}` where the inner
2748+
// closure is dependent on the outer closure's param type, as well as
2749+
// cases like `for i in x where bar({ i })` where there's a dependency on
2750+
// the type variable for the pattern `i`.
2751+
struct CollectVarRefs : public ASTWalker {
27492752
ConstraintSystem &cs;
2750-
llvm::SmallVector<TypeVariableType *, 4> paramRefs;
2753+
llvm::SmallVector<TypeVariableType *, 4> varRefs;
27512754
bool hasErrorExprs = false;
27522755

2753-
CollectParameterRefs(ConstraintSystem &cs) : cs(cs) { }
2756+
CollectVarRefs(ConstraintSystem &cs) : cs(cs) { }
27542757

27552758
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
27562759
// If there are any error expressions in this closure
@@ -2760,21 +2763,21 @@ namespace {
27602763
return {false, nullptr};
27612764
}
27622765

2763-
// Retrieve type variables from references to parameter declarations.
2766+
// Retrieve type variables from references to var decls.
27642767
if (auto *declRef = dyn_cast<DeclRefExpr>(expr)) {
2765-
if (auto *paramDecl = dyn_cast<ParamDecl>(declRef->getDecl())) {
2766-
if (Type paramType = cs.getTypeIfAvailable(paramDecl)) {
2767-
paramType->getTypeVariables(paramRefs);
2768+
if (auto *varDecl = dyn_cast<VarDecl>(declRef->getDecl())) {
2769+
if (auto varType = cs.getTypeIfAvailable(varDecl)) {
2770+
varType->getTypeVariables(varRefs);
27682771
}
27692772
}
27702773
}
27712774

27722775
return { true, expr };
27732776
}
2774-
} collectParameterRefs(CS);
2775-
closure->walk(collectParameterRefs);
2777+
} collectVarRefs(CS);
2778+
closure->walk(collectVarRefs);
27762779

2777-
if (collectParameterRefs.hasErrorExprs)
2780+
if (collectVarRefs.hasErrorExprs)
27782781
return Type();
27792782

27802783
auto inferredType = inferClosureType(closure);
@@ -2784,7 +2787,7 @@ namespace {
27842787
CS.addUnsolvedConstraint(
27852788
Constraint::create(CS, ConstraintKind::DefaultClosureType,
27862789
closureType, inferredType, locator,
2787-
collectParameterRefs.paramRefs));
2790+
collectVarRefs.varRefs));
27882791

27892792
CS.setClosureType(closure, inferredType);
27902793
return closureType;

test/stmt/foreach.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,12 @@ func sr_12398(arr1: [Int], arr2: [(a: Int, b: String)]) {
229229
for (x, y, _) in arr2 {}
230230
// expected-error@-1 {{pattern cannot match values of type '(a: Int, b: String)'}}
231231
}
232+
233+
// rdar://62339835
234+
func testForEachWhereWithClosure(_ x: [Int]) {
235+
func foo<T>(_ fn: () -> T) -> Bool { true }
236+
237+
for i in x where foo({ i }) {}
238+
for i in x where foo({ i.byteSwapped == 5 }) {}
239+
for i in x where x.contains(where: { $0.byteSwapped == i }) {}
240+
}

0 commit comments

Comments
 (0)