Files
swift-mirror/test/SILOptimizer/moveonly_self_captures.swift
Michael Gottesman b060e5ba60 [move-only] Make sure we mark local function inout parameters with mark_must_check.
Originally, we were relying on capture info to determine if we needed to insert
this mark_must_check. This ignored that the way that we are handling
escaping/non-escaping is something that is approximated in the AST but actually
determined at SIL level. With that in mind, rather than relying on the capture
info here, just rely on us having an inout argument. The later SIL level
checking for inout escapes is able to handle mark_must_check and knows how to
turn off noncopyable errors in the closure where we detect the error to prevent
us from emitting further errors due to the mark_must_check here.

I discovered this while playing with the previous commit.

rdar://112555589
2023-07-19 15:02:04 -07:00

108 lines
2.7 KiB
Swift

// RUN: %target-swift-emit-sil -sil-verify-all -verify %s
class Klass {}
struct E {
var k = Klass()
}
struct E2 : ~Copyable {
var k = Klass()
}
var g: () -> () = {}
struct Test : ~Copyable {
var e: E
var e2: E2
// Test that we capture inits by address.
init() {
e = E()
e2 = E2()
func capture() {
let _ = self.e
}
capture()
}
init(x: ()) {
e = E()
e2 = E2()
func capture() {
let _ = self
let _ = self.e2 // expected-error {{cannot partially consume 'self'}}
}
capture()
}
init(y: ()) { // expected-error {{missing reinitialization of closure capture 'self' after consume}}
e = E()
e2 = E2()
func capture() {
let _ = self // expected-note {{consumed here}}
}
capture()
}
init(z: ()) {
e = E()
e2 = E2()
func capture() {
let _ = self // expected-note {{captured here}}
}
capture()
g = capture // expected-error {{escaping local function captures mutating 'self' parameter}}
}
func captureByLocalFunction() {
func capture() {
let _ = self.e
}
capture()
}
func captureByLocalFunction2() { // expected-error {{noncopyable 'self' cannot be consumed when captured by an escaping closure}}
func capture() {
let _ = self.e2 // expected-note {{consumed here}}
}
capture()
}
func captureByLocalFunction3() { // expected-error {{noncopyable 'self' cannot be consumed when captured by an escaping closure}}
func capture() {
let _ = self // expected-note {{consumed here}}
}
capture()
}
func captureByLocalLet() { // expected-error {{'self' cannot be captured by an escaping closure since it is a borrowed parameter}}
let f = { // expected-note {{capturing 'self' here}}
let _ = self.e
}
f()
}
func captureByLocalVar() { // expected-error {{'self' cannot be captured by an escaping closure since it is a borrowed parameter}}
var f = {}
f = { // expected-note {{closure capturing 'self' here}}
let _ = self.e
}
f()
}
func captureByNonEscapingClosure() {
func useClosure(_ f: () -> ()) {}
useClosure {
let _ = self.e
}
}
func captureByNonEscapingClosure2() { // expected-error {{'self' cannot be consumed when captured by an escaping closure}}
func useClosure(_ f: () -> ()) {}
useClosure {
let _ = self // expected-note {{consumed here}}
}
}
}