Files
swift-mirror/test/stmt/if_while_var.swift
gregomni ed09da5094 When parsing a statement that expects a brace item list and the "{" isn't where we expect, try to recover by skipping tokens on the same line until we find an open brace, and use that as
the item list if we find it. (While still erroring that we expected a brace on the first bad token.) Improves recovery in general and in SR-5943 in particular.
2017-09-25 07:29:35 -07:00

145 lines
6.2 KiB
Swift

// RUN: %target-typecheck-verify-swift
struct NonOptionalStruct {}
enum NonOptionalEnum { case foo }
func foo() -> Int? { return .none }
func nonOptionalStruct() -> NonOptionalStruct { fatalError() }
func nonOptionalEnum() -> NonOptionalEnum { fatalError() }
func use(_ x: Int) {}
func modify(_ x: inout Int) {}
if let x = foo() {
use(x)
modify(&x) // expected-error{{cannot pass immutable value as inout argument: 'x' is a 'let' constant}}
}
use(x) // expected-error{{unresolved identifier 'x'}}
if var x = foo() {
use(x)
modify(&x)
}
use(x) // expected-error{{unresolved identifier 'x'}}
if let x = nonOptionalStruct() { } // expected-error{{initializer for conditional binding must have Optional type, not 'NonOptionalStruct'}}
if let x = nonOptionalEnum() { } // expected-error{{initializer for conditional binding must have Optional type, not 'NonOptionalEnum'}}
guard let _ = nonOptionalStruct() else { fatalError() } // expected-error{{initializer for conditional binding must have Optional type, not 'NonOptionalStruct'}}
guard let _ = nonOptionalEnum() else { fatalError() } // expected-error{{initializer for conditional binding must have Optional type, not 'NonOptionalEnum'}}
if case let x? = nonOptionalStruct() { } // expected-error{{'?' pattern cannot match values of type 'NonOptionalStruct'}}
if case let x? = nonOptionalEnum() { } // expected-error{{'?' pattern cannot match values of type 'NonOptionalEnum'}}
class B {} // expected-note * {{did you mean 'B'?}}
class D : B {}// expected-note * {{did you mean 'D'?}}
// TODO poor recovery in these cases
if let {} // expected-error {{expected '{' after 'if' condition}} expected-error {{pattern matching in a condition requires the 'case' keyword}}
if let x = {} // expected-error{{'{' after 'if'}} expected-error {{variable binding in a condition requires an initializer}} expected-error{{initializer for conditional binding must have Optional type, not '() -> ()'}}
if let x = foo() {
} else {
// TODO: more contextual error? "x is only available on the true branch"?
use(x) // expected-error{{unresolved identifier 'x'}}
}
if let x = foo() {
use(x)
} else if let y = foo() { // expected-note {{did you mean 'y'?}}
use(x) // expected-error{{unresolved identifier 'x'}}
use(y)
} else {
use(x) // expected-error{{unresolved identifier 'x'}}
use(y) // expected-error{{unresolved identifier 'y'}}
}
var opt: Int? = .none
if let x = opt {} // expected-warning {{value 'x' was defined but never used; consider replacing with boolean test}}
if var x = opt {} // expected-warning {{value 'x' was defined but never used; consider replacing with boolean test}}
// <rdar://problem/20800015> Fix error message for invalid if-let
let someInteger = 1
if let y = someInteger {} // expected-error {{initializer for conditional binding must have Optional type, not 'Int'}}
if case let y? = someInteger {} // expected-error {{'?' pattern cannot match values of type 'Int'}}
// Test multiple clauses on "if let".
if let x = opt, let y = opt, x != y,
let a = opt, var b = opt { // expected-warning {{immutable value 'a' was never used; consider replacing with '_' or removing it}} expected-warning {{variable 'b' was never used; consider replacing with '_' or removing it}}
}
// Leading boolean conditional.
if 1 != 2, let x = opt,
y = opt, // expected-error {{expected 'let' in conditional}} {{4-4=let }}
x != y,
let a = opt, var b = opt { // expected-warning {{immutable value 'a' was never used; consider replacing with '_' or removing it}} expected-warning {{variable 'b' was never used; consider replacing with '_' or removing it}}
}
// <rdar://problem/20457938> typed pattern is not allowed on if/let condition
if 1 != 2, let x : Int? = opt {} // expected-warning {{immutable value 'x' was never used; consider replacing with '_' or removing it}}
// expected-warning @-1 {{explicitly specified type 'Int?' adds an additional level of optional to the initializer, making the optional check always succeed}} {{20-24=Int}}
if 1 != 2, case let x? : Int? = 42 {} // expected-warning {{immutable value 'x' was never used; consider replacing with '_' or removing it}}
// expected-warning @-1 {{non-optional expression of type 'Int' used in a check for optionals}}
// Test error recovery.
// <rdar://problem/19939746> Improve error recovery for malformed if statements
if 1 != 2, { // expected-error {{'() -> ()' is not convertible to 'Bool'}}
} // expected-error {{expected '{' after 'if' condition}}
if 1 != 2, 4 == 57 {}
if 1 != 2, 4 == 57, let x = opt {} // expected-warning {{immutable value 'x' was never used; consider replacing with '_' or removing it}}
// Test that these don't cause the parser to crash.
if true { if a == 0; {} } // expected-error {{use of unresolved identifier 'a'}} expected-error {{expected '{' after 'if' condition}}
if a == 0, where b == 0 {} // expected-error 3{{}} expected-note {{}} {{25-25=do }}
func testIfCase(_ a : Int?) {
if case nil = a, a != nil {}
if case let (b?) = a, b != 42 {}
if let case (b?) = a, b != 42 {} // expected-error {{pattern matching binding is spelled with 'case let', not 'let case'}} {{6-10=}} {{14-14= let}}
if a != nil, let c = a, case nil = a { _ = c}
if let p? = a {_ = p} // expected-error {{pattern matching in a condition implicitly unwraps optionals}} {{11-12=}}
if let .some(x) = a {_ = x} // expected-error {{pattern matching in a condition requires the 'case' keyword}} {{6-6=case }}
if case _ = a {} // expected-warning {{'if' condition is always true}}
while case _ = a {} // expected-warning {{'while' condition is always true}}
}
// <rdar://problem/20883147> Type annotation for 'let' condition still expected to be optional
func testTypeAnnotations() {
if let x: Int = Optional(1) {_ = x}
if let x: Int = .some(1) {_ = x}
if case _ : Int8 = 19 {} // expected-warning {{'if' condition is always true}}
}
func testShadowing(_ a: Int?, b: Int?, c: Int?, d: Int?) {
guard let a = a, let b = a > 0 ? b : nil else { return }
_ = b
if let c = c, let d = c > 0 ? d : nil {
_ = d
}
}
func useInt(_ x: Int) {}
func testWhileScoping(_ a: Int?) {// expected-note {{did you mean 'a'?}}
while let x = a { }
useInt(x) // expected-error{{use of unresolved identifier 'x'}}
}