Files
swift-mirror/test/SILOptimizer/noimplicitcopy_consuming_parameters.swift
Joe Groff f9d9d75768 SILGen: Change codegen for loading from no-implicit-copy lvalues.
Previously, we would emit this as

  %1 = load [copy] %address
  %2 = moveonly_wrapper_to_copyable [owned] %1

which is difficult for move-only checking to handle, since %2 looks like a
consume of %1, making it difficult to determine %1's true lifetime. Change
this to

  %1 = moveonly_wrapper_to_copyable_addr %address
  %2 = load [copy] %address

which is handled better by move-only checking, improving the accuracy of
existing move-checking as well as fixing a spurious diagnostic when
indirect parameters get passed as by-value arguments to other functions.
2025-01-06 21:34:56 -08:00

1022 lines
27 KiB
Swift

// RUN: %target-swift-frontend -emit-sil %s -verify -sil-verify-all -target %target-swift-5.1-abi-triple
////////////////////////
// MARK: Declarations //
////////////////////////
public class Klass {
}
public struct NonTrivialStruct {
var k = Klass()
let i = 0
func doSomethingDefault() {}
borrowing func doSomethingBorrowing() {}
consuming func doSomethingConsuming() {}
mutating func doSomethingMutating() {}
}
public protocol P {
static var value: Self { get }
}
public struct GenericNonTrivialStruct<T : P> {
var t = T.value
func doSomethingDefault() {}
borrowing func doSomethingBorrowing() {}
consuming func doSomethingConsuming() {}
mutating func doSomethingMutating() {}
}
public struct TrivialStruct {
var k: Int = 5
func doSomethingDefault() {}
consuming func doSomethingConsuming() {}
borrowing func doSomethingBorrowing() {}
mutating func doSomethingMutating() {}
}
enum LoadableEnum {
case x(NonTrivialStruct)
case y(Int)
}
enum TrivialEnum {
case x(Int64)
case y(Int)
}
enum AddressOnlyEnum<T> {
case x(NonTrivialStruct)
case y(T)
}
func borrowValDefault(_ x: NonTrivialStruct) {}
func borrowValBorrowing(_ x: borrowing NonTrivialStruct) {}
func consumeVal(_ x: consuming NonTrivialStruct) {}
func borrowValDefault(_ x: TrivialStruct) {}
func borrowValBorrowing(_ x: borrowing TrivialStruct) {}
func consumeVal(_ x: consuming TrivialStruct) {}
func borrowValDefault<T : P>(_ x: GenericNonTrivialStruct<T>) {}
func borrowValBorrowing<T : P>(_ x: borrowing GenericNonTrivialStruct<T>) {}
func consumeVal<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {}
///////////////////////////////////////////
// MARK: Simple Loadable Borrowing Tests //
///////////////////////////////////////////
func testIgnoredUse(_ x: consuming NonTrivialStruct) {
let _ = x
let _ = x.k
}
func consume(_: consuming NonTrivialStruct) {}
func consume(_: consuming Klass) {}
func testLoadableConsumingConsume1(_ x: consuming NonTrivialStruct) {
// expected-error @-1 {{'x' used after consume}}
consume(x) // expected-note {{consumed here}}
consume(x.k) // expected-note {{used here}}
}
func testLoadableConsumingConsume1a(_ x: consuming NonTrivialStruct) {
consume(x)
x = NonTrivialStruct()
consume(x.k)
}
func testLoadableConsumingConsume2(_ x: consuming NonTrivialStruct) {
// expected-error @-1 {{'x' used after consume}}
var y = x // expected-note {{consumed here}}
y = x // expected-note {{used here}}
_ = y
}
func testLoadableConsumingConsume3(_ x: consuming NonTrivialStruct) {
let y = x
_ = y
}
func testLoadableConsumingUse(_ x: consuming NonTrivialStruct) {
consume(x)
}
func testLoadableConsumingUseAndConsume(_ x: consuming NonTrivialStruct) {
borrowValBorrowing(x)
consume(x)
}
func testLoadableConsumingConsumeAndUse(_ x: consuming NonTrivialStruct) {
// expected-error @-1 {{'x' used after consume}}
consume(x) // expected-note {{consumed here}}
borrowValBorrowing(x) // expected-note {{used here}}
}
func testLoadableConsumingConsumeAndUseReinit(_ x: consuming NonTrivialStruct) {
consume(x)
x = NonTrivialStruct()
borrowValBorrowing(x)
}
func testLoadableConsumingCallBorrowValDefault(_ x: consuming NonTrivialStruct) {
borrowValDefault(x)
}
func testLoadableConsumingCallBorrowValBorrowing(_ x: consuming NonTrivialStruct) {
borrowValBorrowing(x)
}
func testLoadableConsumingCallConsumeVal(_ x: consuming NonTrivialStruct) {
consumeVal(x)
}
func testLoadableConsumingCallConsumeValMultiple(_ x: consuming NonTrivialStruct) {
// expected-error @-1 {{'x' consumed more than once}}
consumeVal(x) // expected-note {{consumed here}}
consumeVal(x) // expected-note {{consumed again here}}
}
func testLoadableConsumingCallMethodSelfDefault(_ x: consuming NonTrivialStruct) {
x.doSomethingDefault()
}
func testLoadableConsumingCallMethodSelfConsuming(_ x: consuming NonTrivialStruct) {
x.doSomethingConsuming()
}
func testLoadableConsumingCallMethodSelfMutating(_ x: consuming NonTrivialStruct) {
x.doSomethingMutating()
}
func testLoadableConsumingEscapingClosure(_ x: consuming NonTrivialStruct) {
var f: () -> () = {}
f = {
consume(x) // expected-error{{noncopyable 'x' cannot be consumed when captured by an escaping closure}}
}
_ = f
}
func testLoadableConsumingEscapingClosure2(_ x: consuming NonTrivialStruct) {
consume(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}}
var f: () -> () = {}
f = {
consume(x) // expected-error{{noncopyable 'x' cannot be consumed when captured by an escaping closure}}
}
_ = f
}
func testLoadableConsumingEscapingClosure3(_ x: consuming NonTrivialStruct) {
var f: () -> () = {}
f = {
consume(x) // expected-error{{noncopyable 'x' cannot be consumed when captured by an escaping closure}}
}
_ = f
consume(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}}
}
func testLoadableConsumingNonEscapingClosure(_ x: consuming NonTrivialStruct) { // expected-error{{}}
func useNonEscaping(_ f: () -> ()) {}
useNonEscaping {
consume(x) // expected-note{{consumed here}}
}
}
func testLoadableConsumingNonEscapingClosure2(_ x: consuming NonTrivialStruct) {
// expected-error @-1 {{'x' used after consume}}
// expected-error @-2 {{}}
consume(x) // expected-note {{consumed here}}
func useNonEscaping(_ f: () -> ()) {}
useNonEscaping { // expected-note {{used here}}
consume(x) // expected-note {{consumed here}}
}
}
func testLoadableConsumingConsumeOperator(_ x: consuming NonTrivialStruct) {
_ = consume x
}
func testLoadableConsumingConsumeOperator1(_ x: consuming NonTrivialStruct) {
// expected-error @-1 {{'x' used after consume}}
_ = consume x // expected-note {{consumed here}}
borrowValDefault(x) // expected-note {{used here}}
}
func testLoadableConsumingConsumeOperator2(_ x: consuming NonTrivialStruct) {
x = consume x
}
func testLoadableConsumingConsumeOperator3(_ x: consuming NonTrivialStruct) {
_ = consume x
let y = NonTrivialStruct()
x = consume y
}
func testLoadableConsumingEnum(_ x: consuming LoadableEnum) {
switch x {
case let .x(y):
_ = y
break
case .y:
break
}
}
func testLoadableConsumingEnum2(_ x: consuming LoadableEnum) {
switch x {
case let .x(y):
_ = consume x
_ = y
break
case .y:
break
}
}
func testLoadableConsumingCopyOperator(_ x: consuming NonTrivialStruct) {
_ = copy x
}
func testLoadableConsumingTrivialLetField(_ x: consuming NonTrivialStruct) -> Int {
return x.i
}
//////////////////////////////////////////
// MARK: Trivial Struct Consuming Tests //
//////////////////////////////////////////
func consume(_: consuming TrivialStruct) {}
func consume(_: consuming Int) {}
func testTrivialConsumingConsume(_ x: consuming TrivialStruct) {
// expected-error @-1 {{'x' used after consume}}
consume(x) // expected-note {{consumed here}}
consume(x.k) // expected-note {{used here}}
}
func testTrivialConsumingConsume2(_ x: consuming TrivialStruct) {
// expected-error @-1 {{'x' used after consume}}
var y = x // expected-note {{consumed here}}
y = x // expected-note {{used here}}
_ = y
}
func testTrivialConsumingConsume3(_ x: consuming TrivialStruct) {
let y = x
_ = y
}
func testTrivialConsumingUse(_ x: consuming TrivialStruct) {
consume(x)
}
func testTrivialConsumingUseAndConsume(_ x: consuming TrivialStruct) {
borrowValBorrowing(x)
consume(x)
}
func testTrivialConsumingConsumeAndUse(_ x: consuming TrivialStruct) {
// expected-error @-1 {{'x' used after consume}}
consume(x) // expected-note {{consumed here}}
borrowValBorrowing(x) // expected-note {{used here}}
}
func testTrivialConsumingConsumeAndUseReinit(_ x: consuming TrivialStruct) {
consume(x)
x = TrivialStruct()
borrowValBorrowing(x)
}
func testTrivialConsumingCallBorrowValDefault(_ x: consuming TrivialStruct) {
borrowValDefault(x)
}
func testTrivialConsumingCallBorrowValBorrowing(_ x: consuming TrivialStruct) {
borrowValBorrowing(x)
}
func testTrivialConsumingCallConsumeVal(_ x: consuming TrivialStruct) {
consumeVal(x)
}
func testTrivialConsumingCallMethodSelfDefault(_ x: consuming TrivialStruct) {
x.doSomethingDefault()
}
func testTrivialConsumingCallMethodSelfConsuming(_ x: consuming TrivialStruct) {
x.doSomethingConsuming()
}
func testTrivialConsumingEscapingClosure(_ x: consuming TrivialStruct) {
var f: () -> () = {}
f = {
consume(x)
}
_ = f
}
func testTrivialConsumingEscapingClosure2(_ x: consuming TrivialStruct) {
consume(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}}
var f: () -> () = {}
f = {
consume(x)
}
_ = f
}
func testTrivialConsumingEscapingClosure3(_ x: consuming TrivialStruct) {
var f: () -> () = {}
f = {
consume(x)
}
_ = f
consume(x) // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}}
}
func testTrivialConsumingNonEscapingClosure(_ x: consuming TrivialStruct) {
func useNonEscaping(_ f: () -> ()) {}
useNonEscaping {
consume(x)
}
}
func testTrivialConsumingNonEscapingClosure2(_ x: consuming TrivialStruct) {
// expected-error @-1 {{'x' used after consume}}
consume(x) // expected-note {{consumed here}}
func useNonEscaping(_ f: () -> ()) {}
useNonEscaping { // expected-note {{used here}}
consume(x)
}
}
func testTrivialConsumingConsumeOperator(_ x: consuming TrivialStruct) {
_ = consume x
}
func testTrivialConsumingEnum(_ x: consuming TrivialEnum) {
switch x {
case let .x(y):
_ = y
break
case .y:
break
}
}
func testTrivialConsumingEnum2(_ x: consuming TrivialEnum) {
switch x {
case let .x(y):
_ = y
break
case .y:
_ = copy x
break
}
}
func testTrivialConsumingCopyOperator(_ x: consuming TrivialStruct) {
_ = copy x
}
//////////////////////////////////////////////
// MARK: Simple AddressOnly Consuming Tests //
//////////////////////////////////////////////
func testAddressOnlyBorrowSimple<T>(_ x: borrowing T) {}
func testAddressOnlyConsumingConsume<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
// expected-error @-1 {{'x' used after consume}}
let _ = x // expected-note {{consumed here}}
let _ = x.t // expected-note {{used here}}
}
func testAddressOnlyConsumingConsume2<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
// expected-error @-1 {{'x' consumed more than once}}
var y = x // expected-note {{consumed here}}
y = x // expected-note {{consumed again here}}
_ = y
}
func testAddressOnlyConsumingConsume3<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
let y = x
_ = y
}
func testAddressOnlyConsumingUse<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
_ = x
}
func testAddressOnlyConsumingUseAndConsume<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
borrowValDefault(x)
let _ = x
}
func testAddressOnlyConsumingConsumeAndUse<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
// expected-error @-1 {{'x' used after consume}}
let _ = x // expected-note {{consumed here}}
borrowValDefault(x) // expected-note {{used here}}
}
func testAddressOnlyConsumingConsumeAndUseReinit<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
let _ = x
x = GenericNonTrivialStruct<T>()
borrowValDefault(x)
}
func testAddressOnlyConsumingCallBorrowValDefault<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
borrowValDefault(x)
}
func testAddressOnlyConsumingCallBorrowValBorrowing<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
borrowValBorrowing(x)
}
func testAddressOnlyConsumingCallConsumeVal<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
consumeVal(x)
}
func testAddressOnlyConsumingCallMethodSelfDefault<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
x.doSomethingDefault()
}
func testAddressOnlyConsumingCallMethodSelfConsuming<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
x.doSomethingConsuming()
}
func testAddressOnlyConsumingEscapingClosure<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
var f: () -> () = {}
f = {
_ = copy x
}
_ = f
}
func testAddressOnlyConsumingEscapingClosure2<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
let _ = x // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}}
var f: () -> () = {}
f = {
_ = copy x
}
_ = f
}
func testAddressOnlyConsumingEscapingClosure3<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
var f: () -> () = {}
f = {
_ = copy x
}
_ = f
let _ = x // expected-error {{noncopyable 'x' cannot be consumed when captured by an escaping closure}}
}
func testAddressOnlyConsumingNonEscapingClosure<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
func useNonEscaping(_ f: () -> ()) {}
useNonEscaping {
_ = copy x
}
}
func testAddressOnlyConsumingNonEscapingClosure2<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
// expected-error @-1 {{'x' used after consume}}
let _ = x // expected-note {{consumed here}}
func useNonEscaping(_ f: () -> ()) {}
useNonEscaping { // expected-note {{used here}}
_ = copy x
}
}
func testAddressOnlyConsumingCast<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
let _ = x as Any
}
func testAddressOnlyConsumingCast2<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
// expected-error @-1 {{'x' consumed more than once}}
let _ = x as Any // expected-note {{consumed here}}
let _ = x as Any // expected-note {{consumed again here}}
}
func testAddressOnlyConsumingCastCheck<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
if x is Any { // expected-warning {{'is' test is always true}}
}
}
func testAddressOnlyConsumingCastCheck2<T : P>(_ x: consuming GenericNonTrivialStruct<T>) {
// expected-error @-1 {{'x' consumed more than once}}
if x is Any { // expected-note {{consumed here}}
// expected-warning @-1 {{'is' test is always true}}
}
if x is Any { // expected-note {{consumed again here}}
// expected-warning @-1 {{'is' test is always true}}
}
}
func testAddressOnlyConsumingEnum<T>(_ x: consuming AddressOnlyEnum<T>) {
switch x {
case let .x(y):
_ = y
break
case let .y(z):
_ = z
break
}
}
func testAddressOnlyConsumingEnum2<T>(_ x: consuming AddressOnlyEnum<T>) {
// expected-error @-1 {{'x' used after consume}}
switch x { // expected-note {{consumed here}}
case let .x(y):
_ = y
break
case let .y(z):
_ = z
break
}
_ = copy x // expected-note {{used here}}
}
func testAddressOnlyConsumeOperator<T>(_ x: consuming GenericNonTrivialStruct<T>) {
_ = consume x
}
func testAddressOnlyCopyOperator<T>(_ x: consuming GenericNonTrivialStruct<T>) {
_ = copy x
}
///////////////////////////////
// MARK: Loadable Self Tests //
///////////////////////////////
func consume(_: consuming LoadableSelfTest) {}
struct LoadableSelfTest {
var k = Klass()
consuming func consumeSelf() {}
func doSomethingDefault() {}
consuming func doSomethingConsuming() {}
borrowing func doSomethingBorrowing() {}
mutating func doSomethingMutating() {}
consuming func testUseSelf() {
consume(self)
}
consuming func testUseSelf2() {
self.doSomethingDefault()
self.doSomethingDefault()
}
consuming func testUseSelf3() {
self.doSomethingBorrowing()
self.doSomethingDefault()
}
consuming func testUseSelf4() {
self.doSomethingBorrowing()
self.doSomethingBorrowing()
}
consuming func testLetUseSelf() {
consume(self)
}
consuming func callDoSomethingDefault() {
self.doSomethingDefault()
}
consuming func callDoSomethingBorrowing() {
self.doSomethingBorrowing()
}
consuming func callDoSomethingConsuming() {
self.doSomethingConsuming()
}
consuming func callDoSomethingMutating() {
self.doSomethingMutating()
}
consuming func callDoSomethingMutating2() {
self.doSomethingMutating()
_ = consume self
}
consuming func callDoSomethingMutating3() {
// expected-error @-1 {{'self' used after consume}}
_ = consume self // expected-note {{consumed here}}
self.doSomethingMutating() // expected-note {{used here}}
}
consuming func testConsumeOperatorSelf() {
_ = consume self
}
consuming func testConsumeOperatorSelf2() {
// expected-error @-1 {{'self' consumed more than once}}
_ = consume self // expected-note {{consumed here}}
_ = consume self // expected-note {{consumed again here}}
}
consuming func testCopyOperatorSelf() {
_ = copy self
}
consuming func testUseField() {
_ = self.k
}
consuming func testConsumeField() {
// No error, since our field is copyable.
let _ = self.k
}
consuming func testCallConsumeMethod() {
consumeSelf()
}
consuming func testCallConsumeMethod2() {
// expected-error @-1 {{'self' consumed more than once}}
consumeSelf() // expected-note {{consumed here}}
consumeSelf() // expected-note {{consumed again here}}
}
consuming func testCallFreeFunctionConsumeSelf() {
consumeLoadableSelfTest(self)
}
consuming func testCallFreeFunctionConsumeSelf2() {
// expected-error @-1 {{'self' consumed more than once}}
consumeLoadableSelfTest(self) // expected-note {{consumed here}}
consumeSelf() // expected-note {{consumed again here}}
}
consuming func testCallEscapingClosure() {
var f: () -> () = {}
f = {
let _ = copy self
}
f()
}
consuming func testCallEscapingClosure2() {
consume(self) // expected-error {{noncopyable 'self' cannot be consumed when captured by an escaping closure}}
var f: () -> () = {}
f = {
let _ = copy self
}
f()
}
consuming func testCallEscapingClosure3() {
var f: () -> () = {}
f = {
let _ = copy self
}
f()
consume(self) // expected-error {{noncopyable 'self' cannot be consumed when captured by an escaping closure}}
}
consuming func testCallNonEscapingClosure() {
func f(_ x: () -> ()) {}
f {
_ = copy self
}
}
consuming func testCallNonEscapingClosure2() {
// expected-error @-1 {{'self' used after consume}}
consume(self) // expected-note {{consumed here}}
func f(_ x: () -> ()) {}
f { // expected-note {{used here}}
_ = copy self
}
}
consuming func testCallNonEscapingClosure3() {
consume(self)
self = LoadableSelfTest()
func f(_ x: () -> ()) {}
f {
_ = copy self
}
}
}
func consumeLoadableSelfTest(_ x: consuming LoadableSelfTest) {}
///////////////////////////////////
// MARK: Address Only Self Tests //
///////////////////////////////////
struct AddressOnlySelfTest<T> {
var t: T
consuming func consumeSelf() {}
func doSomethingDefault() {}
consuming func doSomethingConsuming() {}
mutating func doSomethingMutating() {}
borrowing func doSomethingBorrowing() {}
consuming func testUseSelf() {
// expected-error @-1 {{'self' consumed more than once}}
_ = self // expected-note {{consumed here}}
_ = self // expected-note {{consumed again here}}
}
consuming func testUseSelf2() {
self.doSomethingDefault()
self.doSomethingDefault()
}
consuming func testUseSelf3() {
self.doSomethingBorrowing()
self.doSomethingDefault()
}
consuming func testUseSelf4() {
self.doSomethingDefault()
self.doSomethingBorrowing()
}
consuming func testLetUseSelf() {
// expected-error @-1 {{'self' consumed more than once}}
let _ = self // expected-note {{consumed here}}
let _ = self // expected-note {{consumed again here}}
}
consuming func callDoSomethingDefault() {
self.doSomethingDefault()
self.doSomethingBorrowing()
}
consuming func callDoSomethingConsuming() {
self.doSomethingConsuming()
}
consuming func callDoSomethingConsuming2() {
// expected-error @-1 {{'self' used after consume}}
self.doSomethingConsuming() // expected-note {{consumed here}}
self.doSomethingDefault() // expected-note {{used here}}
}
consuming func callDoSomethingConsuming3() {
// expected-error @-1 {{'self' used after consume}}
self.doSomethingConsuming() // expected-note {{consumed here}}
self.doSomethingDefault() // expected-note {{used here}}
}
consuming func callDoSomethingConsuming4() {
// expected-error @-1 {{'self' used after consume}}
self.doSomethingConsuming() // expected-note {{consumed here}}
self.doSomethingMutating() // expected-note {{used here}}
}
consuming func callDoSomethingConsuming4(_ x: AddressOnlySelfTest<T>) {
self.doSomethingConsuming()
self = x
self.doSomethingDefault()
}
consuming func testConsumeOperatorSelf() {
_ = consume self
}
consuming func testCopyOperatorSelf() {
_ = copy self
}
consuming func testUseField() {
_ = self.t
}
consuming func testConsumeField() {
// No error, since our field is copyable.
let _ = self.t
}
consuming func testCallConsumeMethod() {
consumeSelf()
}
consuming func testCallFreeFunctionConsumeSelf() {
consumeAddressOnlySelfTest(self)
}
consuming func testCallFreeFunctionConsumeSelf2() {
// expected-error @-1 {{'self' consumed more than once}}
consumeAddressOnlySelfTest(self) // expected-note {{consumed here}}
consumeSelf() // expected-note {{consumed again here}}
}
consuming func testCallEscapingClosure() {
var f: () -> () = {}
f = {
let _ = copy self
}
f()
}
consuming func testCallEscapingClosure2() {
let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by an escaping closure}}
var f: () -> () = {}
f = {
let _ = copy self
}
f()
}
consuming func testCallEscapingClosure3() {
var f: () -> () = {}
f = {
let _ = copy self
}
f()
let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by an escaping closure}}
}
consuming func testCallEscapingClosure4() {
var f: () -> () = {}
f = {
let _ = copy self
}
f()
f = {
let _ = copy self
}
let _ = self // expected-error {{noncopyable 'self' cannot be consumed when captured by an escaping closure}}
}
consuming func testCallNonEscapingClosure() {
func f(_ x: () -> ()) {}
f {
_ = copy self
}
}
consuming func testCallNonEscapingClosure2() {
// expected-error @-1 {{'self' used after consume}}
let _ = self // expected-note {{consumed here}}
func f(_ x: () -> ()) {}
f { // expected-note {{used here}}
_ = copy self
}
f {
_ = copy self
}
}
}
func consumeAddressOnlySelfTest<T>(_ x: consuming AddressOnlySelfTest<T>) {}
//////////////////////////////
// MARK: Trivial Self Tests //
//////////////////////////////
func consume(_: consuming TrivialSelfTest) {}
struct TrivialSelfTest {
var t = 5
consuming func consumeSelf() {}
func doSomethingDefault() {}
borrowing func doSomethingBorrowing() {}
consuming func doSomethingConsuming() {}
mutating func doSomethingMutating() {}
consuming func testUseSelf() {
_ = self
}
consuming func testUseSelf2() {
// expected-error @-1 {{'self' consumed more than once}}
consume(self) // expected-note {{consumed here}}
consume(self) // expected-note {{consumed again here}}
}
consuming func testUseSelf3() {
self.doSomethingDefault()
self.doSomethingDefault()
}
consuming func testUseSelf4() {
self.doSomethingDefault()
self.doSomethingBorrowing()
}
consuming func testUseSelf5() {
self.doSomethingBorrowing()
self.doSomethingBorrowing()
}
consuming func testLetUseSelf() {
let _ = self
}
consuming func callDoSomethingDefault() {
self.doSomethingDefault()
}
consuming func callDoSomethingConsuming() {
self.doSomethingConsuming()
}
consuming func testConsumeOperatorSelf() {
_ = consume self
}
consuming func testConsumeOperatorSelf2() {
// expected-error @-1 {{'self' consumed more than once}}
_ = consume self // expected-note {{consumed here}}
_ = consume self // expected-note {{consumed again here}}
}
consuming func testCopyOperatorSelf() {
_ = copy self
}
consuming func testUseField() {
_ = self.t
}
consuming func testConsumeField() {
// No error, since our field is copyable.
let _ = self.t
}
consuming func testCallConsumeMethod() {
consumeSelf()
}
consuming func testCallFreeFunctionConsumeSelf() {
consumeTrivialSelfTest(self)
}
consuming func testCallFreeFunctionConsumeSelf2() {
// expected-error @-1 {{'self' consumed more than once}}
consumeTrivialSelfTest(self) // expected-note {{consumed here}}
consumeSelf() // expected-note {{consumed again here}}
}
consuming func testCallEscapingClosure() {
var f: () -> () = {}
f = {
let _ = self
}
f()
}
consuming func testCallEscapingClosure2() {
consume(self) // expected-error {{noncopyable 'self' cannot be consumed when captured by an escaping closure}}
var f: () -> () = {}
f = {
let _ = self
}
f()
}
consuming func testCallNonEscapingClosure() {
func f(_ x: () -> ()) {}
f {
_ = self
}
}
consuming func testCallNonEscapingClosure2() {
// expected-error @-1 {{'self' used after consume}}
consume(self) // expected-note {{consumed here}}
func f(_ x: () -> ()) {}
f { // expected-note {{used here}}
_ = self
}
}
consuming func testCallNonEscapingClosure3() {
consume(self)
self = TrivialSelfTest()
func f(_ x: () -> ()) {}
f {
_ = self
}
}
}
func consumeTrivialSelfTest(_ x: consuming TrivialSelfTest) {}
extension AsyncSequence where Element: Sendable {
consuming func iterate_bad() async { // expected-error {{missing reinitialization of inout parameter 'self' after consume}}
await withTaskGroup(of: Void.self) { _ in
var _:AsyncIterator = self.makeAsyncIterator() // expected-note {{consumed here}}
}
}
consuming func iterate_fixed() async {
await withTaskGroup(of: Void.self) { [seq = copy self] _ in
var _:AsyncIterator = seq.makeAsyncIterator()
}
}
}