Skip to content

[6.2] [Sema] Continue type-checking for body when preamble fails #81554

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions lib/Sema/TypeCheckStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1434,8 +1434,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
}

Stmt *visitForEachStmt(ForEachStmt *S) {
if (TypeChecker::typeCheckForEachPreamble(DC, S))
return nullptr;
TypeChecker::typeCheckForEachPreamble(DC, S);

// Type-check the body of the loop.
auto sourceFile = DC->getParentSourceFile();
Expand Down
6 changes: 4 additions & 2 deletions test/Parse/recovery.swift
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,10 @@ func missingControllingExprInForEach() {
// The #if block is used to provide a scope for the for stmt to force it to end
// where necessary to provoke the crash.
#if true // <rdar://problem/21679557> compiler crashes on "for{{"
// expected-error @+2 {{expected pattern}}
// expected-error @+1 {{expected Sequence expression for for-each loop}}
// expected-error @+4 {{expected pattern}}
// expected-error @+3 {{expected Sequence expression for for-each loop}}
// expected-error @+2 {{closure expression is unused}}
// expected-note @+1 {{did you mean to use a 'do' statement?}}
for{{ // expected-note 2 {{to match this opening '{'}}
#endif // expected-error {{expected '}' at end of closure}} expected-error {{expected '}' at end of brace statement}}

Expand Down
4 changes: 2 additions & 2 deletions test/stmt/c_style_for.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ for ; other<count; other+=1 { // expected-error {{C-style for statement was remo
}

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

for (var m : Int8 = start; m < count; m+=1) { // expected-error {{C-style for statement was removed in Swift 3}} {{none}}
m += 3
m += 3 // expected-error {{cannot find 'm' in scope}}
}
13 changes: 13 additions & 0 deletions test/stmt/foreach.swift
Original file line number Diff line number Diff line change
Expand Up @@ -351,3 +351,16 @@ do {
}
}
}

// Make sure the bodies still type-check okay if the preamble is invalid.
func testInvalidPreamble() {
func takesAutoclosure(_ x: @autoclosure () -> Int) -> Int { 0 }

for _ in undefined { // expected-error {{cannot find 'undefined' in scope}}
let a = takesAutoclosure(0) // Fine
}
for x in undefined { // expected-error {{cannot find 'undefined' in scope}}
let b: Int = x // No type error, `x` is invalid.
_ = "" as Int // expected-error {{cannot convert value of type 'String' to type 'Int' in coercion}}
}
}