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
|
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-experimental-feature NonescapableTypes -enable-builtin-module
// REQUIRES: asserts
import Builtin
struct BufferView : ~Escapable {
let ptr: UnsafeRawBufferPointer
@_unsafeNonescapableResult
init(_ ptr: UnsafeRawBufferPointer) {
self.ptr = ptr
}
@_unsafeNonescapableResult
init?(_ ptr: UnsafeRawBufferPointer, _ i: Int) {
if (i % 2 == 0) {
return nil
}
self.ptr = ptr
}
init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array<Int>) -> dependsOn(a) Self {
self.ptr = ptr
return self
}
init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper) -> dependsOn(a) Self {
self.ptr = ptr
return self
}
init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper, b: borrowing Array<Int>) -> dependsOn(a) dependsOn(scoped b) Self {
self.ptr = ptr
return self
}
init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array<Double>, b: borrowing Array<Int>, c: Double) -> dependsOn(scoped a) dependsOn(b) Int { // expected-error{{expected Self return type for initializers with lifetime dependence specifiers}}
self.ptr = ptr
return 0
}
/* TODO: Enable this test once Optional is ~Escapable
init?(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array<Int>, _ i: Int) -> dependsOn(a) Self? {
if (i % 2 == 0) {
self.ptr = ptr
return self
}
return nil
}
*/
}
struct MutableBufferView : ~Escapable, ~Copyable {
let ptr: UnsafeMutableRawBufferPointer
@_unsafeNonescapableResult
init(_ ptr: UnsafeMutableRawBufferPointer) {
self.ptr = ptr
}
}
func testBasic() {
let capacity = 4
let a = Array(0..<capacity)
a.withUnsafeBytes {
let view = BufferView($0)
let derivedView = derive(view)
let newView = consumeAndCreate(derivedView)
use(newView)
}
}
func derive(_ x: borrowing BufferView) -> dependsOn(x) BufferView {
return BufferView(x.ptr)
}
func consumeAndCreate(_ x: consuming BufferView) -> dependsOn(x) BufferView {
return BufferView(x.ptr)
}
func use(_ x: borrowing BufferView) {}
func deriveMultiView1(_ x: borrowing BufferView, _ y: borrowing BufferView) -> dependsOn(x, y) BufferView {
if (Int.random(in: 1..<100) % 2 == 0) {
return BufferView(x.ptr)
}
return BufferView(y.ptr)
}
func deriveMultiView2(_ x: borrowing BufferView, _ y: borrowing BufferView) -> dependsOn(x) dependsOn(y) BufferView {
if (Int.random(in: 1..<100) % 2 == 0) {
return BufferView(x.ptr)
}
return BufferView(y.ptr)
}
func consumeAndCreateMultiView1(_ x: consuming BufferView, _ y: consuming BufferView) -> dependsOn(x, y) BufferView {
if (Int.random(in: 1..<100) % 2 == 0) {
return BufferView(x.ptr)
}
return BufferView(y.ptr)
}
func consumeAndCreateMultiView2(_ x: consuming BufferView, _ y: consuming BufferView) -> dependsOn(x) dependsOn(y) BufferView {
if (Int.random(in: 1..<100) % 2 == 0) {
return BufferView(x.ptr)
}
return BufferView(y.ptr)
}
func mixedMultiView(_ x: consuming BufferView, _ y: borrowing BufferView) -> dependsOn(x) dependsOn(y) BufferView {
if (Int.random(in: 1..<100) % 2 == 0) {
return BufferView(x.ptr)
}
return BufferView(y.ptr)
}
func modifiedViewDependsOnInput(_ x: inout MutableBufferView) -> dependsOn(x) MutableBufferView {
return MutableBufferView(x.ptr)
}
func modifiedViewDependsOnParent(_ x: inout MutableBufferView) -> dependsOn(x) MutableBufferView {
return MutableBufferView(x.ptr)
}
func invalidSpecifier1(_ x: borrowing BufferView) -> dependsOn BufferView { // expected-error{{expected '(' after lifetime dependence specifier}}
return BufferView(x.ptr)
}
func invalidSpecifier2(_ x: borrowing BufferView) -> dependsOn() BufferView {// expected-error{{expected identifier, index or self in lifetime dependence specifier}}
return BufferView(x.ptr)
}
func invalidSpecifier3(_ x: borrowing BufferView) -> dependsOn(*) BufferView { // expected-error{{expected identifier, index or self in lifetime dependence specifier}}
return BufferView(x.ptr)
}
// TODO: Diagnose using param indices on func decls in sema
func invalidSpecifier4(_ x: borrowing BufferView) -> dependsOn(self) BufferView { // expected-error{{invalid lifetime dependence specifier on non-existent self}}
return BufferView(x.ptr)
}
struct Wrapper : ~Escapable {
let view: BufferView
init(_ view: consuming BufferView) -> dependsOn(view) Self {
self.view = view
return self
}
borrowing func getView1() -> dependsOn(self) BufferView {
return view
}
consuming func getView2() -> dependsOn(self) BufferView {
return view
}
mutating func getView3() -> dependsOn(self) BufferView {
return view
}
borrowing func getView4() -> dependsOn(self) BufferView {
return view
}
}
|