Skip to content

Commit b405cee

Browse files
committed
[ConstraintSystem] Bring back one-way pattern solving for for-in statements (outside closures)
Type-checker separates `where` clause from `for-in` statement's pattern/sequence in closure contexts which works as a natural barrier for inference, but for-in statements in i.e. function bodies still type-check all of the for-in statement components together, so we need to make sure that where clause cannot be used to infer a type of the pattern before its sequence expression. Resolves: rdar://117220710
1 parent 41dc466 commit b405cee

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

include/swift/Sema/SyntacticElementTarget.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,8 @@ class SyntacticElementTarget {
469469
bool shouldBindPatternVarsOneWay() const {
470470
if (kind == Kind::expression)
471471
return expression.bindPatternVarsOneWay;
472+
if (kind == Kind::forEachStmt)
473+
return !ignoreForEachWhereClause() && forEachStmt.stmt->getWhere();
472474
return false;
473475
}
474476

test/stmt/foreach.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,3 +295,24 @@ do {
295295
}
296296
}
297297
}
298+
299+
// rdar://117220710 - The compiler incorrectly infers `v` pattern to be optional.
300+
do {
301+
struct S {
302+
var test: Int
303+
}
304+
305+
func check(_: S?, _: S?) -> Bool { false }
306+
307+
func test(data: [S]?, exclusion: S?) {
308+
for v in data ?? [] where check(v, exclusion) {
309+
_ = v.test // Ok
310+
}
311+
}
312+
313+
let _ = { (data: [S]?, exclusion: S?) in
314+
for v in data ?? [] where check(v, exclusion) {
315+
_ = v.test // Ok
316+
}
317+
}
318+
}

0 commit comments

Comments
 (0)