| // RUN: %target-parse-verify-swift |
| |
| /* block comments */ |
| /* /* nested too */ */ |
| |
| func markUsed<T>(t: T) {} |
| |
| func f1(a: Int, _ y: Int) {} |
| func f2() {} |
| func f3() -> Int {} |
| |
| func invalid_semi() { |
| ; // expected-error {{';' statements are not allowed}} {{3-5=}} |
| } |
| |
| func nested1(x: Int) { |
| var y : Int |
| |
| func nested2(z: Int) -> Int { |
| return x+y+z |
| } |
| |
| nested2(1) |
| } |
| |
| func funcdecl5(a: Int, y: Int) { |
| var x : Int |
| |
| // a few statements |
| if (x != 0) { |
| if (x != 0 || f3() != 0) { |
| // while with and without a space after it. |
| while(true) { 4; 2; 1 } |
| while (true) { 4; 2; 1 } |
| } |
| } |
| |
| // Assignment statement. |
| x = y |
| (x) = y |
| |
| 1 = x // expected-error {{cannot assign to a literal value}} |
| (1) = x // expected-error {{cannot assign to a literal value}} |
| (x:1).x = 1 // expected-error {{cannot assign to immutable expression of type 'Int'}} |
| var tup : (x:Int, y:Int) |
| tup.x = 1 |
| _ = tup |
| |
| let B : Bool |
| |
| // if/then/else. |
| if (B) { |
| } else if (y == 2) { |
| } |
| |
| // FIXME: This diagnostic is terrible - rdar://12939553 |
| if x {} // expected-error {{type 'Int' does not conform to protocol 'BooleanType'}} |
| |
| if true { |
| if (B) { |
| } else { |
| } |
| } |
| |
| if (B) { |
| f1(1,2) |
| } else { |
| f2() |
| } |
| |
| if (B) { |
| if (B) { |
| f1(1,2) |
| } else { |
| f2() |
| } |
| } else { |
| f2() |
| } |
| |
| // while statement. |
| while (B) { |
| } |
| |
| // It's okay to leave out the spaces in these. |
| while(B) {} |
| if(B) {} |
| } |
| |
| struct infloopbool { |
| var boolValue: infloopbool { |
| return self |
| } |
| } |
| |
| func infloopbooltest() { |
| if (infloopbool()) {} // expected-error {{type 'infloopbool' does not conform to protocol 'BooleanType'}} |
| } |
| |
| // test "builder" API style |
| extension Int { |
| static func builder() -> Int { } |
| var builderProp: Int { return 0 } |
| func builder2() {} |
| } |
| Int |
| .builder() |
| .builderProp |
| .builder2() |
| |
| struct SomeGeneric<T> { |
| static func builder() -> SomeGeneric<T> { } |
| var builderProp: SomeGeneric<T> { return .builder() } |
| func builder2() {} |
| } |
| SomeGeneric<Int> |
| .builder() |
| .builderProp |
| .builder2() |
| |
| func for_loop() { |
| var x = 0 |
| for ;; { } // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| for x = 1; x != 42; ++x { } // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| for infloopbooltest(); x != 12; infloopbooltest() {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| |
| for ; { } // expected-error {{expected ';' in 'for' statement}} |
| |
| for var y = 1; y != 42; ++y {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| for (var y = 1; y != 42; ++y) {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| var z = 10 |
| for (; z != 0; --z) {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| for (z = 10; z != 0; --z) {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| for var (a,b) = (0,12); a != b; --b {++a} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| for (var (a,b) = (0,12); a != b; --b) {++a} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| var j, k : Int |
| for ((j,k) = (0,10); j != k; --k) {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| for var i = 0, j = 0; i * j < 10; i++, j++ {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| for j = 0, k = 52; j < k; ++j, --k { } // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| // rdar://19540536 |
| // expected-error@+4{{expected var declaration in a 'for' statement}} |
| // expected-error@+3{{expression resolves to an unused function}} |
| // expected-error@+2{{expected an attribute name}} |
| // expected-error@+1{{braced block of statements is an unused closure}} |
| for @ {} |
| |
| // <rdar://problem/17462274> Is increment in for loop optional? |
| for (let i = 0; i < 10; ) {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| } |
| |
| break // expected-error {{'break' is only allowed inside a loop, if, do, or switch}} |
| continue // expected-error {{'continue' is only allowed inside a loop}} |
| while true { |
| func f() { |
| break // expected-error {{'break' is only allowed inside a loop}} |
| continue // expected-error {{'continue' is only allowed inside a loop}} |
| } |
| |
| // Labeled if |
| MyIf: if 1 != 2 { |
| break MyIf |
| continue MyIf // expected-error {{'continue' cannot be used with if statements}} |
| break // break the while |
| continue // continue the while. |
| } |
| } |
| |
| // Labeled if |
| MyOtherIf: if 1 != 2 { |
| break MyOtherIf |
| continue MyOtherIf // expected-error {{'continue' cannot be used with if statements}} |
| break // expected-error {{unlabeled 'break' is only allowed inside a loop or switch, a labeled break is required to exit an if}} |
| continue // expected-error {{'continue' is only allowed inside a loop}} |
| } |
| |
| do { |
| break // expected-error {{unlabeled 'break' is only allowed inside a loop or switch, a labeled break is required to exit an if or do}} |
| } |
| |
| func tuple_assign() { |
| var a,b,c,d : Int |
| (a,b) = (1,2) |
| func f() -> (Int,Int) { return (1,2) } |
| ((a,b), (c,d)) = (f(), f()) |
| } |
| |
| func missing_semicolons() { |
| var w = 321 |
| func g() {} |
| g() ++w // expected-error{{consecutive statements}} {{6-6=;}} |
| var z = w"hello" // expected-error{{consecutive statements}} {{12-12=;}} |
| class C {}class C2 {} // expected-error{{consecutive statements}} {{14-14=;}} |
| struct S {}struct S2 {} // expected-error{{consecutive statements}} {{14-14=;}} |
| func j() {}func k() {} // expected-error{{consecutive statements}} {{14-14=;}} |
| } |
| |
| //===--- Return statement. |
| |
| return 42 // expected-error {{return invalid outside of a func}} |
| |
| return // expected-error {{return invalid outside of a func}} |
| |
| func NonVoidReturn1() -> Int { |
| return // expected-error {{non-void function should return a value}} |
| } |
| |
| func NonVoidReturn2() -> Int { |
| return + // expected-error {{unary operator cannot be separated from its operand}} {{11-1=}} expected-error {{expected expression in 'return' statement}} |
| } |
| |
| func VoidReturn1() { |
| if true { return } |
| // Semicolon should be accepted -- rdar://11344875 |
| return; // no-error |
| } |
| |
| func VoidReturn2() { |
| return () // no-error |
| } |
| |
| func VoidReturn3() { |
| return VoidReturn2() // no-error |
| } |
| |
| //===--- If statement. |
| |
| func IfStmt1() { |
| if 1 > 0 // expected-error {{expected '{' after 'if' condition}} |
| _ = 42 |
| } |
| |
| func IfStmt2() { |
| if 1 > 0 { |
| } else // expected-error {{expected '{' after 'else'}} |
| _ = 42 |
| } |
| |
| //===--- While statement. |
| |
| func WhileStmt1() { |
| while 1 > 0 // expected-error {{expected '{' after 'while' condition}} |
| _ = 42 |
| } |
| |
| //===-- Do statement. |
| func DoStmt() { |
| // This is just a 'do' statement now. |
| do { |
| } |
| } |
| |
| func DoWhileStmt() { |
| do { // expected-error {{'do-while' statement is not allowed; use 'repeat-while' instead}} {{3-5=repeat}} |
| } while true |
| } |
| |
| //===--- Repeat-while statement. |
| |
| func RepeatWhileStmt1() { |
| repeat {} while true |
| |
| repeat {} while false |
| |
| repeat { break } while true |
| repeat { continue } while true |
| } |
| |
| func RepeatWhileStmt2() { |
| repeat // expected-error {{expected '{' after 'repeat'}} |
| } |
| |
| func RepeatWhileStmt4() { |
| repeat { |
| } while + // expected-error {{unary operator cannot be separated from its operand}} {{12-1=}} expected-error {{expected expression in 'repeat-while' condition}} |
| } |
| |
| func brokenSwitch(x: Int) -> Int { |
| switch x { |
| case .Blah(let rep): // expected-error{{enum case 'Blah' not found in type 'Int'}} |
| return rep |
| } |
| } |
| |
| func breakContinue(x : Int) -> Int { |
| |
| Outer: |
| for _ in 0...1000 { |
| |
| Switch: |
| switch x { |
| case 42: break Outer |
| case 97: continue Outer |
| case 102: break Switch |
| case 13: continue |
| case 139: break // <rdar://problem/16563853> 'break' should be able to break out of switch statements |
| } |
| } |
| |
| // <rdar://problem/16692437> shadowing loop labels should be an error |
| Loop: // expected-note {{previously declared here}} |
| for _ in 0...2 { |
| Loop: // expected-error {{label 'Loop' cannot be reused on an inner statement}} |
| for _ in 0...2 { |
| } |
| } |
| |
| |
| // <rdar://problem/16798323> Following a 'break' statement by another statement on a new line result in an error/fit-it |
| switch 5 { |
| case 5: |
| markUsed("before the break") |
| break |
| markUsed("after the break") // 'markUsed' is not a label for the break. |
| default: |
| markUsed("") |
| } |
| |
| let x : Int? = 42 |
| |
| // <rdar://problem/16879701> Should be able to pattern match 'nil' against optionals |
| switch x { |
| case .Some(42): break |
| case nil: break |
| |
| } |
| |
| } |
| |
| |
| enum MyEnumWithCaseLabels { |
| case Case(one: String, two: Int) |
| } |
| |
| func testMyEnumWithCaseLabels(a : MyEnumWithCaseLabels) { |
| // <rdar://problem/20135489> Enum case labels are ignored in "case let" statements |
| switch a { |
| case let .Case(one: _, two: x): break // ok |
| case let .Case(xxx: _, two: x): break // expected-error {{tuple pattern element label 'xxx' must be 'one'}} |
| // TODO: In principle, reordering like this could be supported. |
| case let .Case(two: _, one: x): break // expected-error {{tuple pattern element label}} |
| } |
| } |
| |
| |
| |
| // "defer" |
| |
| func test_defer(a : Int) { |
| |
| defer { VoidReturn1() } |
| defer { breakContinue(1)+42 } |
| |
| // Ok: |
| defer { while false { break } } |
| |
| // Not ok. |
| while false { defer { break } } // expected-error {{'break' cannot transfer control out of a defer statement}} |
| defer { return } // expected-error {{'return' cannot transfer control out of a defer statement}} |
| } |
| |
| class SomeTestClass { |
| var x = 42 |
| |
| func method() { |
| defer { x = 97 } // self. not required here! |
| } |
| } |
| |
| |
| func test_require(x : Int, y : Int??, cond : Bool) { |
| |
| // These are all ok. |
| guard let a = y else {} |
| markUsed(a) |
| guard let b = y where cond else {} |
| guard case let c = x where cond else {} |
| guard case let Optional.Some(d) = y else {} |
| guard x != 4, case _ = x else { } |
| |
| |
| guard let e where cond else {} // expected-error {{variable binding in a condition requires an initializer}} |
| guard case let f? : Int? where cond else {} // expected-error {{variable binding in a condition requires an initializer}} |
| |
| guard let g = y else { |
| markUsed(g) // expected-error {{variable declared in 'guard' condition is not usable in its body}} |
| } |
| |
| guard let h = y where cond {} // expected-error {{expected 'else' after 'guard' condition}} |
| |
| |
| guard case _ = x else {} // expected-warning {{'guard' condition is always true, body is unreachable}} |
| } |
| |
| func test_is_as_patterns() { |
| switch 4 { |
| case is Int: break // expected-warning {{'is' test is always true}} |
| case _ as Int: break // expected-warning {{'as' test is always true}} |
| case _: break |
| } |
| } |
| |
| // <rdar://problem/21387308> Fuzzing SourceKit: crash in Parser::parseStmtForEach(...) |
| func matching_pattern_recursion() { |
| switch 42 { |
| case { // expected-error {{expression pattern of type '() -> ()' cannot match values of type 'Int'}} |
| for i in zs { |
| } |
| }: break |
| } |
| } |
| |
| // <rdar://problem/18776073> Swift's break operator in switch should be indicated in errors |
| func r18776073(a : Int?) { |
| switch a { |
| case nil: // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{14-14= break}} |
| case _?: break |
| } |
| } |
| |
| // <rdar://problem/22491782> unhelpful error message from "throw nil" |
| func testThrowNil() throws { |
| throw nil // expected-error {{cannot infer concrete ErrorType for thrown 'nil' value}} |
| } |
| |
| |
| // <rdar://problem/16650625> |
| func for_ignored_lvalue_init() { |
| var i = 0 |
| for i; // expected-error {{expression resolves to an unused l-value}} expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| i < 10; ++i {} |
| } |
| |
| // rdar://problem/18643692 |
| func for_loop_multi_iter() { |
| for (var i = 0, x = 0; i < 10; i++, // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} |
| x) { // expected-error {{expression resolves to an unused l-value}} |
| x -= 1 |
| } |
| } |
| |
| // rdar://problem/23684220 |
| // Even if the condition fails to typecheck, save it in the AST anyway; the old |
| // condition may have contained a SequenceExpr. |
| func r23684220(b: Any) { |
| if let _ = b ?? b {} // expected-error {{initializer for conditional binding must have Optional type, not 'Any' (aka 'protocol<>')}} |
| } |
| |
| // Errors in case syntax |
| class |
| case, // expected-error {{expected identifier in enum 'case' declaration}} expected-error {{expected pattern}} |
| case // expected-error {{expected identifier after comma in enum 'case' declaration}} expected-error {{expected identifier in enum 'case' declaration}} expected-error {{enum 'case' is not allowed outside of an enum}} expected-error {{expected pattern}} |
| // NOTE: EOF is important here to properly test a code path that used to crash the parser |