Skip to content

Commit 0198a70

Browse files
committed
[Multi-expression closures] Add support for for..in loops.
1 parent 6d57439 commit 0198a70

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

lib/Sema/CSClosure.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,25 @@ class ClosureConstraintGenerator
9494
visit(doStmt->getBody());
9595
}
9696

97+
void visitForEachStmt(ForEachStmt *forEachStmt) {
98+
auto sequenceProto = TypeChecker::getProtocol(
99+
closure->getASTContext(), forEachStmt->getForLoc(),
100+
KnownProtocolKind::Sequence);
101+
assert(sequenceProto && "Missing Sequence protocol");
102+
103+
// Generate constraints for the loop header. This also wires up the
104+
// types for the patterns.
105+
auto target = SolutionApplicationTarget::forForEachStmt(
106+
forEachStmt, sequenceProto, closure, /*bindPatternVarsOneWay=*/true);
107+
if (cs.generateConstraints(target, FreeTypeVariableBinding::Disallow)) {
108+
hadError = true;
109+
}
110+
111+
cs.setSolutionApplicationTarget(forEachStmt, target);
112+
113+
visit(forEachStmt->getBody());
114+
}
115+
97116
void visitGuardStmt(GuardStmt *guardStmt) {
98117
if (cs.generateConstraints(guardStmt->getCond(), closure))
99118
hadError = true;
@@ -159,7 +178,6 @@ class ClosureConstraintGenerator
159178
UNSUPPORTED_STMT(Yield)
160179
UNSUPPORTED_STMT(Defer)
161180
UNSUPPORTED_STMT(DoCatch)
162-
UNSUPPORTED_STMT(ForEach)
163181
UNSUPPORTED_STMT(Switch)
164182
UNSUPPORTED_STMT(Case)
165183
UNSUPPORTED_STMT(Break)
@@ -256,6 +274,19 @@ class ClosureConstraintApplication
256274
return doStmt;
257275
}
258276

277+
ASTNode visitForEachStmt(ForEachStmt *forEachStmt) {
278+
ConstraintSystem &cs = solution.getConstraintSystem();
279+
auto forEachTarget =
280+
rewriteTarget(*cs.getSolutionApplicationTarget(forEachStmt));
281+
if (!forEachTarget)
282+
hadError = true;
283+
284+
auto body = visit(forEachStmt->getBody()).get<Stmt *>();
285+
forEachStmt->setBody(cast<BraceStmt>(body));
286+
287+
return forEachStmt;
288+
}
289+
259290
ASTNode visitGuardStmt(GuardStmt *guardStmt) {
260291
// Rewrite the condition.
261292
if (auto condition = rewriteTarget(
@@ -387,7 +418,6 @@ class ClosureConstraintApplication
387418
UNSUPPORTED_STMT(Yield)
388419
UNSUPPORTED_STMT(Defer)
389420
UNSUPPORTED_STMT(DoCatch)
390-
UNSUPPORTED_STMT(ForEach)
391421
UNSUPPORTED_STMT(Switch)
392422
UNSUPPORTED_STMT(Case)
393423
UNSUPPORTED_STMT(Break)

test/expr/closure/multi_statement.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ func mapWithMoreStatements(ints: [Int]) {
3333
print("still here")
3434
} while random(i)
3535

36+
for j in 0..<i where j % 2 == 0 {
37+
print("even")
38+
}
39+
3640
return String(value)
3741
}
3842
}

0 commit comments

Comments
 (0)