1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
|
// RUN: %target-typecheck-verify-swift -enable-bare-slash-regex -disable-availability-checking -enable-experimental-feature ThenStatements
// Required for experimental features
// REQUIRES: asserts
// Required for regex
// REQUIRES: swift_swift_parser
func then(_: Int = 0, x: Int = 0, fn: () -> Void = {}) {}
func testThenStmt(_ x: Int) {
// These are statements
then x // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
then () // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
then (1) // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
then (1, 2) // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
then "" // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
then []
// expected-error@-1 {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
// expected-error@-2 {{empty collection literal requires an explicit type}}
then [0] // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
then if .random() { 0 } else { 1 }
// expected-error@-1 {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
// expected-error@-2 {{'if' may only be used as expression in return, throw, or as the source of an assignment}}
then -1 // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
then ~1 // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
then /abc/ // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
let x: Int = if .random() {
then .zero
} else {
then 0
}
let y = if .random() { then x } else { then 1 }
let _ = if .random() { (); then y } else { then 1 }
// We don't allow labels on 'then' statements.
let _ = switch Bool.random() {
case true:
a: then 0 // expected-error {{labels are only valid on loops, if, and switch statements}}
case false:
then 1
}
}
func testThenFunctionCalls() {
// These should all be treated as function calls.
then()
then(0)
then(x: 0)
then{}
then {}
}
func testThenLabel() {
then: for then in [0] { // expected-warning {{immutable value 'then' was never used; consider replacing with '_' or removing it}}
break then
continue then
}
}
struct S {
var then: Int
func then(_ x: Int) {}
subscript(x: Int) -> Void { () }
mutating func testThenAsMember() -> Int {
do {
then // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
} // expected-error {{expected expression after 'then'}}
then // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
0 // expected-warning {{expression following 'then' is treated as an argument of the 'then'}}
// expected-note@-1 {{indent the expression to silence this warning}}
// Indented is okay.
then // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
0
then;
// expected-error@-1 {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
// expected-error@-2 {{expected expression after 'then'}}
then . foo
// expected-error@-1 {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
// expected-error@-2 {{reference to member 'foo' cannot be resolved without a contextual type}}
// These are expressions.
let _ = then
let _ = self.then
then + 1 // expected-warning {{result of operator '+' is unused}}
then = 2
(then) // expected-warning {{property is accessed but result is unused}}
then is Int
// expected-warning@-1 {{'is' test is always true}}
// expected-warning@-2 {{expression of type 'Bool' is unused}}
then as Int
// expected-warning@-1 {{expression of type 'Int' is unused}}
then as? Int
// expected-warning@-1 {{conditional cast from 'Int' to 'Int' always succeeds}}
// expected-warning@-2 {{expression of type 'Int?' is unused}}
then as! Int
// expected-warning@-1 {{forced cast of 'Int' to same type has no effect}}
// expected-warning@-2 {{expression of type 'Int' is unused}}
then ? 0 : 1 // expected-error {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}}
then! // expected-error {{cannot force unwrap value of non-optional type 'Int'}}
then? // expected-error {{cannot use optional chaining on non-optional value of type 'Int'}}
then.bitWidth // expected-warning {{expression of type 'Int' is unused}}
then?.bitWidth // expected-error {{cannot use optional chaining on non-optional value of type 'Int'}}
then!.bitWidth // expected-error {{cannot force unwrap value of non-optional type 'Int'}}
// This is tricky because the lexer considers '/^' to be an infix operator.
then /^ then/
// expected-error@-1 {{cannot find operator '/^' in scope}}
// expected-error@-2 {{'/' is not a postfix unary operator}}
self.then(0)
return then
}
func testThenSubscript() {
let then = self
then[0]
}
}
func testOutOfPlace() -> Int {
if .random() {
guard .random() else {
then 0 // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
}
if .random() {
then 0 // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
} else {
then 1 // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
}
then 0 // expected-error {{'then' may only appear as the last statement in an 'if', 'switch', or 'do' expression}}
then 0
} else {
then 1
}
}
func testNested1() -> Int {
if .random() {
if .random() {
then 1
} else {
then 2
}
} else {
switch Bool.random() {
case true:
then 0
case false:
then 1
}
}
}
func testNested2() -> Int {
if .random() {
then if .random() {
then 1
} else {
then 2
}
} else {
then switch Bool.random() {
case true:
then 0
case false:
then 1
}
}
}
func testNested3() -> Int {
if .random() {
print("hello")
then if .random() {
then 1
} else {
then 2
}
} else {
()
()
then switch Bool.random() {
case true:
then 0
case false:
then 1
}
}
}
func throwingFn() throws -> Int { 0 }
func testTryOnThen() throws -> Int {
switch 0 {
case 1:
then try throwingFn() // okay
default:
try then() // expected-warning {{no calls to throwing functions occur within 'try' expression}}
try then{} // expected-warning {{no calls to throwing functions occur within 'try' expression}}
try then {} // expected-warning {{no calls to throwing functions occur within 'try' expression}}
try then throwingFn()
// expected-error@-1 {{'try' must be placed on the produced expression}} {{5-9=}} {{14-14=try }}
}
}
func testReturnTryThen(_ then: Int) -> Int {
return try then // expected-warning {{no calls to throwing functions occur within 'try' expression}}
}
|