Skip to content

Commit abf0808

Browse files
committed
[Sema] Continue type-checking for body when preamble fails
Skipping type-checking the body when the preamble fails to type-check seems to be more of a historical artifact than intentional behavior. Certain elements of the body may still get type-checked through request evaluation, and as such may introduce autoclosures that won't be properly contextualized. Make sure we continue type-checking the body even if the preamble fails. We already invalidate any variables bound in the element pattern, so downstream type-checking should be able to handle it just fine. This ensures autoclosures get contextualized, and that we're still able to provide semantic diagnostics for other issues in the body. rdar://136500008
1 parent 5856ec0 commit abf0808

File tree

4 files changed

+20
-6
lines changed

4 files changed

+20
-6
lines changed

lib/Sema/TypeCheckStmt.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,8 +1433,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
14331433
}
14341434

14351435
Stmt *visitForEachStmt(ForEachStmt *S) {
1436-
if (TypeChecker::typeCheckForEachPreamble(DC, S))
1437-
return nullptr;
1436+
TypeChecker::typeCheckForEachPreamble(DC, S);
14381437

14391438
// Type-check the body of the loop.
14401439
auto sourceFile = DC->getParentSourceFile();

test/Parse/recovery.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,10 @@ func missingControllingExprInForEach() {
210210
// The #if block is used to provide a scope for the for stmt to force it to end
211211
// where necessary to provoke the crash.
212212
#if true // <rdar://problem/21679557> compiler crashes on "for{{"
213-
// expected-error @+2 {{expected pattern}}
214-
// expected-error @+1 {{expected Sequence expression for for-each loop}}
213+
// expected-error @+4 {{expected pattern}}
214+
// expected-error @+3 {{expected Sequence expression for for-each loop}}
215+
// expected-error @+2 {{closure expression is unused}}
216+
// expected-note @+1 {{did you mean to use a 'do' statement?}}
215217
for{{ // expected-note 2 {{to match this opening '{'}}
216218
#endif // expected-error {{expected '}' at end of closure}} expected-error {{expected '}' at end of brace statement}}
217219

test/stmt/c_style_for.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ for ; other<count; other+=1 { // expected-error {{C-style for statement was remo
3232
}
3333

3434
for (var number : Int8 = start; number < count; number+=1) { // expected-error {{C-style for statement was removed in Swift 3}} {{none}}
35-
print(number)
35+
print(number) // expected-error {{cannot find 'number' in scope}}
3636
}
3737

3838
for (var m : Int8 = start; m < count; m+=1) { // expected-error {{C-style for statement was removed in Swift 3}} {{none}}
39-
m += 3
39+
m += 3 // expected-error {{cannot find 'm' in scope}}
4040
}

test/stmt/foreach.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,3 +351,16 @@ do {
351351
}
352352
}
353353
}
354+
355+
// Make sure the bodies still type-check okay if the preamble is invalid.
356+
func testInvalidPreamble() {
357+
func takesAutoclosure(_ x: @autoclosure () -> Int) -> Int { 0 }
358+
359+
for _ in undefined { // expected-error {{cannot find 'undefined' in scope}}
360+
let a = takesAutoclosure(0) // Fine
361+
}
362+
for x in undefined { // expected-error {{cannot find 'undefined' in scope}}
363+
let b: Int = x // No type error, `x` is invalid.
364+
_ = "" as Int // expected-error {{cannot convert value of type 'String' to type 'Int' in coercion}}
365+
}
366+
}

0 commit comments

Comments
 (0)