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 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
|
// RUN: %target-swift-frontend %s \
// RUN: -emit-sil -target %target-swift-5.1-abi-triple \
// RUN: -enable-experimental-feature LifetimeDependence \
// RUN: | %FileCheck %s
// REQUIRES: swift_feature_LifetimeDependence
struct BufferView : ~Escapable {
let ptr: UnsafeRawBufferPointer
let c: Int
@lifetime(borrow ptr)
init(_ ptr: UnsafeRawBufferPointer, _ c: Int) {
self.ptr = ptr
self.c = c
}
@_unsafeNonescapableResult
init(independent ptr: UnsafeRawBufferPointer, _ c: Int) {
self.ptr = ptr
self.c = c
}
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence10BufferViewVyA2ChcfC : $@convention(method) (@guaranteed BufferView, @thin BufferView.Type) -> @lifetime(copy 0) @owned BufferView {
init(_ otherBV: borrowing BufferView) {
self.ptr = otherBV.ptr
self.c = otherBV.c
}
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence10BufferViewVyA2CcfC : $@convention(method) (@owned BufferView, @thin BufferView.Type) -> @lifetime(copy 0) @owned BufferView {
init(_ otherBV: consuming BufferView) {
self.ptr = otherBV.ptr
self.c = otherBV.c
}
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence10BufferViewVyACSW_SaySiGhtcfC : $@convention(method) (UnsafeRawBufferPointer, @guaranteed Array<Int>, @thin BufferView.Type) -> @lifetime(borrow 1) @owned BufferView {
init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array<Int>) {
self.ptr = ptr
self.c = a.count
}
}
struct MutableBufferView : ~Escapable, ~Copyable {
let ptr: UnsafeMutableRawBufferPointer
let c: Int
@lifetime(borrow ptr)
init(_ ptr: UnsafeMutableRawBufferPointer, _ c: Int) {
self.ptr = ptr
self.c = c
}
}
func testBasic() {
let a = [Int](repeating: 0, count: 4)
a.withUnsafeBytes {
let view = BufferView($0, a.count)
let derivedView = derive(view)
let newView = consumeAndCreate(derivedView)
use(newView)
}
}
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence6deriveyAA10BufferViewVADF : $@convention(thin) (@guaranteed BufferView) -> @lifetime(copy 0) @owned BufferView {
func derive(_ x: borrowing BufferView) -> BufferView {
return BufferView(x.ptr, x.c)
}
func derive(_ unused: Int, _ x: borrowing BufferView) -> BufferView {
return BufferView(independent: x.ptr, x.c)
}
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence16consumeAndCreateyAA10BufferViewVADnF : $@convention(thin) (@owned BufferView) -> @lifetime(copy 0) @owned BufferView {
func consumeAndCreate(_ x: consuming BufferView) -> BufferView {
return BufferView(independent: x.ptr, x.c)
}
func use(_ x: borrowing BufferView) {}
struct Wrapper : ~Escapable {
var _view: BufferView
var view: BufferView {
// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV4viewAA10BufferViewVvr : $@yield_once @convention(method) (@guaranteed Wrapper) -> @lifetime(copy 0) @yields @guaranteed BufferView {
_read {
yield _view
}
// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV4viewAA10BufferViewVvM : $@yield_once @convention(method) (@inout Wrapper) -> @lifetime(copy 0) @yields @inout BufferView {
_modify {
yield &_view
}
}
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence7WrapperVyAcA10BufferViewVcfC : $@convention(method) (@owned BufferView, @thin Wrapper.Type) -> @lifetime(copy 0) @owned Wrapper {
init(_ view: consuming BufferView) {
self._view = view
}
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence7WrapperV8getView1AA10BufferViewVyKF : $@convention(method) (@guaranteed Wrapper) -> @lifetime(copy 0) (@owned BufferView, @error any Error) {
borrowing func getView1() throws -> BufferView {
return _view
}
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence7WrapperV8getView2AA10BufferViewVyYaKF : $@convention(method) @async (@owned Wrapper) -> @lifetime(copy 0) (@owned BufferView, @error any Error) {
consuming func getView2() async throws -> BufferView {
return _view
}
}
struct Container1 : ~Copyable {
let ptr: UnsafeRawBufferPointer
let c: Int
// CHECK: sil hidden @$s28implicit_lifetime_dependence10Container1V4viewAA10BufferViewVvg : $@convention(method) (@guaranteed Container1) -> @lifetime(borrow 0) @owned BufferView {
var view: BufferView {
get {
return BufferView(ptr, c)
}
}
}
struct Container2 : ~Copyable {
let ptr: UnsafeMutableRawBufferPointer
let c: Int
// CHECK: sil hidden @$s28implicit_lifetime_dependence10Container2V11mutableViewAA013MutableBufferF0Vvr : $@yield_once @convention(method) (@guaranteed Container2) -> @lifetime(borrow 0) @yields @guaranteed MutableBufferView {
var mutableView: MutableBufferView {
_read {
yield MutableBufferView(ptr, c)
}
}
}
struct FakeRange<Bound> {
public let lowerBound: Bound
public let upperBound: Bound
}
struct GenericBufferView<Element> : ~Escapable {
typealias Index = Int
typealias Pointer = UnsafeRawPointer
let baseAddress: Pointer
let count: Int
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence17GenericBufferViewV11baseAddress5countACyxGSV_SitcfC : $@convention(method) <Element> (UnsafeRawPointer, Int, @thin GenericBufferView<Element>.Type) -> @lifetime(borrow 0) @owned GenericBufferView<Element> {
init<Storage>(baseAddress: Pointer,
count: Int,
dependsOn: borrowing Storage) {
self = GenericBufferView<Element>(baseAddress: baseAddress,
count: count)
}
// unsafe private API
@lifetime(borrow baseAddress)
init(baseAddress: Pointer, count: Int) {
precondition(count >= 0, "Count must not be negative")
self.baseAddress = baseAddress
self.count = count
}
subscript(position: Pointer) -> Element {
get {
if _isPOD(Element.self) {
return position.loadUnaligned(as: Element.self)
}
else {
return position.load(as: Element.self)
}
}
}
// CHECK: sil hidden @$s28implicit_lifetime_dependence17GenericBufferViewVyACyxGAA9FakeRangeVySVGcig : $@convention(method) <Element> (FakeRange<UnsafeRawPointer>, @guaranteed GenericBufferView<Element>) -> @lifetime(copy 1) @owned GenericBufferView<Element> {
subscript(bounds: FakeRange<Pointer>) -> Self {
get {
GenericBufferView(
baseAddress: UnsafeRawPointer(bounds.lowerBound),
count: bounds.upperBound.distance(to:bounds.lowerBound) / MemoryLayout<Element>.stride
)
}
}
}
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence23tupleLifetimeDependenceyAA10BufferViewV_ADtADF : $@convention(thin) (@guaranteed BufferView) -> @lifetime(copy 0) (@owned BufferView, @owned BufferView) {
func tupleLifetimeDependence(_ x: borrowing BufferView) -> (BufferView, BufferView) {
return (BufferView(x.ptr, x.c), BufferView(x.ptr, x.c))
}
public struct OuterNE: ~Escapable {
// A public property generates an implicit setter with an infered dependence on 'newValue'.
//
// [inner1.setter]
// CHECK-LABEL: sil [transparent] @$s28implicit_lifetime_dependence7OuterNEV6inner1AC05InnerE0Vvs : $@convention(method) (@owned OuterNE.InnerNE, @lifetime(copy 0) @inout OuterNE) -> () {
public var inner1: InnerNE
// Explicit setter with an infered dependence on 'newValue'.
public var inner2: InnerNE {
get { inner1 }
set { inner1 = newValue }
}
public struct InnerNE: ~Escapable {
init<Owner: ~Escapable & ~Copyable>(
owner: borrowing Owner
) {}
}
init<Owner: ~Copyable & ~Escapable>(owner: borrowing Owner) {
self.inner1 = InnerNE(owner: owner)
}
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence7OuterNEV8setInner5valueyAC0gE0V_tF : $@convention(method) (@guaranteed OuterNE.InnerNE, @lifetime(copy 0) @inout OuterNE) -> () {
@lifetime(self: value)
mutating func setInner(value: InnerNE) {
self.inner1 = value
}
}
|