blob: 06f7954e5584fa0e2ca887b6bfd380b324449f2a [file] [log] [blame]
// RUN: %target-swift-emit-silgen %s -verify
/// We emit an invalid forward capture as an 'undef'; make sure
/// we cover the various possible cases.
public func captureBeforeDefLet(amount: Int) -> () -> Int {
func getter() -> Int { // expected-error {{closure captures 'modifiedAmount' before it is declared}}
return modifiedAmount // expected-note {{captured here}}
}
let closure = getter
let modifiedAmount = amount // expected-note{{captured value declared here}}
return closure
}
public func captureBeforeDefVar(amount: Int) -> () -> Int {
func incrementor() -> Int { // expected-error {{closure captures 'currentTotal' before it is declared}}
currentTotal += amount // expected-note {{captured here}}
return currentTotal
}
let closure = incrementor
var currentTotal = 0 // expected-note{{captured value declared here}}
currentTotal = 1
return closure
}
public func captureBeforeDefWeakVar(obj: AnyObject) -> () -> AnyObject? {
func getter() -> AnyObject? { // expected-error {{closure captures 'weakObj' before it is declared}}
return weakObj // expected-note {{captured here}}
}
let closure = getter
weak var weakObj: AnyObject? = obj // expected-note{{captured value declared here}}
return closure
}
public func captureBeforeDefUnownedLet(obj: AnyObject) -> () -> AnyObject? {
func getter() -> AnyObject? { // expected-error {{closure captures 'unownedObj' before it is declared}}
return unownedObj // expected-note {{captured here}}
}
let closure = getter
unowned let unownedObj: AnyObject = obj // expected-note{{captured value declared here}}
return closure
}
public func captureBeforeDefUnownedVar(obj: AnyObject) -> () -> AnyObject? {
func getter() -> AnyObject? { // expected-error {{closure captures 'unownedObj' before it is declared}}
return unownedObj // expected-note {{captured here}}
}
let closure = getter
unowned var unownedObj: AnyObject = obj // expected-note{{captured value declared here}}
// expected-warning@-1 {{variable 'unownedObj' was never mutated; consider changing to 'let' constant}}
return closure
}
/// Examples of transitive capture
func pingpong() {
func ping() -> Int {
return pong()
}
func pong() -> Int {
return ping()
}
_ = ping()
}
func transitiveForwardCapture() {
func ping() -> Int { // expected-error {{closure captures 'x' before it is declared}}
return pong()
}
_ = ping()
var x = 1 // expected-note {{captured value declared here}}
func pong() -> Int {
x += 1 // expected-note {{captured here}}
return ping()
}
}
func transitiveForwardCapture2() {
func ping() -> Int { // expected-error {{closure captures 'x' before it is declared}}
_ = pong()
}
_ = ping()
var x = 1 // expected-note {{captured value declared here}}
func pong() -> Int {
_ = pung()
}
func pung() -> Int {
x += 1 // expected-note {{captured here}}
return ping()
}
}
func transitiveForwardCapture3() {
var y = 2
func ping() -> Int { // expected-error {{closure captures 'x' before it is declared}}
_ = pong()
}
_ = ping()
var x = 1 // expected-note {{captured value declared here}}
func pung() -> Int {
x += 1 // expected-note {{captured here}}
return ping()
}
func pong() -> Int {
y += 2
_ = pung()
}
}
func captureInClosure() {
let x = { (i: Int) in // expected-error {{closure captures 'currentTotal' before it is declared}}
currentTotal += i // expected-note {{captured here}}
}
var currentTotal = 0 // expected-note {{captured value declared here}}
_ = x
}
/// Regression tests
func sr3210_crash() {
defer { // expected-error {{'defer' block captures 'b' before it is declared}}
print("\(b)") // expected-note {{captured here}}
}
return
let b = 2 // expected-note {{captured value declared here}}
// expected-warning@-1 {{code after 'return' will never be executed}}
}
func sr3210() {
defer {
print("\(b)")
}
let b = 2
}
class SR4812 {
public func foo() {
let bar = { [weak self] in
// expected-error@-1 {{closure captures 'bar' before it is declared}}
// expected-note@-2 {{captured value declared here}}
// expected-warning@-3 {{variable 'self' was written to, but never read}}
bar2()
}
func bar2() {
bar() // expected-note {{captured here}}
}
bar()
}
}
func timeout(_ f: @escaping () -> Void) {
f()
}
func sr10687() {
timeout { // expected-error {{closure captures 'x' before it is declared}}
proc()
}
let x = 0 // expected-note {{captured value declared here}}
func proc() {
_ = x // expected-note {{captured here}}
}
}
class rdar40600800 {
func foo() {
let callback = { // expected-error {{closure captures 'callback' before it is declared}}
// expected-note@-1 {{captured value declared here}}
innerFunction()
}
func innerFunction() {
let closure = {
// expected-warning@-1 {{initialization of immutable value 'closure' was never used; consider replacing with assignment to '_' or removing it}}
callback() // expected-note {{captured here}}
}
}
}
}