Skip to content
Merged
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
143 changes: 131 additions & 12 deletions test/SILGen/capture_order.swift
Original file line number Diff line number Diff line change
Expand Up @@ -224,14 +224,6 @@ func forward_declared_let_captures() {
// expected-note@-3 {{captured value declared here}}
}

do {
func bad_local_f() -> Any { bad }
// expected-error@-1 {{closure captures 'bad' before it is declared}}
// expected-note@-2 {{captured here}}
let bad = bad_local_f()
// expected-note@-1 {{captured value declared here}}
}

do {
let bad = global_fwd { bad }
// expected-error@-1 {{closure captures 'bad' before it is declared}}
Expand Down Expand Up @@ -320,12 +312,139 @@ func forward_declared_let_captures() {
}
}

// FIXME: should/could these be diagnosed instead of accepted?
func forward_declared_let_captures_local_fn() {
do {
func bad_local_f() -> Any { bad }
// expected-error@-1 {{closure captures 'bad' before it is declared}}
// expected-note@-2 {{captured here}}
let bad = bad_local_f()
// expected-note@-1 {{captured value declared here}}
}

do {
func fwd(_ i: () -> Any) -> Any { i() }
func badFn() -> Any {
// expected-error@-1 {{closure captures 'bad' before it is declared}}
fwd { bad }
// expected-note@-1 {{captured here}}
}
let bad = badFn()
// expected-note@-1 {{captured value declared here}}
}

do {
func badFn() -> Any {
// expected-error@-1 {{closure captures 'bad' before it is declared}}
global_gen_fwd { bad }
// expected-note@-1 {{captured here}}
}
let bad = badFn()
// expected-note@-1 {{captured value declared here}}
}

do {
func badFn() -> Any {
// expected-error@-1 {{closure captures 'bad' before it is declared}}
E.static_gen_fwd { bad }
// expected-note@-1 {{captured here}}
}
let bad = badFn()
// expected-note@-1 {{captured value declared here}}
}

do {
func badFn() -> Any {
// expected-error@-1 {{closure captures 'badNested' before it is declared}}
global_fwd { { [badNested] in badNested }() }
// expected-note@-1 {{captured here}}
}
let badNested = badFn()
// expected-note@-1 {{captured value declared here}}
}

do {
func badFn() -> Any? {
// expected-error@-1 {{closure captures 'badOpt' before it is declared}}
{ () -> Any? in badOpt }()
// expected-note@-1 {{captured here}}
}
let badOpt = badFn()
// expected-note@-1 {{captured value declared here}}
}

do {
func badFn() -> (Any, Any) {
// expected-error@-1 {{closure captures 'badTup' before it is declared}}
{ (badTup.0, badTup.1) }()
// expected-note@-1 {{captured here}}
}
let badTup = badFn()
// expected-note@-1 {{captured value declared here}}
}

do {
func badFn() -> (Int, Any) {
// expected-error@-1 {{closure captures 'badTup' before it is declared}}
{ (badTup.0, badTup.1) }()
// expected-note@-1 {{captured here}}
}
let badTup = badFn()
// expected-note@-1 {{captured value declared here}}
}

do {
func badFn() -> (Any, Any) {
// expected-error@-1 {{closure captures 'badTup3' before it is declared}}
// expected-error@-2 {{closure captures 'badTup4' before it is declared}}
{ (badTup4, badTup3) }()
// expected-note@-1 2{{captured here}}
}
let (badTup3, badTup4) = badFn()
// expected-note@-1 2{{captured value declared here}}
}

do {
struct S { var p: Any }
func badFn() -> S {
// expected-error@-1 {{closure captures 'badStruct' before it is declared}}
{ S(p: badStruct.p) }()
// expected-note@-1 {{captured here}}
}
let badStruct = badFn()
// expected-note@-1 {{captured value declared here}}
}

do {
enum EE {
case boring
case weird(Any)
case strange(Any)
}

func badFn() -> EE {
// expected-error@-1 {{closure captures 'badEnum' before it is declared}}
{ .weird(EE.strange(badEnum)) }()
// expected-note@-1 {{captured here}}
}
let badEnum = badFn()
// expected-note@-1 {{captured value declared here}}
}

do {
func badFn() -> any P {
// expected-error@-1 {{closure captures 'badproto' before it is declared}}
global_fwd_p { badproto }
// expected-note@-1 {{captured here}}
}
let badproto = badFn()
// expected-note@-1 {{captured value declared here}}
}
}

func forward_declared_local_lazy_captures() {
// runtime stack overflow, maybe UB?
// runtime stack overflow
lazy var infiniteRecurse: Any = { infiniteRecurse }()

// ??? not entirely sure what's going on here...
// this can be called and doesn't seem to trip the sanitizers...
// function that returns itself
lazy var hmm: () -> Any = { hmm }
}