mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Update tests for strict @lifetime type checking
This commit is contained in:
@@ -219,13 +219,13 @@ struct OpTest {
|
|||||||
|
|
||||||
struct E {}
|
struct E {}
|
||||||
struct NE : ~Escapable {}
|
struct NE : ~Escapable {}
|
||||||
@lifetime(ne) func derive(_ ne: NE) -> NE { ne }
|
@lifetime(copy ne) func derive(_ ne: NE) -> NE { ne }
|
||||||
@lifetime(borrow ne1, ne2) func derive(_ ne1: NE, _ ne2: NE) -> NE {
|
@lifetime(borrow ne1, copy ne2) func derive(_ ne1: NE, _ ne2: NE) -> NE {
|
||||||
if (Int.random(in: 1..<100) < 50) { return ne1 }
|
if (Int.random(in: 1..<100) < 50) { return ne1 }
|
||||||
return ne2
|
return ne2
|
||||||
}
|
}
|
||||||
@lifetime(borrow borrow) func testNameConflict(_ borrow: E) -> NE { NE() }
|
@lifetime(borrow borrow) func testNameConflict(_ borrow: E) -> NE { NE() }
|
||||||
@lifetime(result: source) func testTarget(_ result: inout NE, _ source: consuming NE) { result = source }
|
@lifetime(result: copy source) func testTarget(_ result: inout NE, _ source: consuming NE) { result = source }
|
||||||
|
|
||||||
actor MyActor {
|
actor MyActor {
|
||||||
nonisolated let constFlag: Bool = false
|
nonisolated let constFlag: Bool = false
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
// RUN: %target-typecheck-verify-swift \
|
// RUN: %target-typecheck-verify-swift \
|
||||||
|
// RUN: -enable-experimental-feature LifetimeDependence \
|
||||||
// RUN: -debug-diagnostic-names -target arm64-apple-macos14.4
|
// RUN: -debug-diagnostic-names -target arm64-apple-macos14.4
|
||||||
|
|
||||||
|
// REQUIRES: swift_feature_LifetimeDependence
|
||||||
|
|
||||||
// REQUIRES: OS=macosx || OS=ios || OS=tvos || OS=watchOS || OS=xros
|
// REQUIRES: OS=macosx || OS=ios || OS=tvos || OS=watchOS || OS=xros
|
||||||
|
|
||||||
protocol P {}
|
protocol P {}
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
// RUN: %target-swift-frontend -typecheck -verify %s
|
// RUN: %target-swift-frontend \
|
||||||
|
// RUN: -enable-experimental-feature LifetimeDependence \
|
||||||
|
// RUN: -typecheck -verify %s
|
||||||
|
|
||||||
|
// REQUIRES: swift_feature_LifetimeDependence
|
||||||
|
|
||||||
struct C_C1<T: ~Copyable>: ~Copyable {}
|
struct C_C1<T: ~Copyable>: ~Copyable {}
|
||||||
extension C_C1: Copyable where T: Copyable {}
|
extension C_C1: Copyable where T: Copyable {}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// RUN: %target-typecheck-verify-swift \
|
// RUN: %target-typecheck-verify-swift \
|
||||||
|
// RUN: -enable-experimental-feature LifetimeDependence \
|
||||||
// RUN: -enable-experimental-feature SuppressedAssociatedTypes
|
// RUN: -enable-experimental-feature SuppressedAssociatedTypes
|
||||||
|
|
||||||
|
// REQUIRES: swift_feature_LifetimeDependence
|
||||||
// REQUIRES: swift_feature_SuppressedAssociatedTypes
|
// REQUIRES: swift_feature_SuppressedAssociatedTypes
|
||||||
|
|
||||||
protocol P {}
|
protocol P {}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
// RUN: %target-swift-frontend \
|
// RUN: %target-swift-frontend \
|
||||||
|
// RUN: -enable-experimental-feature LifetimeDependence \
|
||||||
// RUN: -verify -typecheck %s -debug-generic-signatures \
|
// RUN: -verify -typecheck %s -debug-generic-signatures \
|
||||||
// RUN: -debug-inverse-requirements 2>&1 | %FileCheck %s --implicit-check-not "error:"
|
// RUN: -debug-inverse-requirements 2>&1 | %FileCheck %s --implicit-check-not "error:"
|
||||||
|
|
||||||
|
// REQUIRES: swift_feature_LifetimeDependence
|
||||||
|
|
||||||
// CHECK-LABEL: .Outer@
|
// CHECK-LABEL: .Outer@
|
||||||
// CHECK: Generic signature: <A where A : Escapable>
|
// CHECK: Generic signature: <A where A : Escapable>
|
||||||
|
|||||||
@@ -249,6 +249,7 @@ struct BuggerView<T: ~Copyable>: ~Escapable, Copyable {}
|
|||||||
|
|
||||||
struct MutableBuggerView<T: ~Copyable>: ~Copyable, ~Escapable {}
|
struct MutableBuggerView<T: ~Copyable>: ~Copyable, ~Escapable {}
|
||||||
|
|
||||||
|
@lifetime(mutRef: copy mutRef)
|
||||||
func checkNominals(_ mutRef: inout MutableBuggerView<NC>,
|
func checkNominals(_ mutRef: inout MutableBuggerView<NC>,
|
||||||
_ ref: BuggerView<NC>,
|
_ ref: BuggerView<NC>,
|
||||||
_ intMutRef: borrowing MutableBuggerView<Int>,
|
_ intMutRef: borrowing MutableBuggerView<Int>,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import CountedByNoEscapeClang
|
|||||||
// CHECK: @_alwaysEmitIntoClient public func complexExpr(_ len: Int{{.*}}, _ offset: Int{{.*}}, _ p: MutableSpan<Int{{.*}}>)
|
// CHECK: @_alwaysEmitIntoClient public func complexExpr(_ len: Int{{.*}}, _ offset: Int{{.*}}, _ p: MutableSpan<Int{{.*}}>)
|
||||||
// CHECK-NEXT: @_alwaysEmitIntoClient public func nonnull(_ p: MutableSpan<Int{{.*}}>)
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func nonnull(_ p: MutableSpan<Int{{.*}}>)
|
||||||
// CHECK-NEXT: @_alwaysEmitIntoClient public func nullUnspecified(_ p: MutableSpan<Int{{.*}}>)
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func nullUnspecified(_ p: MutableSpan<Int{{.*}}>)
|
||||||
// CHECK-NEXT: @lifetime(p)
|
// CHECK-NEXT: @lifetime(copy p)
|
||||||
// CHECK-NEXT: @_alwaysEmitIntoClient public func returnLifetimeBound(_ len1: Int32, _ p: MutableSpan<Int32>) -> MutableSpan<Int32>
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func returnLifetimeBound(_ len1: Int32, _ p: MutableSpan<Int32>) -> MutableSpan<Int32>
|
||||||
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func returnPointer(_ len: Int{{.*}}) -> UnsafeMutableBufferPointer<Int{{.*}}>
|
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func returnPointer(_ len: Int{{.*}}) -> UnsafeMutableBufferPointer<Int{{.*}}>
|
||||||
// CHECK-NEXT: @_alwaysEmitIntoClient public func shared(_ len: Int{{.*}}, _ p1: MutableSpan<Int{{.*}}>, _ p2: MutableSpan<Int{{.*}}>)
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func shared(_ len: Int{{.*}}, _ p1: MutableSpan<Int{{.*}}>, _ p2: MutableSpan<Int{{.*}}>)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ module Test {
|
|||||||
struct SWIFT_NONESCAPABLE View {
|
struct SWIFT_NONESCAPABLE View {
|
||||||
__attribute__((swift_attr("@lifetime(immortal)")))
|
__attribute__((swift_attr("@lifetime(immortal)")))
|
||||||
View() : member(nullptr) {}
|
View() : member(nullptr) {}
|
||||||
__attribute__((swift_attr("@lifetime(p)")))
|
__attribute__((swift_attr("@lifetime(copy p)")))
|
||||||
View(const int *p [[clang::lifetimebound]]) : member(p) {}
|
View(const int *p [[clang::lifetimebound]]) : member(p) {}
|
||||||
View(const View&) = default;
|
View(const View&) = default;
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -35,11 +35,11 @@ import CxxStdlib
|
|||||||
// CHECK-NEXT: mutating func foo(_ s: std.{{.*}}span<__cxxConst<CInt>, _C{{.*}}_{{.*}}>)
|
// CHECK-NEXT: mutating func foo(_ s: std.{{.*}}span<__cxxConst<CInt>, _C{{.*}}_{{.*}}>)
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
// CHECK: @_alwaysEmitIntoClient public func funcWithSafeWrapper(_ s: Span<CInt>)
|
// CHECK: @_alwaysEmitIntoClient public func funcWithSafeWrapper(_ s: Span<CInt>)
|
||||||
// CHECK-NEXT: @lifetime(s)
|
// CHECK-NEXT: @lifetime(copy s)
|
||||||
// CHECK-NEXT: @_alwaysEmitIntoClient public func funcWithSafeWrapper2(_ s: Span<CInt>) -> Span<CInt>
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func funcWithSafeWrapper2(_ s: Span<CInt>) -> Span<CInt>
|
||||||
// CHECK-NEXT: @lifetime(borrow v)
|
// CHECK-NEXT: @lifetime(borrow v)
|
||||||
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func funcWithSafeWrapper3(_ v: borrowing VecOfInt) -> Span<CInt>
|
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func funcWithSafeWrapper3(_ v: borrowing VecOfInt) -> Span<CInt>
|
||||||
// CHECK-NEXT: @lifetime(p)
|
// CHECK-NEXT: @lifetime(copy p)
|
||||||
// CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper1(_ p: Span<Int32>) -> Span<CInt>
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper1(_ p: Span<Int32>) -> Span<CInt>
|
||||||
// CHECK-NEXT: @lifetime(borrow v)
|
// CHECK-NEXT: @lifetime(borrow v)
|
||||||
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func mixedFuncWithSafeWrapper2(_ v: borrowing VecOfInt, _ len: Int32) -> Span<Int32>
|
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func mixedFuncWithSafeWrapper2(_ v: borrowing VecOfInt, _ len: Int32) -> Span<Int32>
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ func lifetimeDependentBorrow(_ p: borrowing UnsafePointer<CInt>, _ len1: CInt, _
|
|||||||
// CHECK-NEXT: func nonEscaping(_ len: CInt) -> UnsafeBufferPointer<CInt> {
|
// CHECK-NEXT: func nonEscaping(_ len: CInt) -> UnsafeBufferPointer<CInt> {
|
||||||
// CHECK-NEXT: return unsafe UnsafeBufferPointer<CInt> (start: nonEscaping(len), count: Int(len))
|
// CHECK-NEXT: return unsafe UnsafeBufferPointer<CInt> (start: nonEscaping(len), count: Int(len))
|
||||||
|
|
||||||
// CHECK: @_alwaysEmitIntoClient @lifetime(p)
|
// CHECK: @_alwaysEmitIntoClient @lifetime(copy p)
|
||||||
// CHECK-NEXT: func lifetimeDependentCopy(_ p: Span<CInt>, _ len2: CInt) -> Span<CInt> {
|
// CHECK-NEXT: func lifetimeDependentCopy(_ p: Span<CInt>, _ len2: CInt) -> Span<CInt> {
|
||||||
// CHECK-NEXT: return unsafe Span<CInt> (_unsafeStart: p.withUnsafeBufferPointer { _pPtr in
|
// CHECK-NEXT: return unsafe Span<CInt> (_unsafeStart: p.withUnsafeBufferPointer { _pPtr in
|
||||||
// CHECK-NEXT: return unsafe lifetimeDependentCopy(_pPtr.baseAddress!, CInt(exactly: p.count)!, len2)
|
// CHECK-NEXT: return unsafe lifetimeDependentCopy(_pPtr.baseAddress!, CInt(exactly: p.count)!, len2)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ struct X {
|
|||||||
func myFunc5() -> SpanOfInt {}
|
func myFunc5() -> SpanOfInt {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK: @_alwaysEmitIntoClient @lifetime(span)
|
// CHECK: @_alwaysEmitIntoClient @lifetime(copy span)
|
||||||
// CHECK-NEXT: func myFunc(_ span: Span<CInt>) -> Span<CInt> {
|
// CHECK-NEXT: func myFunc(_ span: Span<CInt>) -> Span<CInt> {
|
||||||
// CHECK-NEXT: return unsafe _unsafeRemoveLifetime(Span(_unsafeCxxSpan: myFunc(SpanOfInt(span))))
|
// CHECK-NEXT: return unsafe _unsafeRemoveLifetime(Span(_unsafeCxxSpan: myFunc(SpanOfInt(span))))
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
@@ -42,12 +42,12 @@ struct X {
|
|||||||
// CHECK-NEXT: return unsafe _unsafeRemoveLifetime(Span(_unsafeCxxSpan: myFunc2(vec)))
|
// CHECK-NEXT: return unsafe _unsafeRemoveLifetime(Span(_unsafeCxxSpan: myFunc2(vec)))
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
|
|
||||||
// CHECK: @_alwaysEmitIntoClient @lifetime(span1, span2)
|
// CHECK: @_alwaysEmitIntoClient @lifetime(copy span1, copy span2)
|
||||||
// CHECK-NEXT: func myFunc3(_ span1: Span<CInt>, _ span2: Span<CInt>) -> Span<CInt> {
|
// CHECK-NEXT: func myFunc3(_ span1: Span<CInt>, _ span2: Span<CInt>) -> Span<CInt> {
|
||||||
// CHECK-NEXT: return unsafe _unsafeRemoveLifetime(Span(_unsafeCxxSpan: myFunc3(SpanOfInt(span1), SpanOfInt(span2))))
|
// CHECK-NEXT: return unsafe _unsafeRemoveLifetime(Span(_unsafeCxxSpan: myFunc3(SpanOfInt(span1), SpanOfInt(span2))))
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
|
|
||||||
// CHECK: @_alwaysEmitIntoClient @lifetime(borrow vec, span)
|
// CHECK: @_alwaysEmitIntoClient @lifetime(borrow vec, copy span)
|
||||||
// CHECK-NEXT: func myFunc4(_ vec: borrowing VecOfInt, _ span: Span<CInt>) -> Span<CInt> {
|
// CHECK-NEXT: func myFunc4(_ vec: borrowing VecOfInt, _ span: Span<CInt>) -> Span<CInt> {
|
||||||
// CHECK-NEXT: return unsafe _unsafeRemoveLifetime(Span(_unsafeCxxSpan: myFunc4(vec, SpanOfInt(span))))
|
// CHECK-NEXT: return unsafe _unsafeRemoveLifetime(Span(_unsafeCxxSpan: myFunc4(vec, SpanOfInt(span))))
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ internal func _overrideLifetime<T: ~Copyable & ~Escapable, U: ~Copyable & ~Escap
|
|||||||
@_unsafeNonescapableResult
|
@_unsafeNonescapableResult
|
||||||
@_alwaysEmitIntoClient
|
@_alwaysEmitIntoClient
|
||||||
@_transparent
|
@_transparent
|
||||||
@lifetime(source)
|
@lifetime(copy source)
|
||||||
internal func _overrideLifetime<T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable>(
|
internal func _overrideLifetime<T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable>(
|
||||||
_ dependent: consuming T, copying source: borrowing U) -> T {
|
_ dependent: consuming T, copying source: borrowing U) -> T {
|
||||||
dependent
|
dependent
|
||||||
@@ -43,7 +43,7 @@ public struct BufferView : ~Escapable {
|
|||||||
self = _overrideLifetime(bv, borrowing: a)
|
self = _overrideLifetime(bv, borrowing: a)
|
||||||
}
|
}
|
||||||
@inlinable
|
@inlinable
|
||||||
@lifetime(a)
|
@lifetime(copy a)
|
||||||
internal init(_ ptr: UnsafeRawBufferPointer, _ a: consuming AnotherView) {
|
internal init(_ ptr: UnsafeRawBufferPointer, _ a: consuming AnotherView) {
|
||||||
let bv = BufferView(ptr, a._count)
|
let bv = BufferView(ptr, a._count)
|
||||||
self = _overrideLifetime(bv, copying: a)
|
self = _overrideLifetime(bv, copying: a)
|
||||||
@@ -51,7 +51,7 @@ public struct BufferView : ~Escapable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@inlinable
|
@inlinable
|
||||||
@lifetime(x)
|
@lifetime(copy x)
|
||||||
public func derive(_ x: consuming BufferView) -> BufferView {
|
public func derive(_ x: consuming BufferView) -> BufferView {
|
||||||
let pointer = x._ptr
|
let pointer = x._ptr
|
||||||
let bv = BufferView(pointer, x._count)
|
let bv = BufferView(pointer, x._count)
|
||||||
@@ -62,7 +62,7 @@ public func derive(_ x: consuming BufferView) -> BufferView {
|
|||||||
public func use(_ x: consuming BufferView) {}
|
public func use(_ x: consuming BufferView) {}
|
||||||
|
|
||||||
@inlinable
|
@inlinable
|
||||||
@lifetime(view)
|
@lifetime(copy view)
|
||||||
public func consumeAndCreate(_ view: consuming BufferView) -> BufferView {
|
public func consumeAndCreate(_ view: consuming BufferView) -> BufferView {
|
||||||
let pointer = view._ptr
|
let pointer = view._ptr
|
||||||
let bv = BufferView(pointer, view._count)
|
let bv = BufferView(pointer, view._count)
|
||||||
@@ -70,7 +70,7 @@ public func consumeAndCreate(_ view: consuming BufferView) -> BufferView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@inlinable
|
@inlinable
|
||||||
@lifetime(this, that)
|
@lifetime(copy this, copy that)
|
||||||
public func deriveThisOrThat(_ this: consuming BufferView, _ that: consuming BufferView) -> BufferView {
|
public func deriveThisOrThat(_ this: consuming BufferView, _ that: consuming BufferView) -> BufferView {
|
||||||
if (Int.random(in: 1..<100) == 0) {
|
if (Int.random(in: 1..<100) == 0) {
|
||||||
return BufferView(this._ptr, this._count)
|
return BufferView(this._ptr, this._count)
|
||||||
|
|||||||
@@ -24,16 +24,16 @@
|
|||||||
import lifetime_dependence
|
import lifetime_dependence
|
||||||
// CHECK: @lifetime(borrow a)
|
// CHECK: @lifetime(borrow a)
|
||||||
// CHECK-NEXT: @inlinable internal init(_ ptr: Swift.UnsafeRawBufferPointer, _ a: borrowing Swift.Array<Swift.Int>) {
|
// CHECK-NEXT: @inlinable internal init(_ ptr: Swift.UnsafeRawBufferPointer, _ a: borrowing Swift.Array<Swift.Int>) {
|
||||||
// CHECK: @lifetime(a)
|
// CHECK: @lifetime(copy a)
|
||||||
// CHECK-NEXT: @inlinable internal init(_ ptr: Swift.UnsafeRawBufferPointer, _ a: consuming lifetime_dependence.AnotherView) {
|
// CHECK-NEXT: @inlinable internal init(_ ptr: Swift.UnsafeRawBufferPointer, _ a: consuming lifetime_dependence.AnotherView) {
|
||||||
|
|
||||||
// CHECK: @lifetime(x)
|
// CHECK: @lifetime(copy x)
|
||||||
// CHECK-NEXT: @inlinable public func derive(_ x: consuming lifetime_dependence.BufferView) -> lifetime_dependence.BufferView {
|
// CHECK-NEXT: @inlinable public func derive(_ x: consuming lifetime_dependence.BufferView) -> lifetime_dependence.BufferView {
|
||||||
|
|
||||||
// CHECK: @lifetime(view)
|
// CHECK: @lifetime(copy view)
|
||||||
// CHECK-NEXT: @inlinable public func consumeAndCreate(_ view: consuming lifetime_dependence.BufferView) -> lifetime_dependence.BufferView {
|
// CHECK-NEXT: @inlinable public func consumeAndCreate(_ view: consuming lifetime_dependence.BufferView) -> lifetime_dependence.BufferView {
|
||||||
|
|
||||||
// CHECK: @lifetime(this, that)
|
// CHECK: @lifetime(copy this, copy that)
|
||||||
// CHECK-NEXT: @inlinable public func deriveThisOrThat(_ this: consuming lifetime_dependence.BufferView, _ that: consuming lifetime_dependence.BufferView) -> lifetime_dependence.BufferView {
|
// CHECK-NEXT: @inlinable public func deriveThisOrThat(_ this: consuming lifetime_dependence.BufferView, _ that: consuming lifetime_dependence.BufferView) -> lifetime_dependence.BufferView {
|
||||||
|
|
||||||
// Check that an implicitly dependent variable accessor is guarded by LifetimeDependence.
|
// Check that an implicitly dependent variable accessor is guarded by LifetimeDependence.
|
||||||
|
|||||||
@@ -50,19 +50,19 @@ public enum Y<T: ~Escapable>: ~Escapable {
|
|||||||
extension Y: Escapable where T: Escapable { }
|
extension Y: Escapable where T: Escapable { }
|
||||||
|
|
||||||
// CHECK: #if compiler(>=5.3) && $NonescapableTypes
|
// CHECK: #if compiler(>=5.3) && $NonescapableTypes
|
||||||
// CHECK: @lifetime(y)
|
// CHECK: @lifetime(copy y)
|
||||||
// CHECK: public func derive<T>(_ y: Test.Y<T>) -> Test.Y<T> where T : ~Escapable
|
// CHECK: public func derive<T>(_ y: Test.Y<T>) -> Test.Y<T> where T : ~Escapable
|
||||||
// CHECK: #endif
|
// CHECK: #endif
|
||||||
@lifetime(y)
|
@lifetime(copy y)
|
||||||
public func derive<T : ~Escapable>(_ y: Y<T>) -> Y<T> {
|
public func derive<T : ~Escapable>(_ y: Y<T>) -> Y<T> {
|
||||||
y
|
y
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK: #if compiler(>=5.3) && $NonescapableTypes
|
// CHECK: #if compiler(>=5.3) && $NonescapableTypes
|
||||||
// CHECK: @lifetime(x)
|
// CHECK: @lifetime(copy x)
|
||||||
// CHECK: public func derive<T>(_ x: Test.X<T>) -> Test.X<T> where T : ~Escapable
|
// CHECK: public func derive<T>(_ x: Test.X<T>) -> Test.X<T> where T : ~Escapable
|
||||||
// CHECK: #endif
|
// CHECK: #endif
|
||||||
@lifetime(x)
|
@lifetime(copy x)
|
||||||
public func derive<T : ~Escapable>(_ x: X<T>) -> X<T> {
|
public func derive<T : ~Escapable>(_ x: X<T>) -> X<T> {
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
// RUN: %target-typecheck-verify-swift
|
// RUN: %target-typecheck-verify-swift \
|
||||||
|
// RUN: -enable-experimental-feature LifetimeDependence
|
||||||
|
|
||||||
|
// REQUIRES: swift_feature_LifetimeDependence
|
||||||
|
|
||||||
struct S: ~Escapable {}
|
struct S: ~Escapable {}
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ struct E {}
|
|||||||
|
|
||||||
struct NE : ~Escapable {}
|
struct NE : ~Escapable {}
|
||||||
|
|
||||||
@lifetime(ne)
|
@lifetime(copy ne)
|
||||||
func derive(_ ne: NE) -> NE {
|
func derive(_ ne: NE) -> NE {
|
||||||
ne
|
ne
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(borrow ne1, ne2)
|
@lifetime(borrow ne1, copy ne2)
|
||||||
func derive(_ ne1: NE, _ ne2: NE) -> NE {
|
func derive(_ ne1: NE, _ ne2: NE) -> NE {
|
||||||
if (Int.random(in: 1..<100) < 50) {
|
if (Int.random(in: 1..<100) < 50) {
|
||||||
return ne1
|
return ne1
|
||||||
@@ -19,13 +19,13 @@ func derive(_ ne1: NE, _ ne2: NE) -> NE {
|
|||||||
return ne2
|
return ne2
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime // expected-error{{expected '(' after lifetime dependence specifier}}
|
@lifetime // expected-error{{expected '(' after lifetime dependence specifier}}
|
||||||
func testMissingLParenError(_ ne: NE) -> NE {
|
func testMissingLParenError(_ ne: NE) -> NE { // expected-error{{cannot infer the lifetime dependence scope on a function with a ~Escapable parameter, specify '@lifetime(borrow ne)' or '@lifetime(copy ne)'}}
|
||||||
ne
|
ne
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime() // expected-error{{expected identifier, index or self in lifetime dependence specifier}}
|
@lifetime() // expected-error{{expected identifier, index or self in lifetime dependence specifier}}
|
||||||
func testMissingDependence(_ ne: NE) -> NE {
|
func testMissingDependence(_ ne: NE) -> NE { // expected-error{{cannot infer the lifetime dependence scope on a function with a ~Escapable parameter, specify '@lifetime(borrow ne)' or '@lifetime(copy ne)'}}
|
||||||
ne
|
ne
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
// RUN: %empty-directory(%t)
|
// RUN: %empty-directory(%t)
|
||||||
// RUN: %target-build-swift -target %target-swift-5.1-abi-triple -parse-stdlib %s -module-name main -o %t/a.out
|
// RUN: %target-build-swift -target %target-swift-5.1-abi-triple -parse-stdlib %s -module-name main -o %t/a.out \
|
||||||
|
// RUN: -enable-experimental-feature LifetimeDependence
|
||||||
// RUN: %target-codesign %t/a.out
|
// RUN: %target-codesign %t/a.out
|
||||||
// RUN: %target-run %t/a.out
|
// RUN: %target-run %t/a.out
|
||||||
// REQUIRES: executable_test
|
// REQUIRES: executable_test
|
||||||
// REQUIRES: concurrency
|
// REQUIRES: concurrency
|
||||||
|
// REQUIRES: swift_feature_LifetimeDependence
|
||||||
// UNSUPPORTED: use_os_stdlib
|
// UNSUPPORTED: use_os_stdlib
|
||||||
// UNSUPPORTED: back_deployment_runtime
|
// UNSUPPORTED: back_deployment_runtime
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ struct NCG<T> : ~Copyable {
|
|||||||
// CHECK-NEXT: var t: T
|
// CHECK-NEXT: var t: T
|
||||||
struct NEG<T : ~Escapable> : ~Escapable {
|
struct NEG<T : ~Escapable> : ~Escapable {
|
||||||
var t: T
|
var t: T
|
||||||
|
@lifetime(copy t)
|
||||||
init(_ t: consuming T) {
|
init(_ t: consuming T) {
|
||||||
self.t = t
|
self.t = t
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ internal func _overrideLifetime<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@_unsafeNonescapableResult
|
@_unsafeNonescapableResult
|
||||||
@lifetime(source)
|
@lifetime(copy source)
|
||||||
internal func _overrideLifetime<
|
internal func _overrideLifetime<
|
||||||
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
|
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
|
||||||
>(
|
>(
|
||||||
@@ -56,12 +56,12 @@ struct BufferView : ~Escapable {
|
|||||||
self.ptr = ptr
|
self.ptr = ptr
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers10BufferViewVyACSW_AA7WrapperVtcfC : $@convention(method) (UnsafeRawBufferPointer, @owned Wrapper, @thin BufferView.Type) -> @lifetime(copy 1) @owned BufferView {
|
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers10BufferViewVyACSW_AA7WrapperVtcfC : $@convention(method) (UnsafeRawBufferPointer, @owned Wrapper, @thin BufferView.Type) -> @lifetime(copy 1) @owned BufferView {
|
||||||
@lifetime(a)
|
@lifetime(copy a)
|
||||||
init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper) {
|
init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper) {
|
||||||
self.ptr = ptr
|
self.ptr = ptr
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers10BufferViewVyACSW_AA7WrapperVSaySiGhtcfC : $@convention(method) (UnsafeRawBufferPointer, @owned Wrapper, @guaranteed Array<Int>, @thin BufferView.Type) -> @lifetime(copy 1, borrow 2) @owned BufferView {
|
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers10BufferViewVyACSW_AA7WrapperVSaySiGhtcfC : $@convention(method) (UnsafeRawBufferPointer, @owned Wrapper, @guaranteed Array<Int>, @thin BufferView.Type) -> @lifetime(copy 1, borrow 2) @owned BufferView {
|
||||||
@lifetime(a, borrow b)
|
@lifetime(copy a, borrow b)
|
||||||
init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper, _ b: borrowing Array<Int>) {
|
init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper, _ b: borrowing Array<Int>) {
|
||||||
self.ptr = ptr
|
self.ptr = ptr
|
||||||
}
|
}
|
||||||
@@ -93,14 +93,14 @@ func derive(_ x: borrowing BufferView) -> BufferView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers16consumeAndCreateyAA10BufferViewVADnF : $@convention(thin) (@owned BufferView) -> @lifetime(copy 0) @owned BufferView {
|
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers16consumeAndCreateyAA10BufferViewVADnF : $@convention(thin) (@owned BufferView) -> @lifetime(copy 0) @owned BufferView {
|
||||||
@lifetime(x)
|
@lifetime(copy x)
|
||||||
func consumeAndCreate(_ x: consuming BufferView) -> BufferView {
|
func consumeAndCreate(_ x: consuming BufferView) -> BufferView {
|
||||||
let bv = BufferView(independent: x.ptr)
|
let bv = BufferView(independent: x.ptr)
|
||||||
return _overrideLifetime(bv, copying: x)
|
return _overrideLifetime(bv, copying: x)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers17deriveThisOrThat1yAA10BufferViewVAD_ADtF : $@convention(thin) (@guaranteed BufferView, @guaranteed BufferView) -> @lifetime(copy 1, borrow 0) @owned BufferView {
|
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers17deriveThisOrThat1yAA10BufferViewVAD_ADtF : $@convention(thin) (@guaranteed BufferView, @guaranteed BufferView) -> @lifetime(copy 1, borrow 0) @owned BufferView {
|
||||||
@lifetime(borrow this, that)
|
@lifetime(borrow this, copy that)
|
||||||
func deriveThisOrThat1(_ this: borrowing BufferView, _ that: borrowing BufferView) -> BufferView {
|
func deriveThisOrThat1(_ this: borrowing BufferView, _ that: borrowing BufferView) -> BufferView {
|
||||||
if (Int.random(in: 1..<100) == 0) {
|
if (Int.random(in: 1..<100) == 0) {
|
||||||
return BufferView(independent: this.ptr)
|
return BufferView(independent: this.ptr)
|
||||||
@@ -109,7 +109,7 @@ func deriveThisOrThat1(_ this: borrowing BufferView, _ that: borrowing BufferVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers17deriveThisOrThat2yAA10BufferViewVAD_ADntF : $@convention(thin) (@guaranteed BufferView, @owned BufferView) -> @lifetime(copy 1, borrow 0) @owned BufferView {
|
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers17deriveThisOrThat2yAA10BufferViewVAD_ADntF : $@convention(thin) (@guaranteed BufferView, @owned BufferView) -> @lifetime(copy 1, borrow 0) @owned BufferView {
|
||||||
@lifetime(borrow this, that)
|
@lifetime(borrow this, copy that)
|
||||||
func deriveThisOrThat2(_ this: borrowing BufferView, _ that: consuming BufferView) -> BufferView {
|
func deriveThisOrThat2(_ this: borrowing BufferView, _ that: consuming BufferView) -> BufferView {
|
||||||
if (Int.random(in: 1..<100) == 0) {
|
if (Int.random(in: 1..<100) == 0) {
|
||||||
return BufferView(independent: this.ptr)
|
return BufferView(independent: this.ptr)
|
||||||
@@ -122,6 +122,7 @@ func use(_ x: borrowing BufferView) {}
|
|||||||
|
|
||||||
struct Wrapper : ~Escapable {
|
struct Wrapper : ~Escapable {
|
||||||
let view: BufferView
|
let view: BufferView
|
||||||
|
@lifetime(copy view)
|
||||||
init(_ view: consuming BufferView) {
|
init(_ view: consuming BufferView) {
|
||||||
self.view = view
|
self.view = view
|
||||||
}
|
}
|
||||||
@@ -132,7 +133,7 @@ struct Wrapper : ~Escapable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers7WrapperV8getView2AA10BufferViewVyF : $@convention(method) (@owned Wrapper) -> @lifetime(copy 0) @owned BufferView {
|
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers7WrapperV8getView2AA10BufferViewVyF : $@convention(method) (@owned Wrapper) -> @lifetime(copy 0) @owned BufferView {
|
||||||
@lifetime(self)
|
@lifetime(copy self)
|
||||||
consuming func getView2() -> BufferView {
|
consuming func getView2() -> BufferView {
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
@@ -147,7 +148,7 @@ struct Container : ~Escapable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers16getConsumingViewyAA06BufferG0VAA9ContainerVnF : $@convention(thin) (@owned Container) -> @lifetime(copy 0) @owned BufferView {
|
// CHECK-LABEL: sil hidden @$s39explicit_lifetime_dependence_specifiers16getConsumingViewyAA06BufferG0VAA9ContainerVnF : $@convention(thin) (@owned Container) -> @lifetime(copy 0) @owned BufferView {
|
||||||
@lifetime(x)
|
@lifetime(copy x)
|
||||||
func getConsumingView(_ x: consuming Container) -> BufferView {
|
func getConsumingView(_ x: consuming Container) -> BufferView {
|
||||||
let bv = BufferView(independent: x.ptr)
|
let bv = BufferView(independent: x.ptr)
|
||||||
return _overrideLifetime(bv, copying: x)
|
return _overrideLifetime(bv, copying: x)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ internal func _overrideLifetime<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@_unsafeNonescapableResult
|
@_unsafeNonescapableResult
|
||||||
@lifetime(source)
|
@lifetime(copy source)
|
||||||
internal func _overrideLifetime<
|
internal func _overrideLifetime<
|
||||||
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
|
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
|
||||||
>(
|
>(
|
||||||
@@ -43,16 +43,19 @@ struct BufferView : ~Escapable {
|
|||||||
self.c = c
|
self.c = c
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence10BufferViewVyA2ChcfC : $@convention(method) (@guaranteed BufferView, @thin BufferView.Type) -> @lifetime(copy 0) @owned BufferView {
|
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence10BufferViewVyA2ChcfC : $@convention(method) (@guaranteed BufferView, @thin BufferView.Type) -> @lifetime(copy 0) @owned BufferView {
|
||||||
|
@lifetime(copy otherBV)
|
||||||
init(_ otherBV: borrowing BufferView) {
|
init(_ otherBV: borrowing BufferView) {
|
||||||
self.ptr = otherBV.ptr
|
self.ptr = otherBV.ptr
|
||||||
self.c = otherBV.c
|
self.c = otherBV.c
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence10BufferViewVyA2CcfC : $@convention(method) (@owned BufferView, @thin BufferView.Type) -> @lifetime(copy 0) @owned BufferView {
|
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence10BufferViewVyA2CcfC : $@convention(method) (@owned BufferView, @thin BufferView.Type) -> @lifetime(copy 0) @owned BufferView {
|
||||||
|
@lifetime(copy otherBV)
|
||||||
init(_ otherBV: consuming BufferView) {
|
init(_ otherBV: consuming BufferView) {
|
||||||
self.ptr = otherBV.ptr
|
self.ptr = otherBV.ptr
|
||||||
self.c = otherBV.c
|
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 {
|
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence10BufferViewVyACSW_SaySiGhtcfC : $@convention(method) (UnsafeRawBufferPointer, @guaranteed Array<Int>, @thin BufferView.Type) -> @lifetime(borrow 0) @owned BufferView {
|
||||||
|
@lifetime(borrow ptr)
|
||||||
init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array<Int>) {
|
init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array<Int>) {
|
||||||
self.ptr = ptr
|
self.ptr = ptr
|
||||||
self.c = a.count
|
self.c = a.count
|
||||||
@@ -80,15 +83,18 @@ func testBasic() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence6deriveyAA10BufferViewVADF : $@convention(thin) (@guaranteed BufferView) -> @lifetime(copy 0) @owned BufferView {
|
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence6deriveyAA10BufferViewVADF : $@convention(thin) (@guaranteed BufferView) -> @lifetime(copy 0) @owned BufferView {
|
||||||
|
@lifetime(copy x)
|
||||||
func derive(_ x: borrowing BufferView) -> BufferView {
|
func derive(_ x: borrowing BufferView) -> BufferView {
|
||||||
return BufferView(x.ptr, x.c)
|
return BufferView(x.ptr, x.c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(copy x)
|
||||||
func derive(_ unused: Int, _ x: borrowing BufferView) -> BufferView {
|
func derive(_ unused: Int, _ x: borrowing BufferView) -> BufferView {
|
||||||
return BufferView(independent: x.ptr, x.c)
|
return BufferView(independent: x.ptr, x.c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence16consumeAndCreateyAA10BufferViewVADnF : $@convention(thin) (@owned BufferView) -> @lifetime(copy 0) @owned BufferView {
|
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence16consumeAndCreateyAA10BufferViewVADnF : $@convention(thin) (@owned BufferView) -> @lifetime(copy 0) @owned BufferView {
|
||||||
|
@lifetime(copy x)
|
||||||
func consumeAndCreate(_ x: consuming BufferView) -> BufferView {
|
func consumeAndCreate(_ x: consuming BufferView) -> BufferView {
|
||||||
let bv = BufferView(independent: x.ptr, x.c)
|
let bv = BufferView(independent: x.ptr, x.c)
|
||||||
return _overrideLifetime(bv, copying: x)
|
return _overrideLifetime(bv, copying: x)
|
||||||
@@ -100,24 +106,29 @@ struct Wrapper : ~Escapable {
|
|||||||
var _view: BufferView
|
var _view: BufferView
|
||||||
var view: BufferView {
|
var view: BufferView {
|
||||||
// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV4viewAA10BufferViewVvr : $@yield_once @convention(method) (@guaranteed Wrapper) -> @lifetime(copy 0) @yields @guaranteed BufferView {
|
// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV4viewAA10BufferViewVvr : $@yield_once @convention(method) (@guaranteed Wrapper) -> @lifetime(copy 0) @yields @guaranteed BufferView {
|
||||||
|
@lifetime(copy self)
|
||||||
_read {
|
_read {
|
||||||
yield _view
|
yield _view
|
||||||
}
|
}
|
||||||
// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV4viewAA10BufferViewVvM : $@yield_once @convention(method) (@inout Wrapper) -> @lifetime(copy 0) @yields @inout BufferView {
|
// CHECK: sil hidden @$s28implicit_lifetime_dependence7WrapperV4viewAA10BufferViewVvM : $@yield_once @convention(method) (@inout Wrapper) -> @lifetime(borrow 0) @yields @inout BufferView {
|
||||||
|
@lifetime(borrow self)
|
||||||
_modify {
|
_modify {
|
||||||
yield &_view
|
yield &_view
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence7WrapperVyAcA10BufferViewVcfC : $@convention(method) (@owned BufferView, @thin Wrapper.Type) -> @lifetime(copy 0) @owned Wrapper {
|
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence7WrapperVyAcA10BufferViewVcfC : $@convention(method) (@owned BufferView, @thin Wrapper.Type) -> @lifetime(copy 0) @owned Wrapper {
|
||||||
|
@lifetime(copy view)
|
||||||
init(_ view: consuming BufferView) {
|
init(_ view: consuming BufferView) {
|
||||||
self._view = view
|
self._view = view
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence7WrapperV8getView1AA10BufferViewVyKF : $@convention(method) (@guaranteed Wrapper) -> @lifetime(copy 0) (@owned BufferView, @error any Error) {
|
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence7WrapperV8getView1AA10BufferViewVyKF : $@convention(method) (@guaranteed Wrapper) -> @lifetime(copy 0) (@owned BufferView, @error any Error) {
|
||||||
|
@lifetime(copy self)
|
||||||
borrowing func getView1() throws -> BufferView {
|
borrowing func getView1() throws -> BufferView {
|
||||||
return _view
|
return _view
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence7WrapperV8getView2AA10BufferViewVyYaKF : $@convention(method) @async (@owned Wrapper) -> @lifetime(copy 0) (@owned BufferView, @error any Error) {
|
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence7WrapperV8getView2AA10BufferViewVyYaKF : $@convention(method) @async (@owned Wrapper) -> @lifetime(copy 0) (@owned BufferView, @error any Error) {
|
||||||
|
@lifetime(copy self)
|
||||||
consuming func getView2() async throws -> BufferView {
|
consuming func getView2() async throws -> BufferView {
|
||||||
return _view
|
return _view
|
||||||
}
|
}
|
||||||
@@ -185,6 +196,7 @@ struct GenericBufferView<Element> : ~Escapable {
|
|||||||
}
|
}
|
||||||
// CHECK: sil hidden @$s28implicit_lifetime_dependence17GenericBufferViewVyACyxGAA9FakeRangeVySVGcig : $@convention(method) <Element> (FakeRange<UnsafeRawPointer>, @guaranteed GenericBufferView<Element>) -> @lifetime(copy 1) @owned GenericBufferView<Element> {
|
// 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 {
|
subscript(bounds: FakeRange<Pointer>) -> Self {
|
||||||
|
@lifetime(copy self)
|
||||||
get {
|
get {
|
||||||
let pointer = UnsafeRawPointer(bounds.lowerBound)
|
let pointer = UnsafeRawPointer(bounds.lowerBound)
|
||||||
let result = GenericBufferView(
|
let result = GenericBufferView(
|
||||||
@@ -198,6 +210,7 @@ struct GenericBufferView<Element> : ~Escapable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence23tupleLifetimeDependenceyAA10BufferViewV_ADtADF : $@convention(thin) (@guaranteed BufferView) -> @lifetime(copy 0) (@owned BufferView, @owned BufferView) {
|
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence23tupleLifetimeDependenceyAA10BufferViewV_ADtADF : $@convention(thin) (@guaranteed BufferView) -> @lifetime(copy 0) (@owned BufferView, @owned BufferView) {
|
||||||
|
@lifetime(copy x)
|
||||||
func tupleLifetimeDependence(_ x: borrowing BufferView) -> (BufferView, BufferView) {
|
func tupleLifetimeDependence(_ x: borrowing BufferView) -> (BufferView, BufferView) {
|
||||||
return (BufferView(x.ptr, x.c), BufferView(x.ptr, x.c))
|
return (BufferView(x.ptr, x.c), BufferView(x.ptr, x.c))
|
||||||
}
|
}
|
||||||
@@ -206,27 +219,31 @@ public struct OuterNE: ~Escapable {
|
|||||||
// A public property generates an implicit setter with an infered dependence on 'newValue'.
|
// A public property generates an implicit setter with an infered dependence on 'newValue'.
|
||||||
//
|
//
|
||||||
// [inner1.setter]
|
// [inner1.setter]
|
||||||
// CHECK-LABEL: sil [transparent] @$s28implicit_lifetime_dependence7OuterNEV6inner1AC05InnerE0Vvs : $@convention(method) (@owned OuterNE.InnerNE, @lifetime(copy 0) @inout OuterNE) -> () {
|
// CHECK-LABEL: sil [transparent] @$s28implicit_lifetime_dependence7OuterNEV6inner1AC05InnerE0Vvs : $@convention(method) (@owned OuterNE.InnerNE, @lifetime(copy 0, copy 1) @inout OuterNE) -> () {
|
||||||
public var inner1: InnerNE
|
public var inner1: InnerNE
|
||||||
|
|
||||||
// Explicit setter with an infered dependence on 'newValue'.
|
// Explicit setter with an infered dependence on 'newValue'.
|
||||||
public var inner2: InnerNE {
|
public var inner2: InnerNE {
|
||||||
|
@lifetime(copy self)
|
||||||
get { inner1 }
|
get { inner1 }
|
||||||
|
@lifetime(self: copy newValue)
|
||||||
set { inner1 = newValue }
|
set { inner1 = newValue }
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct InnerNE: ~Escapable {
|
public struct InnerNE: ~Escapable {
|
||||||
|
@lifetime(copy owner)
|
||||||
init<Owner: ~Escapable & ~Copyable>(
|
init<Owner: ~Escapable & ~Copyable>(
|
||||||
owner: borrowing Owner
|
owner: borrowing Owner
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(copy owner)
|
||||||
init<Owner: ~Copyable & ~Escapable>(owner: borrowing Owner) {
|
init<Owner: ~Copyable & ~Escapable>(owner: borrowing Owner) {
|
||||||
self.inner1 = InnerNE(owner: owner)
|
self.inner1 = InnerNE(owner: owner)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence7OuterNEV8setInner5valueyAC0gE0V_tF : $@convention(method) (@guaranteed OuterNE.InnerNE, @lifetime(copy 0) @inout OuterNE) -> () {
|
// CHECK-LABEL: sil hidden @$s28implicit_lifetime_dependence7OuterNEV8setInner5valueyAC0gE0V_tF : $@convention(method) (@guaranteed OuterNE.InnerNE, @lifetime(copy 0) @inout OuterNE) -> () {
|
||||||
@lifetime(self: value)
|
@lifetime(self: copy value)
|
||||||
mutating func setInner(value: InnerNE) {
|
mutating func setInner(value: InnerNE) {
|
||||||
self.inner1 = value
|
self.inner1 = value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
public struct Span<Element> : ~Escapable {
|
public struct Span<Element> : ~Escapable {
|
||||||
private var baseAddress: UnsafeRawPointer
|
private var baseAddress: UnsafeRawPointer
|
||||||
public let count: Int
|
public let count: Int
|
||||||
|
@lifetime(copy owner)
|
||||||
public init<Owner: ~Copyable & ~Escapable>(
|
public init<Owner: ~Copyable & ~Escapable>(
|
||||||
baseAddress: UnsafeRawPointer,
|
baseAddress: UnsafeRawPointer,
|
||||||
count: Int,
|
count: Int,
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ internal func _overrideLifetime<
|
|||||||
}
|
}
|
||||||
|
|
||||||
@_unsafeNonescapableResult
|
@_unsafeNonescapableResult
|
||||||
@lifetime(source)
|
@lifetime(copy source)
|
||||||
internal func _overrideLifetime<
|
internal func _overrideLifetime<
|
||||||
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
|
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
|
||||||
>(
|
>(
|
||||||
@@ -83,7 +83,7 @@ public struct Span<Element> : ~Escapable {
|
|||||||
public let count: Int
|
public let count: Int
|
||||||
private var baseAddress: UnsafeRawPointer { start._rawValue }
|
private var baseAddress: UnsafeRawPointer { start._rawValue }
|
||||||
// CHECK-LABEL: sil @$s025lifetime_dependence_span_A5_attr4SpanV11baseAddress5count9dependsOnACyxGSV_Siqd__htcRi_d__Ri0_d__lufC : $@convention(method) <Element><Owner where Owner : ~Copyable, Owner : ~Escapable> (UnsafeRawPointer, Int, @in_guaranteed Owner, @thin Span<Element>.Type) -> @lifetime(copy 2) @owned Span<Element> {
|
// CHECK-LABEL: sil @$s025lifetime_dependence_span_A5_attr4SpanV11baseAddress5count9dependsOnACyxGSV_Siqd__htcRi_d__Ri0_d__lufC : $@convention(method) <Element><Owner where Owner : ~Copyable, Owner : ~Escapable> (UnsafeRawPointer, Int, @in_guaranteed Owner, @thin Span<Element>.Type) -> @lifetime(copy 2) @owned Span<Element> {
|
||||||
@lifetime(owner)
|
@lifetime(copy owner)
|
||||||
public init<Owner: ~Copyable & ~Escapable>(
|
public init<Owner: ~Copyable & ~Escapable>(
|
||||||
baseAddress: UnsafeRawPointer,
|
baseAddress: UnsafeRawPointer,
|
||||||
count: Int,
|
count: Int,
|
||||||
@@ -94,7 +94,7 @@ public struct Span<Element> : ~Escapable {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: sil hidden @$s025lifetime_dependence_span_A5_attr4SpanV5start5count9dependsOnACyxGAA0E5IndexVyxG_Siqd__htcRi_d__Ri0_d__lufC : $@convention(method) <Element><Owner where Owner : ~Copyable, Owner : ~Escapable> (SpanIndex<Element>, Int, @in_guaranteed Owner, @thin Span<Element>.Type) -> @lifetime(copy 2) @owned Span<Element> {
|
// CHECK-LABEL: sil hidden @$s025lifetime_dependence_span_A5_attr4SpanV5start5count9dependsOnACyxGAA0E5IndexVyxG_Siqd__htcRi_d__Ri0_d__lufC : $@convention(method) <Element><Owner where Owner : ~Copyable, Owner : ~Escapable> (SpanIndex<Element>, Int, @in_guaranteed Owner, @thin Span<Element>.Type) -> @lifetime(copy 2) @owned Span<Element> {
|
||||||
@lifetime(owner)
|
@lifetime(copy owner)
|
||||||
init<Owner: ~Copyable & ~Escapable>(
|
init<Owner: ~Copyable & ~Escapable>(
|
||||||
start index: SpanIndex<Element>,
|
start index: SpanIndex<Element>,
|
||||||
count: Int,
|
count: Int,
|
||||||
@@ -150,7 +150,7 @@ extension Span {
|
|||||||
|
|
||||||
// CHECK-LABEL: sil @$s025lifetime_dependence_span_A5_attr4SpanVyACyxGAA9FakeRangeVyAA0E5IndexVyxGGcig : $@convention(method) <Element> (FakeRange<SpanIndex<Element>>, @guaranteed Span<Element>) -> @lifetime(copy 1) @owned Span<Element> {
|
// CHECK-LABEL: sil @$s025lifetime_dependence_span_A5_attr4SpanVyACyxGAA9FakeRangeVyAA0E5IndexVyxGGcig : $@convention(method) <Element> (FakeRange<SpanIndex<Element>>, @guaranteed Span<Element>) -> @lifetime(copy 1) @owned Span<Element> {
|
||||||
public subscript(bounds: FakeRange<SpanIndex<Element>>) -> Self {
|
public subscript(bounds: FakeRange<SpanIndex<Element>>) -> Self {
|
||||||
@lifetime(self)
|
@lifetime(copy self)
|
||||||
get {
|
get {
|
||||||
let span = Span(
|
let span = Span(
|
||||||
start: bounds.lowerBound,
|
start: bounds.lowerBound,
|
||||||
@@ -161,7 +161,7 @@ extension Span {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: sil @$s025lifetime_dependence_span_A5_attr4SpanV6prefix4upToACyxGAA0E5IndexVyxG_tF : $@convention(method) <Element> (SpanIndex<Element>, @guaranteed Span<Element>) -> @lifetime(copy 1) @owned Span<Element> {
|
// CHECK-LABEL: sil @$s025lifetime_dependence_span_A5_attr4SpanV6prefix4upToACyxGAA0E5IndexVyxG_tF : $@convention(method) <Element> (SpanIndex<Element>, @guaranteed Span<Element>) -> @lifetime(copy 1) @owned Span<Element> {
|
||||||
@lifetime(self)
|
@lifetime(copy self)
|
||||||
borrowing public func prefix(upTo index: SpanIndex<Element>) -> Self {
|
borrowing public func prefix(upTo index: SpanIndex<Element>) -> Self {
|
||||||
index == startIndex
|
index == startIndex
|
||||||
? Self(start: start, count: 0, dependsOn: copy self)
|
? Self(start: start, count: 0, dependsOn: copy self)
|
||||||
@@ -169,14 +169,14 @@ extension Span {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: sil @$s025lifetime_dependence_span_A5_attr4SpanV6prefix7throughACyxGAA0E5IndexVyxG_tF : $@convention(method) <Element> (SpanIndex<Element>, @guaranteed Span<Element>) -> @lifetime(copy 1) @owned Span<Element> {
|
// CHECK-LABEL: sil @$s025lifetime_dependence_span_A5_attr4SpanV6prefix7throughACyxGAA0E5IndexVyxG_tF : $@convention(method) <Element> (SpanIndex<Element>, @guaranteed Span<Element>) -> @lifetime(copy 1) @owned Span<Element> {
|
||||||
@lifetime(self)
|
@lifetime(copy self)
|
||||||
borrowing public func prefix(through index: Index) -> Self {
|
borrowing public func prefix(through index: Index) -> Self {
|
||||||
let nc = distance(from: startIndex, to: index) &+ 1
|
let nc = distance(from: startIndex, to: index) &+ 1
|
||||||
return Self(start: start, count: nc, dependsOn: copy self)
|
return Self(start: start, count: nc, dependsOn: copy self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: sil @$s025lifetime_dependence_span_A5_attr4SpanV6prefixyACyxGSiF : $@convention(method) <Element> (Int, @owned Span<Element>) -> @lifetime(copy 1) @owned Span<Element> {
|
// CHECK-LABEL: sil @$s025lifetime_dependence_span_A5_attr4SpanV6prefixyACyxGSiF : $@convention(method) <Element> (Int, @owned Span<Element>) -> @lifetime(copy 1) @owned Span<Element> {
|
||||||
@lifetime(self)
|
@lifetime(copy self)
|
||||||
consuming public func prefix(_ maxLength: Int) -> Self {
|
consuming public func prefix(_ maxLength: Int) -> Self {
|
||||||
precondition(maxLength >= 0, "Can't have a prefix of negative length.")
|
precondition(maxLength >= 0, "Can't have a prefix of negative length.")
|
||||||
let nc = maxLength < count ? maxLength : count
|
let nc = maxLength < count ? maxLength : count
|
||||||
|
|||||||
@@ -7,9 +7,11 @@
|
|||||||
// RUN: -module-name Swift \
|
// RUN: -module-name Swift \
|
||||||
// RUN: -disable-availability-checking \
|
// RUN: -disable-availability-checking \
|
||||||
// RUN: -enable-experimental-feature BuiltinModule \
|
// RUN: -enable-experimental-feature BuiltinModule \
|
||||||
|
// RUN: -enable-experimental-feature LifetimeDependence \
|
||||||
// RUN: -enable-builtin-module
|
// RUN: -enable-builtin-module
|
||||||
|
|
||||||
// REQUIRES: swift_feature_BuiltinModule
|
// REQUIRES: swift_feature_BuiltinModule
|
||||||
|
// REQUIRES: swift_feature_LifetimeDependence
|
||||||
|
|
||||||
// Force verification of TypeLowering's isTrivial.
|
// Force verification of TypeLowering's isTrivial.
|
||||||
|
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ func check(_ t: borrowing any NoEscapeP & ~Escapable) {}
|
|||||||
// CHECK: sil hidden [ossa] @$s4main5checkyyAA9NoEscapeP_pRi0_s_XPnF : $@convention(thin) (@in any NoEscapeP & ~Escapable) -> () {
|
// CHECK: sil hidden [ossa] @$s4main5checkyyAA9NoEscapeP_pRi0_s_XPnF : $@convention(thin) (@in any NoEscapeP & ~Escapable) -> () {
|
||||||
func check(_ t: consuming any NoEscapeP & ~Escapable) {}
|
func check(_ t: consuming any NoEscapeP & ~Escapable) {}
|
||||||
|
|
||||||
// CHECK: sil hidden [ossa] @$s4main5checkyyAA9NoEscapeP_pRi0_s_XPzF : $@convention(thin) (@inout any NoEscapeP & ~Escapable) -> () {
|
// CHECK: sil hidden [ossa] @$s4main5checkyyAA9NoEscapeP_pRi0_s_XPzF : $@convention(thin) (@lifetime(copy 0) @inout any NoEscapeP & ~Escapable) -> () {
|
||||||
func check(_ t: inout any NoEscapeP & ~Escapable) {}
|
func check(_ t: inout any NoEscapeP & ~Escapable) {}
|
||||||
|
|
||||||
// MARK: conditionally Copyable & Escapable SILGen
|
// MARK: conditionally Copyable & Escapable SILGen
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ internal func _overrideLifetime<
|
|||||||
@_unsafeNonescapableResult
|
@_unsafeNonescapableResult
|
||||||
@_alwaysEmitIntoClient
|
@_alwaysEmitIntoClient
|
||||||
@_transparent
|
@_transparent
|
||||||
@lifetime(source)
|
@lifetime(copy source)
|
||||||
internal func _overrideLifetime<
|
internal func _overrideLifetime<
|
||||||
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
|
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
|
||||||
>(
|
>(
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ struct View : ~Escapable {
|
|||||||
self.ptr = ptr
|
self.ptr = ptr
|
||||||
self.c = c
|
self.c = c
|
||||||
}
|
}
|
||||||
|
@lifetime(copy otherBV)
|
||||||
init(_ otherBV: borrowing View) {
|
init(_ otherBV: borrowing View) {
|
||||||
self.ptr = otherBV.ptr
|
self.ptr = otherBV.ptr
|
||||||
self.c = otherBV.c
|
self.c = otherBV.c
|
||||||
@@ -23,6 +24,7 @@ struct View : ~Escapable {
|
|||||||
}
|
}
|
||||||
// This overload requires a separate label because overloading
|
// This overload requires a separate label because overloading
|
||||||
// on borrowing/consuming attributes is not allowed
|
// on borrowing/consuming attributes is not allowed
|
||||||
|
@lifetime(copy k)
|
||||||
init(consumingView k: consuming View) {
|
init(consumingView k: consuming View) {
|
||||||
self.ptr = k.ptr
|
self.ptr = k.ptr
|
||||||
self.c = k.c
|
self.c = k.c
|
||||||
@@ -34,13 +36,16 @@ struct Wrapper : ~Escapable {
|
|||||||
|
|
||||||
// Nested coroutine access.
|
// Nested coroutine access.
|
||||||
var view: View {
|
var view: View {
|
||||||
|
@lifetime(copy self)
|
||||||
_read {
|
_read {
|
||||||
yield _view
|
yield _view
|
||||||
}
|
}
|
||||||
|
@lifetime(borrow self)
|
||||||
_modify {
|
_modify {
|
||||||
yield &_view
|
yield &_view
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@lifetime(copy view)
|
||||||
init(_ view: consuming View) {
|
init(_ view: consuming View) {
|
||||||
self._view = view
|
self._view = view
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ struct Span<T>: ~Escapable {
|
|||||||
struct Wrapper<T: BitwiseCopyable>: ~Escapable {
|
struct Wrapper<T: BitwiseCopyable>: ~Escapable {
|
||||||
private let span: Span<T>
|
private let span: Span<T>
|
||||||
|
|
||||||
|
@lifetime(copy span)
|
||||||
init(span: borrowing Span<T>) {
|
init(span: borrowing Span<T>) {
|
||||||
self.span = copy span
|
self.span = copy span
|
||||||
}
|
}
|
||||||
@@ -41,6 +42,7 @@ struct SuperWrapper<T: BitwiseCopyable>: ~Escapable {
|
|||||||
|
|
||||||
// Make sure that LocalVariableUtils can successfully analyze 'self'. That's required to determine that the assignment
|
// Make sure that LocalVariableUtils can successfully analyze 'self'. That's required to determine that the assignment
|
||||||
// of `wrapper` is returned without escaping
|
// of `wrapper` is returned without escaping
|
||||||
|
@lifetime(copy span)
|
||||||
init(span: borrowing Span<T>) {
|
init(span: borrowing Span<T>) {
|
||||||
self.wrapper = Wrapper(span: span)
|
self.wrapper = Wrapper(span: span)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ struct Span<T>: ~Escapable {
|
|||||||
struct Wrapper<T: BitwiseCopyable>: ~Escapable {
|
struct Wrapper<T: BitwiseCopyable>: ~Escapable {
|
||||||
private let span: Span<T>
|
private let span: Span<T>
|
||||||
|
|
||||||
|
@lifetime(copy span)
|
||||||
init(span: borrowing Span<T>) {
|
init(span: borrowing Span<T>) {
|
||||||
self.span = copy span
|
self.span = copy span
|
||||||
}
|
}
|
||||||
@@ -41,6 +42,7 @@ struct SuperWrapper<T: BitwiseCopyable>: ~Escapable {
|
|||||||
|
|
||||||
// Make sure that LocalVariableUtils can successfully analyze 'self'. That's required to determine that the assignment
|
// Make sure that LocalVariableUtils can successfully analyze 'self'. That's required to determine that the assignment
|
||||||
// of `wrapper` is returned without escaping
|
// of `wrapper` is returned without escaping
|
||||||
|
@lifetime(copy span)
|
||||||
init(span: borrowing Span<T>) {
|
init(span: borrowing Span<T>) {
|
||||||
self.wrapper = Wrapper(span: span)
|
self.wrapper = Wrapper(span: span)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ struct MBV : ~Escapable, ~Copyable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Requires a borrow.
|
// Requires a borrow.
|
||||||
@lifetime(self)
|
@lifetime(copy self)
|
||||||
borrowing func getBV() -> BV {
|
borrowing func getBV() -> BV {
|
||||||
BV(p, i)
|
BV(p, i)
|
||||||
}
|
}
|
||||||
@@ -55,25 +55,26 @@ struct MBV : ~Escapable, ~Copyable {
|
|||||||
struct NEBV : ~Escapable {
|
struct NEBV : ~Escapable {
|
||||||
var bv: BV
|
var bv: BV
|
||||||
|
|
||||||
|
@lifetime(copy bv)
|
||||||
init(_ bv: consuming BV) {
|
init(_ bv: consuming BV) {
|
||||||
self.bv = bv
|
self.bv = bv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Propagate a borrow.
|
// Propagate a borrow.
|
||||||
@lifetime(container)
|
@lifetime(copy container)
|
||||||
func bv_get_borrow(container: borrowing MBV) -> BV {
|
func bv_get_borrow(container: borrowing MBV) -> BV {
|
||||||
container.getBV()
|
container.getBV()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy a borrow.
|
// Copy a borrow.
|
||||||
@lifetime(container)
|
@lifetime(copy container)
|
||||||
func bv_get_copy(container: borrowing MBV) -> BV {
|
func bv_get_copy(container: borrowing MBV) -> BV {
|
||||||
return container.getBV()
|
return container.getBV()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recognize nested accesses as part of the same dependence scope.
|
// Recognize nested accesses as part of the same dependence scope.
|
||||||
@lifetime(container)
|
@lifetime(copy container)
|
||||||
func bv_get_mutate(container: inout MBV) -> BV {
|
func bv_get_mutate(container: inout MBV) -> BV {
|
||||||
container.getBV()
|
container.getBV()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ struct NE : ~Escapable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(copy container)
|
||||||
func bv_get_consume(container: consuming NE) -> BV {
|
func bv_get_consume(container: consuming NE) -> BV {
|
||||||
return container.getBV() // expected-error {{lifetime-dependent value escapes its scope}}
|
return container.getBV() // expected-error {{lifetime-dependent value escapes its scope}}
|
||||||
// expected-note @-1{{it depends on this scoped access to variable 'container'}}
|
// expected-note @-1{{it depends on this scoped access to variable 'container'}}
|
||||||
@@ -70,12 +71,12 @@ struct Wrapper : ~Escapable {
|
|||||||
let bv: BV
|
let bv: BV
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(bv2)
|
@lifetime(copy bv2)
|
||||||
func bv_incorrect_annotation1(_ bv1: borrowing BV, _ bv2: borrowing BV) -> BV { // expected-error {{lifetime-dependent variable 'bv1' escapes its scope}}
|
func bv_incorrect_annotation1(_ bv1: borrowing BV, _ bv2: borrowing BV) -> BV { // expected-error {{lifetime-dependent variable 'bv1' escapes its scope}}
|
||||||
return copy bv1 // expected-note @-1{{it depends on the lifetime of argument 'bv1'}}
|
return copy bv1 // expected-note @-1{{it depends on the lifetime of argument 'bv1'}}
|
||||||
} // expected-note @-1{{this use causes the lifetime-dependent value to escape}}
|
} // expected-note @-1{{this use causes the lifetime-dependent value to escape}}
|
||||||
|
|
||||||
@lifetime(w2)
|
@lifetime(copy w2)
|
||||||
func bv_incorrect_annotation2(_ w1: borrowing Wrapper, _ w2: borrowing Wrapper) -> BV { // expected-error {{lifetime-dependent variable 'w1' escapes its scope}}
|
func bv_incorrect_annotation2(_ w1: borrowing Wrapper, _ w2: borrowing Wrapper) -> BV { // expected-error {{lifetime-dependent variable 'w1' escapes its scope}}
|
||||||
return w1.bv // expected-note @-1{{it depends on the lifetime of argument 'w1'}}
|
return w1.bv // expected-note @-1{{it depends on the lifetime of argument 'w1'}}
|
||||||
} // expected-note @-1{{this use causes the lifetime-dependent value to escape}}
|
} // expected-note @-1{{this use causes the lifetime-dependent value to escape}}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ struct BV : ~Escapable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(bv)
|
@lifetime(copy bv)
|
||||||
func bv_copy(_ bv: borrowing BV) -> BV {
|
func bv_copy(_ bv: borrowing BV) -> BV {
|
||||||
copy bv
|
copy bv
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ public struct NEInt: ~Escapable {
|
|||||||
var i: Int
|
var i: Int
|
||||||
|
|
||||||
// Test yielding an address.
|
// Test yielding an address.
|
||||||
// CHECK-LABEL: sil hidden @$s4test5NEIntV5ipropSivM : $@yield_once @convention(method) (@inout NEInt) -> @yields @inout Int {
|
// CHECK-LABEL: sil hidden @$s4test5NEIntV5ipropSivM : $@yield_once @convention(method) (@inout NEInt) -> @lifetime(borrow 0) @yields @inout Int
|
||||||
// CHECK: bb0(%0 : $*NEInt):
|
// CHECK: bb0(%0 : $*NEInt):
|
||||||
// CHECK: [[A:%.*]] = begin_access [modify] [static] %0 : $*NEInt
|
// CHECK: [[A:%.*]] = begin_access [modify] [static] %0 : $*NEInt
|
||||||
// CHECK: [[E:%.*]] = struct_element_addr [[A]] : $*NEInt, #NEInt.i
|
// CHECK: [[E:%.*]] = struct_element_addr [[A]] : $*NEInt, #NEInt.i
|
||||||
@@ -39,7 +39,9 @@ public struct NEInt: ~Escapable {
|
|||||||
// CHECK: end_access [[A]] : $*NEInt
|
// CHECK: end_access [[A]] : $*NEInt
|
||||||
// CHECK-LABEL: } // end sil function '$s4test5NEIntV5ipropSivM'
|
// CHECK-LABEL: } // end sil function '$s4test5NEIntV5ipropSivM'
|
||||||
var iprop: Int {
|
var iprop: Int {
|
||||||
|
@lifetime(copy self)
|
||||||
_read { yield i }
|
_read { yield i }
|
||||||
|
@lifetime(borrow self)
|
||||||
_modify { yield &i }
|
_modify { yield &i }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +58,7 @@ public enum NEOptional<Wrapped: ~Escapable>: ~Escapable {
|
|||||||
|
|
||||||
extension NEOptional where Wrapped: ~Escapable {
|
extension NEOptional where Wrapped: ~Escapable {
|
||||||
// Test that enum initialization passes diagnostics.
|
// Test that enum initialization passes diagnostics.
|
||||||
|
@lifetime(copy some)
|
||||||
public init(_ some: consuming Wrapped) { self = .some(some) }
|
public init(_ some: consuming Wrapped) { self = .some(some) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ struct NCInt: ~Copyable {
|
|||||||
struct NEInt: ~Escapable {
|
struct NEInt: ~Escapable {
|
||||||
let value: Builtin.Int64
|
let value: Builtin.Int64
|
||||||
|
|
||||||
@lifetime(o)
|
@lifetime(copy o)
|
||||||
init<O: ~Copyable & ~Escapable>(v: Builtin.Int64, o: borrowing O) {
|
init<O: ~Copyable & ~Escapable>(v: Builtin.Int64, o: borrowing O) {
|
||||||
self.value = v
|
self.value = v
|
||||||
}
|
}
|
||||||
@@ -64,17 +64,17 @@ struct NEInt: ~Escapable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(ne)
|
@lifetime(copy ne)
|
||||||
public func consume_indirect<NE: ~Escapable>(ne: consuming NE) -> NE {
|
public func consume_indirect<NE: ~Escapable>(ne: consuming NE) -> NE {
|
||||||
return ne
|
return ne
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(ne)
|
@lifetime(copy ne)
|
||||||
public func copy_indirect<NE: ~Escapable>(ne: borrowing NE) -> NE {
|
public func copy_indirect<NE: ~Escapable>(ne: borrowing NE) -> NE {
|
||||||
return copy ne
|
return copy ne
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(ne)
|
@lifetime(copy ne)
|
||||||
public func copy_inout<NE: ~Escapable>(ne: inout NE) -> NE {
|
public func copy_inout<NE: ~Escapable>(ne: inout NE) -> NE {
|
||||||
return copy ne
|
return copy ne
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
// TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence should be expressed by a builtin that is
|
// TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence should be expressed by a builtin that is
|
||||||
// hidden within the function body.
|
// hidden within the function body.
|
||||||
@_unsafeNonescapableResult
|
@_unsafeNonescapableResult
|
||||||
@lifetime(source)
|
@lifetime(copy source)
|
||||||
func unsafeLifetime<T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable>(
|
func unsafeLifetime<T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable>(
|
||||||
dependent: consuming T, dependsOn source: borrowing U)
|
dependent: consuming T, dependsOn source: borrowing U)
|
||||||
-> T {
|
-> T {
|
||||||
@@ -34,7 +34,7 @@ struct BV : ~Escapable {
|
|||||||
self.i = i
|
self.i = i
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(self)
|
@lifetime(copy self)
|
||||||
consuming func derive() -> BV {
|
consuming func derive() -> BV {
|
||||||
// Technically, this "new" view does not depend on the 'view' argument.
|
// Technically, this "new" view does not depend on the 'view' argument.
|
||||||
// This unsafely creates a new view with no dependence.
|
// This unsafely creates a new view with no dependence.
|
||||||
@@ -48,14 +48,17 @@ struct NEBV : ~Escapable {
|
|||||||
var bv: BV
|
var bv: BV
|
||||||
|
|
||||||
// Test lifetime inheritance through initialization.
|
// Test lifetime inheritance through initialization.
|
||||||
|
@lifetime(copy bv)
|
||||||
init(_ bv: consuming BV) {
|
init(_ bv: consuming BV) {
|
||||||
self.bv = bv
|
self.bv = bv
|
||||||
}
|
}
|
||||||
|
|
||||||
var view: BV {
|
var view: BV {
|
||||||
|
@lifetime(copy self)
|
||||||
_read {
|
_read {
|
||||||
yield bv
|
yield bv
|
||||||
}
|
}
|
||||||
|
@lifetime(borrow self)
|
||||||
_modify {
|
_modify {
|
||||||
yield &bv
|
yield &bv
|
||||||
}
|
}
|
||||||
@@ -68,18 +71,18 @@ struct NEBV : ~Escapable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Test lifetime inheritance through chained consumes.
|
// Test lifetime inheritance through chained consumes.
|
||||||
@lifetime(bv)
|
@lifetime(copy bv)
|
||||||
func bv_derive(bv: consuming BV) -> BV {
|
func bv_derive(bv: consuming BV) -> BV {
|
||||||
bv.derive()
|
bv.derive()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test lifetime inheritance through stored properties.
|
// Test lifetime inheritance through stored properties.
|
||||||
@lifetime(nebv)
|
@lifetime(copy nebv)
|
||||||
func ne_extract_member(nebv: consuming NEBV) -> BV {
|
func ne_extract_member(nebv: consuming NEBV) -> BV {
|
||||||
return nebv.bv
|
return nebv.bv
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(nebv)
|
@lifetime(copy nebv)
|
||||||
func ne_yield_member(nebv: consuming NEBV) -> BV {
|
func ne_yield_member(nebv: consuming NEBV) -> BV {
|
||||||
return nebv.view
|
return nebv.view
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
// TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence should be expressed by a builtin that is
|
// TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence should be expressed by a builtin that is
|
||||||
// hidden within the function body.
|
// hidden within the function body.
|
||||||
@_unsafeNonescapableResult
|
@_unsafeNonescapableResult
|
||||||
@lifetime(source)
|
@lifetime(copy source)
|
||||||
func unsafeLifetime<T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable>(
|
func unsafeLifetime<T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable>(
|
||||||
dependent: consuming T, dependsOn source: borrowing U)
|
dependent: consuming T, dependsOn source: borrowing U)
|
||||||
-> T {
|
-> T {
|
||||||
@@ -46,7 +46,7 @@ struct BV : ~Escapable {
|
|||||||
struct NE : ~Escapable {
|
struct NE : ~Escapable {
|
||||||
var bv: BV
|
var bv: BV
|
||||||
|
|
||||||
@lifetime(bv)
|
@lifetime(copy bv)
|
||||||
init(_ bv: consuming BV) {
|
init(_ bv: consuming BV) {
|
||||||
self.bv = bv
|
self.bv = bv
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ internal func _overrideLifetime<
|
|||||||
/// the `source` argument.
|
/// the `source` argument.
|
||||||
@_unsafeNonescapableResult
|
@_unsafeNonescapableResult
|
||||||
@_transparent
|
@_transparent
|
||||||
@lifetime(source)
|
@lifetime(copy source)
|
||||||
internal func _overrideLifetime<
|
internal func _overrideLifetime<
|
||||||
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
|
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
|
||||||
>(
|
>(
|
||||||
@@ -91,7 +91,10 @@ struct MutableSpan : ~Escapable, ~Copyable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var iterator: Iter { Iter(base: base, count: count) }
|
var iterator: Iter {
|
||||||
|
@lifetime(copy self)
|
||||||
|
get { Iter(base: base, count: count) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Array where Element == Int {
|
extension Array where Element == Int {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ extension Nillable: ExpressibleByNilLiteral where Wrapped: ~Copyable & ~Escapabl
|
|||||||
|
|
||||||
extension Nillable where Wrapped: ~Copyable & ~Escapable {
|
extension Nillable where Wrapped: ~Copyable & ~Escapable {
|
||||||
@_transparent
|
@_transparent
|
||||||
|
@lifetime(copy some)
|
||||||
public init(_ some: consuming Wrapped) { self = .some(some) }
|
public init(_ some: consuming Wrapped) { self = .some(some) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
// TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence should be expressed by a builtin that is
|
// TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence should be expressed by a builtin that is
|
||||||
// hidden within the function body.
|
// hidden within the function body.
|
||||||
@_unsafeNonescapableResult
|
@_unsafeNonescapableResult
|
||||||
@lifetime(source)
|
@lifetime(copy source)
|
||||||
func unsafeLifetime<T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable>(
|
func unsafeLifetime<T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable>(
|
||||||
dependent: consuming T, dependsOn source: borrowing U)
|
dependent: consuming T, dependsOn source: borrowing U)
|
||||||
-> T {
|
-> T {
|
||||||
@@ -38,7 +38,7 @@ struct BV : ~Escapable {
|
|||||||
public var isEmpty: Bool { i == 0 }
|
public var isEmpty: Bool { i == 0 }
|
||||||
|
|
||||||
// Test consuming `self`
|
// Test consuming `self`
|
||||||
@lifetime(self)
|
@lifetime(copy self)
|
||||||
consuming func derive() -> BV {
|
consuming func derive() -> BV {
|
||||||
// Technically, this "new" view does not depend on the 'view' argument.
|
// Technically, this "new" view does not depend on the 'view' argument.
|
||||||
// This unsafely creates a new view with no dependence.
|
// This unsafely creates a new view with no dependence.
|
||||||
@@ -51,7 +51,7 @@ struct BV : ~Escapable {
|
|||||||
struct NE {
|
struct NE {
|
||||||
var bv: BV
|
var bv: BV
|
||||||
|
|
||||||
@lifetime(bv)
|
@lifetime(copy bv)
|
||||||
init(_ bv: BV) {
|
init(_ bv: BV) {
|
||||||
self.bv = bv
|
self.bv = bv
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,44 +33,47 @@ struct NC : ~Copyable {
|
|||||||
struct NE {
|
struct NE {
|
||||||
var bv: BV
|
var bv: BV
|
||||||
|
|
||||||
@lifetime(bv)
|
@lifetime(copy bv)
|
||||||
init(_ bv: consuming BV) {
|
init(_ bv: consuming BV) {
|
||||||
self.bv = bv
|
self.bv = bv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func bv_assign_inout(bv: BV, other: inout BV) { // expected-error{{lifetime-dependent variable 'bv' escapes its scope}}
|
@lifetime(other: copy bv)
|
||||||
// expected-note @-1 {{it depends on the lifetime of argument 'bv'}}
|
func bv_assign_inout_copy(bv: BV, other: inout BV) {
|
||||||
other = bv // expected-note {{this use causes the lifetime-dependent value to escape}}
|
other = bv // OK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(other: borrow bv)
|
||||||
|
func bv_assign_inout_borrow(bv: BV, other: inout BV) {
|
||||||
|
other = bv
|
||||||
|
}
|
||||||
|
|
||||||
|
@lifetime(bv: copy bv)
|
||||||
|
@lifetime(other: copy bv)
|
||||||
func bvmut_assign_inout(bv: inout BV, other: inout BV) {
|
func bvmut_assign_inout(bv: inout BV, other: inout BV) {
|
||||||
other = bv // expected-error{{lifetime-dependent value escapes its scope}}
|
other = bv
|
||||||
// expected-note @-2 {{it depends on the lifetime of argument 'bv'}}
|
|
||||||
// expected-note @-2 {{this use causes the lifetime-dependent value to escape}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(other: copy bv)
|
||||||
func bvcons_assign_inout(bv: consuming BV, other: inout BV) {
|
func bvcons_assign_inout(bv: consuming BV, other: inout BV) {
|
||||||
other = bv // expected-error{{lifetime-dependent value escapes its scope}}
|
other = bv
|
||||||
// expected-note @-2 {{it depends on the lifetime of argument 'bv'}}
|
|
||||||
// expected-note @-2 {{this use causes the lifetime-dependent value to escape}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func bv_assign_field(bv: BV, other: inout NE) { // expected-error{{lifetime-dependent variable 'bv' escapes its scope}}
|
@lifetime(other: copy bv)
|
||||||
// expected-note @-1 {{it depends on the lifetime of argument 'bv'}}
|
func bv_assign_field(bv: BV, other: inout NE) {
|
||||||
other.bv = bv // expected-note {{this use causes the lifetime-dependent value to escape}}
|
other.bv = bv
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(bv: copy bv)
|
||||||
|
@lifetime(other: copy bv)
|
||||||
func bvmut_assign_field(bv: inout BV, other: inout NE) {
|
func bvmut_assign_field(bv: inout BV, other: inout NE) {
|
||||||
other.bv = bv // expected-error{{lifetime-dependent value escapes its scope}}
|
other.bv = bv
|
||||||
// expected-note @-2 {{it depends on the lifetime of argument 'bv'}}
|
|
||||||
// expected-note @-2 {{this use causes the lifetime-dependent value to escape}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(other: copy bv)
|
||||||
func bvcons_assign_field(bv: consuming BV, other: inout NE) {
|
func bvcons_assign_field(bv: consuming BV, other: inout NE) {
|
||||||
other.bv = bv // expected-error{{lifetime-dependent value escapes its scope}}
|
other.bv = bv
|
||||||
// expected-note @-2 {{it depends on the lifetime of argument 'bv'}}
|
|
||||||
// expected-note @-2 {{this use causes the lifetime-dependent value to escape}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func bv_capture_escape(bv: BV) -> ()->Int { // expected-error{{lifetime-dependent variable 'bv' escapes its scope}}
|
func bv_capture_escape(bv: BV) -> ()->Int { // expected-error{{lifetime-dependent variable 'bv' escapes its scope}}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ struct View : ~Escapable {
|
|||||||
self.ptr = ptr
|
self.ptr = ptr
|
||||||
self.c = c
|
self.c = c
|
||||||
}
|
}
|
||||||
|
@lifetime(copy otherBV)
|
||||||
init(_ otherBV: borrowing View) {
|
init(_ otherBV: borrowing View) {
|
||||||
self.ptr = otherBV.ptr
|
self.ptr = otherBV.ptr
|
||||||
self.c = otherBV.c
|
self.c = otherBV.c
|
||||||
@@ -32,6 +33,7 @@ struct View : ~Escapable {
|
|||||||
}
|
}
|
||||||
// This overload requires a separate label because overloading
|
// This overload requires a separate label because overloading
|
||||||
// on borrowing/consuming attributes is not allowed
|
// on borrowing/consuming attributes is not allowed
|
||||||
|
@lifetime(copy k)
|
||||||
init(consumingView k: consuming View) {
|
init(consumingView k: consuming View) {
|
||||||
self.ptr = k.ptr
|
self.ptr = k.ptr
|
||||||
self.c = k.c
|
self.c = k.c
|
||||||
@@ -46,6 +48,7 @@ struct MutableView : ~Copyable, ~Escapable {
|
|||||||
self.ptr = ptr
|
self.ptr = ptr
|
||||||
self.c = c
|
self.c = c
|
||||||
}
|
}
|
||||||
|
@lifetime(copy otherBV)
|
||||||
init(_ otherBV: borrowing View) {
|
init(_ otherBV: borrowing View) {
|
||||||
self.ptr = otherBV.ptr
|
self.ptr = otherBV.ptr
|
||||||
self.c = otherBV.c
|
self.c = otherBV.c
|
||||||
@@ -63,7 +66,7 @@ func consume(_ o : consuming View) {}
|
|||||||
func use(_ o : borrowing MutableView) {}
|
func use(_ o : borrowing MutableView) {}
|
||||||
func consume(_ o : consuming MutableView) {}
|
func consume(_ o : consuming MutableView) {}
|
||||||
|
|
||||||
@lifetime(x)
|
@lifetime(copy x)
|
||||||
func getConsumingView(_ x: consuming View) -> View {
|
func getConsumingView(_ x: consuming View) -> View {
|
||||||
return View(consumingView: x)
|
return View(consumingView: x)
|
||||||
}
|
}
|
||||||
@@ -190,13 +193,16 @@ func test8(_ a: Array<Int>) {
|
|||||||
struct Wrapper : ~Escapable {
|
struct Wrapper : ~Escapable {
|
||||||
var _view: View
|
var _view: View
|
||||||
var view: View {
|
var view: View {
|
||||||
|
@lifetime(copy self)
|
||||||
_read {
|
_read {
|
||||||
yield _view
|
yield _view
|
||||||
}
|
}
|
||||||
|
@lifetime(borrow self)
|
||||||
_modify {
|
_modify {
|
||||||
yield &_view
|
yield &_view
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@lifetime(copy view)
|
||||||
init(_ view: consuming View) {
|
init(_ view: consuming View) {
|
||||||
self._view = view
|
self._view = view
|
||||||
}
|
}
|
||||||
@@ -212,6 +218,7 @@ func test9() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(copy x)
|
||||||
func getViewTuple(_ x: borrowing View) -> (View, View) {
|
func getViewTuple(_ x: borrowing View) -> (View, View) {
|
||||||
return (View(x.ptr, x.c), View(x.ptr, x.c))
|
return (View(x.ptr, x.c), View(x.ptr, x.c))
|
||||||
}
|
}
|
||||||
@@ -236,4 +243,5 @@ public func test10() {
|
|||||||
func testPointeeDependenceOnMutablePointer(p: UnsafePointer<Int64>) {
|
func testPointeeDependenceOnMutablePointer(p: UnsafePointer<Int64>) {
|
||||||
var ptr = p
|
var ptr = p
|
||||||
_ = ptr.pointee
|
_ = ptr.pointee
|
||||||
|
_ = ptr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ internal func _overrideLifetime<
|
|||||||
/// the `source` argument.
|
/// the `source` argument.
|
||||||
@_unsafeNonescapableResult
|
@_unsafeNonescapableResult
|
||||||
@_transparent
|
@_transparent
|
||||||
@lifetime(source)
|
@lifetime(copy source)
|
||||||
internal func _overrideLifetime<
|
internal func _overrideLifetime<
|
||||||
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
|
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
|
||||||
>(
|
>(
|
||||||
@@ -83,6 +83,7 @@ public struct Span<T>: ~Escapable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension Span {
|
extension Span {
|
||||||
|
@lifetime(copy self)
|
||||||
consuming func dropFirst() -> Span<T> {
|
consuming func dropFirst() -> Span<T> {
|
||||||
let nextPointer = self.base.flatMap { $0 + 1 }
|
let nextPointer = self.base.flatMap { $0 + 1 }
|
||||||
let local = Span(base: nextPointer, count: self.count - 1)
|
let local = Span(base: nextPointer, count: self.count - 1)
|
||||||
@@ -91,6 +92,7 @@ extension Span {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension Span {
|
extension Span {
|
||||||
|
@lifetime(copy self)
|
||||||
mutating func droppingPrefix(length: Int) -> /* */ Span<T> {
|
mutating func droppingPrefix(length: Int) -> /* */ Span<T> {
|
||||||
let oldBase = base
|
let oldBase = base
|
||||||
let result = Span(base: oldBase, count: length)
|
let result = Span(base: oldBase, count: length)
|
||||||
@@ -231,6 +233,7 @@ struct Outer {
|
|||||||
|
|
||||||
func parse(_ span: Span<Int>) {}
|
func parse(_ span: Span<Int>) {}
|
||||||
|
|
||||||
|
@lifetime(copy arg)
|
||||||
func copySpan<T>(_ arg: Span<T>) -> /* */ Span<T> { arg }
|
func copySpan<T>(_ arg: Span<T>) -> /* */ Span<T> { arg }
|
||||||
|
|
||||||
@lifetime(borrow arg)
|
@lifetime(borrow arg)
|
||||||
@@ -600,12 +603,3 @@ func testBorrowedAddressableIntReturn(arg: Holder) -> Span<Int> {
|
|||||||
} // todo-note {{this use causes the lifetime-dependent value to escape}}
|
} // todo-note {{this use causes the lifetime-dependent value to escape}}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Parameter dependencies
|
|
||||||
// =============================================================================
|
|
||||||
|
|
||||||
// rdar://146401190 ([nonescapable] implement non-inout parameter dependencies)
|
|
||||||
@lifetime(span: borrow holder)
|
|
||||||
func testParameterDep(holder: Holder, span: Span<Int>) {} // expected-error {{lifetime-dependent parameter must be 'inout'}}
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
// TODO: uncomment the @lifetime annotations when we have component lifetimes.
|
// TODO: uncomment the @lifetime annotations when we have component lifetimes.
|
||||||
|
|
||||||
// @lifetime(elements)
|
// @lifetime(copy elements)
|
||||||
struct Span<T: ~Escapable>: ~Escapable {
|
struct Span<T: ~Escapable>: ~Escapable {
|
||||||
// Pretend that 'element' is in separate storage.
|
// Pretend that 'element' is in separate storage.
|
||||||
var element: T
|
var element: T
|
||||||
@@ -22,7 +22,7 @@ struct Span<T: ~Escapable>: ~Escapable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @lifetime(elements)
|
// @lifetime(copy elements)
|
||||||
extension Array {
|
extension Array {
|
||||||
// @lifetime(span: borrow self)
|
// @lifetime(span: borrow self)
|
||||||
// @lifetime(span.elements: copy self.elements)
|
// @lifetime(span.elements: copy self.elements)
|
||||||
@@ -34,7 +34,7 @@ extension Array {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// use 'scalars' instead of 'elements' to avoid confusion from nesting
|
// use 'scalars' instead of 'elements' to avoid confusion from nesting
|
||||||
// @lifetime(scalars)
|
// @lifetime(copy scalars)
|
||||||
struct Vec<T: ~Escapable>: ~Escapable {
|
struct Vec<T: ~Escapable>: ~Escapable {
|
||||||
// Pretend that 't' is in separate storage.
|
// Pretend that 't' is in separate storage.
|
||||||
var scalar: T
|
var scalar: T
|
||||||
|
|||||||
@@ -64,11 +64,13 @@ struct TestCoroAccessorOfCoroAccessor<T : ~Escapable> : ~Copyable & ~Escapable {
|
|||||||
var t: T
|
var t: T
|
||||||
|
|
||||||
var inner: TestCoroAccessorOfCoroAccessor<T> {
|
var inner: TestCoroAccessorOfCoroAccessor<T> {
|
||||||
|
@lifetime(copy self)
|
||||||
_read {
|
_read {
|
||||||
fatalError()
|
fatalError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var outer: TestCoroAccessorOfCoroAccessor<T> {
|
var outer: TestCoroAccessorOfCoroAccessor<T> {
|
||||||
|
@lifetime(copy self)
|
||||||
_read {
|
_read {
|
||||||
yield inner
|
yield inner
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// RUN: %empty-directory(%t)
|
// RUN: %empty-directory(%t)
|
||||||
// RUN: %target-swift-frontend -emit-module-path %t/SpanExtras.swiftmodule %S/Inputs/SpanExtras.swift -enable-builtin-module -enable-experimental-feature LifetimeDependence -O
|
// RUN: %target-swift-frontend -emit-module-path %t/SpanExtras.swiftmodule %S/Inputs/SpanExtras.swift -enable-builtin-module -enable-experimental-feature LifetimeDependence -O
|
||||||
// RUN: %target-swift-frontend -I %t -O -emit-sil %s -disable-availability-checking | %FileCheck %s --check-prefix=CHECK-SIL
|
// RUN: %target-swift-frontend -I %t -O -emit-sil %s -enable-experimental-feature LifetimeDependence -disable-availability-checking | %FileCheck %s --check-prefix=CHECK-SIL
|
||||||
// RUN: %target-swift-frontend -I %t -O -emit-ir %s -disable-availability-checking | %FileCheck %s --check-prefix=CHECK-IR
|
// RUN: %target-swift-frontend -I %t -O -emit-ir %s -enable-experimental-feature LifetimeDependence -disable-availability-checking | %FileCheck %s --check-prefix=CHECK-IR
|
||||||
|
|
||||||
// REQUIRES: swift_in_compiler
|
// REQUIRES: swift_in_compiler
|
||||||
// REQUIRES: swift_feature_LifetimeDependence
|
// REQUIRES: swift_feature_LifetimeDependence
|
||||||
@@ -44,6 +44,7 @@ public func span_zero_init(_ output: inout MutableSpan<Int>) {
|
|||||||
// CHECK-IR: define {{.*}} void @"$s31mutable_span_bounds_check_tests0B14_copy_elemwiseyy10SpanExtras07MutableH0VySiGz_s0H0VySiGtF"
|
// CHECK-IR: define {{.*}} void @"$s31mutable_span_bounds_check_tests0B14_copy_elemwiseyy10SpanExtras07MutableH0VySiGz_s0H0VySiGtF"
|
||||||
// CHECK-IR: vector.body
|
// CHECK-IR: vector.body
|
||||||
// CHECK-IR: store <{{.*}}>
|
// CHECK-IR: store <{{.*}}>
|
||||||
|
@lifetime(output: copy output, copy input)
|
||||||
public func span_copy_elemwise(_ output: inout MutableSpan<Int>, _ input: Span<Int>) {
|
public func span_copy_elemwise(_ output: inout MutableSpan<Int>, _ input: Span<Int>) {
|
||||||
precondition(output.count >= input.count)
|
precondition(output.count >= input.count)
|
||||||
for i in input.indices {
|
for i in input.indices {
|
||||||
@@ -65,6 +66,7 @@ public func span_copy_elemwise(_ output: inout MutableSpan<Int>, _ input: Span<I
|
|||||||
// CHECK-IR: define {{.*}} void @"$s31mutable_span_bounds_check_tests0B16_append_elemwiseyy10SpanExtras06OutputH0VySiGz_s0H0VySiGtF"
|
// CHECK-IR: define {{.*}} void @"$s31mutable_span_bounds_check_tests0B16_append_elemwiseyy10SpanExtras06OutputH0VySiGz_s0H0VySiGtF"
|
||||||
// CHECK-IR: vector.body
|
// CHECK-IR: vector.body
|
||||||
// CHECK-IR: store <{{.*}}>
|
// CHECK-IR: store <{{.*}}>
|
||||||
|
@lifetime(output: copy output, copy input)
|
||||||
public func span_append_elemwise(_ output: inout OutputSpan<Int>, _ input: Span<Int>) {
|
public func span_append_elemwise(_ output: inout OutputSpan<Int>, _ input: Span<Int>) {
|
||||||
for i in input.indices {
|
for i in input.indices {
|
||||||
output.append(input[i])
|
output.append(input[i])
|
||||||
@@ -83,6 +85,7 @@ public func span_append_elemwise(_ output: inout OutputSpan<Int>, _ input: Span<
|
|||||||
// CHECK-IR: define {{.*}} void @"$s31mutable_span_bounds_check_tests0B12_sum_wo_trapyy10SpanExtras07MutableI0VySiGz_s0I0VySiGAItF"
|
// CHECK-IR: define {{.*}} void @"$s31mutable_span_bounds_check_tests0B12_sum_wo_trapyy10SpanExtras07MutableI0VySiGz_s0I0VySiGAItF"
|
||||||
// CHECK-IR: vector.body
|
// CHECK-IR: vector.body
|
||||||
// CHECK-IR: store <{{.*}}>
|
// CHECK-IR: store <{{.*}}>
|
||||||
|
@lifetime(output: copy output, copy input1, copy input2)
|
||||||
public func span_sum_wo_trap(_ output: inout MutableSpan<Int>, _ input1: Span<Int>, _ input2: Span<Int>) {
|
public func span_sum_wo_trap(_ output: inout MutableSpan<Int>, _ input1: Span<Int>, _ input2: Span<Int>) {
|
||||||
precondition(input1.count == input2.count)
|
precondition(input1.count == input2.count)
|
||||||
precondition(output.count == input1.count)
|
precondition(output.count == input1.count)
|
||||||
@@ -97,7 +100,7 @@ public func span_sum_wo_trap(_ output: inout MutableSpan<Int>, _ input1: Span<In
|
|||||||
// CHECK-SIL-NOT: cond_fail {{.*}}, "precondition failure"
|
// CHECK-SIL-NOT: cond_fail {{.*}}, "precondition failure"
|
||||||
// CHECK-SIL: cond_br
|
// CHECK-SIL: cond_br
|
||||||
// CHECK-SIL-LABEL: } // end sil function '$s31mutable_span_bounds_check_tests0B14_sum_with_trapyy10SpanExtras07MutableI0VySiGz_s0I0VySiGAItF'
|
// CHECK-SIL-LABEL: } // end sil function '$s31mutable_span_bounds_check_tests0B14_sum_with_trapyy10SpanExtras07MutableI0VySiGz_s0I0VySiGAItF'
|
||||||
|
@lifetime(output: copy input1, copy input2)
|
||||||
public func span_sum_with_trap(_ output: inout MutableSpan<Int>, _ input1: Span<Int>, _ input2: Span<Int>) {
|
public func span_sum_with_trap(_ output: inout MutableSpan<Int>, _ input1: Span<Int>, _ input2: Span<Int>) {
|
||||||
precondition(input1.count == input2.count)
|
precondition(input1.count == input2.count)
|
||||||
precondition(output.count == input1.count)
|
precondition(output.count == input1.count)
|
||||||
|
|||||||
@@ -328,6 +328,7 @@ public func mutate_span(_ v: inout Span<Int>) { }
|
|||||||
// CHECK-SIL-NOT: cond_fail {{.*}}, "Index out of bounds"
|
// CHECK-SIL-NOT: cond_fail {{.*}}, "Index out of bounds"
|
||||||
// CHECK-SIL: cond_br
|
// CHECK-SIL: cond_br
|
||||||
// CHECK-SIL-LABEL: } // end sil function '$s23span_bounds_check_tests06inout_A33_sum_iterate_to_unknown_with_trapySis4SpanVySiGz_SitF'
|
// CHECK-SIL-LABEL: } // end sil function '$s23span_bounds_check_tests06inout_A33_sum_iterate_to_unknown_with_trapySis4SpanVySiGz_SitF'
|
||||||
|
@lifetime(v: copy v)
|
||||||
public func inout_span_sum_iterate_to_unknown_with_trap(_ v: inout Span<Int>, _ n: Int) -> Int {
|
public func inout_span_sum_iterate_to_unknown_with_trap(_ v: inout Span<Int>, _ n: Int) -> Int {
|
||||||
var sum = 0
|
var sum = 0
|
||||||
for i in 0...n {
|
for i in 0...n {
|
||||||
@@ -342,6 +343,7 @@ public func inout_span_sum_iterate_to_unknown_with_trap(_ v: inout Span<Int>, _
|
|||||||
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
|
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
|
||||||
// CHECK-SIL: cond_br
|
// CHECK-SIL: cond_br
|
||||||
// CHECK-SIL-LABEL: } // end sil function '$s23span_bounds_check_tests06inout_A41_sum_iterate_to_unknown_with_trap_dontoptySis4SpanVySiGz_SitF'
|
// CHECK-SIL-LABEL: } // end sil function '$s23span_bounds_check_tests06inout_A41_sum_iterate_to_unknown_with_trap_dontoptySis4SpanVySiGz_SitF'
|
||||||
|
@lifetime(v: copy v)
|
||||||
public func inout_span_sum_iterate_to_unknown_with_trap_dontopt(_ v: inout Span<Int>, _ n: Int) -> Int {
|
public func inout_span_sum_iterate_to_unknown_with_trap_dontopt(_ v: inout Span<Int>, _ n: Int) -> Int {
|
||||||
var sum = 0
|
var sum = 0
|
||||||
for i in 0...n {
|
for i in 0...n {
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
// RUN: %target-typecheck-verify-swift \
|
// RUN: %target-typecheck-verify-swift \
|
||||||
// RUN: -disable-availability-checking \
|
// RUN: -disable-availability-checking \
|
||||||
// RUN: -enable-experimental-feature Sensitive \
|
// RUN: -enable-experimental-feature Sensitive \
|
||||||
|
// RUN: -enable-experimental-feature LifetimeDependence \
|
||||||
// RUN: -enable-builtin-module \
|
// RUN: -enable-builtin-module \
|
||||||
// RUN: -debug-diagnostic-names
|
// RUN: -debug-diagnostic-names
|
||||||
|
|
||||||
// REQUIRES: swift_feature_Sensitive
|
// REQUIRES: swift_feature_Sensitive
|
||||||
|
// REQUIRES: swift_feature_LifetimeDependence
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
//===========================DEPENDENCY-FREE TESTS=(BEGIN)===================={{
|
//===========================DEPENDENCY-FREE TESTS=(BEGIN)===================={{
|
||||||
@@ -212,9 +214,7 @@ struct S_Explicit_With_2BitwiseCopyable_Generic_Optional<T : BitwiseCopyable> :
|
|||||||
var o2: T?
|
var o2: T?
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: When the standard library is built with NonescapableTypes, this should
|
struct S_Explicit_Nonescapable : ~Escapable, BitwiseCopyable {}
|
||||||
// be uncommented.
|
|
||||||
//struct S_Explicit_Nonescapable : ~Escapable, BitwiseCopyable {}
|
|
||||||
|
|
||||||
struct S_Explicit_Noncopyable : ~Copyable, BitwiseCopyable {} // expected-error{{type_does_not_conform}}
|
struct S_Explicit_Noncopyable : ~Copyable, BitwiseCopyable {} // expected-error{{type_does_not_conform}}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
// RUN: %target-typecheck-verify-swift \
|
// RUN: %target-typecheck-verify-swift \
|
||||||
// RUN: -enable-builtin-module \
|
// RUN: -enable-builtin-module \
|
||||||
|
// RUN: -enable-experimental-feature LifetimeDependence \
|
||||||
// RUN: -debug-diagnostic-names
|
// RUN: -debug-diagnostic-names
|
||||||
|
|
||||||
|
// REQUIRES: swift_feature_LifetimeDependence
|
||||||
|
|
||||||
// This test file only exists in order to test without noncopyable_generics and can be deleted once that is always enabled.
|
// This test file only exists in order to test without noncopyable_generics and can be deleted once that is always enabled.
|
||||||
|
|
||||||
@_nonescapable
|
@_nonescapable
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ struct BufferView : ~Escapable, ~Copyable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ImplicitInit1 : ~Escapable { // expected-error{{cannot infer lifetime dependence on implicit initializer, no parameters found that are either ~Escapable or Escapable with a borrowing ownership}}
|
struct ImplicitInit1 : ~Escapable {
|
||||||
let ptr: UnsafeRawBufferPointer
|
let ptr: UnsafeRawBufferPointer
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,20 +20,21 @@ struct ImplicitInit2 : ~Escapable, ~Copyable {
|
|||||||
let mbv: BufferView
|
let mbv: BufferView
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ImplicitInit3 : ~Escapable, ~Copyable { // expected-error{{cannot infer lifetime dependence on implicit initializer, multiple parameters qualifiy as a candidate}}
|
struct ImplicitInit3 : ~Escapable, ~Copyable {
|
||||||
let mbv1: BufferView
|
let mbv1: BufferView
|
||||||
let mbv2: BufferView
|
let mbv2: BufferView
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo1() -> BufferView { // expected-error{{cannot infer lifetime dependence, no parameters found that are either ~Escapable or Escapable with a borrowing ownership}}
|
func foo1() -> BufferView { // expected-error{{a function with a ~Escapable result needs a parameter to depend on}}
|
||||||
|
// expected-note@-1{{'@lifetime(immortal)' can be used to indicate that values produced by this initializer have no lifetime dependencies}}
|
||||||
return BufferView(nil, 0)
|
return BufferView(nil, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo2(_ i: borrowing Int) -> BufferView { // expected-error{{cannot infer lifetime dependence, no parameters found that are either ~Escapable or Escapable with a borrowing ownership}}
|
func foo2(_ i: borrowing Int) -> BufferView {
|
||||||
return BufferView(nil, 0)
|
return BufferView(nil, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func foo3<T: BitwiseCopyable>(arg: borrowing T) -> BufferView { // expected-error{{cannot infer lifetime dependence, no parameters found that are either ~Escapable or Escapable with a borrowing ownership}}
|
func foo3<T: BitwiseCopyable>(arg: borrowing T) -> BufferView {
|
||||||
return BufferView(nil, 0)
|
return BufferView(nil, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,16 +3,16 @@
|
|||||||
// REQUIRES: swift_feature_LifetimeDependence
|
// REQUIRES: swift_feature_LifetimeDependence
|
||||||
|
|
||||||
struct NE : ~Escapable {
|
struct NE : ~Escapable {
|
||||||
@lifetime(self) // expected-error{{invalid lifetime dependence on self in an initializer}}
|
@lifetime(copy self) // expected-error{{invalid lifetime dependence specifier on non-existent self}}
|
||||||
init() {}
|
init() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(nonexisting) // expected-error{{invalid parameter name specified 'nonexisting'}}
|
@lifetime(copy nonexisting) // expected-error{{invalid parameter name specified 'nonexisting'}}
|
||||||
func invalidAttrOnNonExistingParam(_ ne: NE) -> NE {
|
func invalidAttrOnNonExistingParam(_ ne: NE) -> NE {
|
||||||
ne
|
ne
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(self) // expected-error{{invalid lifetime dependence specifier on non-existent self}}
|
@lifetime(copy self) // expected-error{{invalid lifetime dependence specifier on non-existent self}}
|
||||||
func invalidAttrOnNonExistingSelf(_ ne: NE) -> NE {
|
func invalidAttrOnNonExistingSelf(_ ne: NE) -> NE {
|
||||||
ne
|
ne
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ func invalidAttrOnNonExistingParamIndex(_ ne: NE) -> NE {
|
|||||||
ne
|
ne
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(ne, ne) // expected-error{{duplicate lifetime dependence specifier}}
|
@lifetime(copy ne, borrow ne) // expected-error{{duplicate lifetime dependence specifier}}
|
||||||
func invalidDuplicateLifetimeDependence1(_ ne: borrowing NE) -> NE {
|
func invalidDuplicateLifetimeDependence1(_ ne: borrowing NE) -> NE {
|
||||||
ne
|
ne
|
||||||
}
|
}
|
||||||
@@ -34,8 +34,8 @@ func invalidDependence(_ x: consuming Klass) -> NE {
|
|||||||
NE()
|
NE()
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(result: source)
|
@lifetime(result: copy source)
|
||||||
@lifetime(result: source) // TODO: display error here
|
@lifetime(result: borrow source) // TODO: display error here
|
||||||
func invalidTarget(_ result: inout NE, _ source: consuming NE) { // expected-error{{invalid duplicate target lifetime dependencies on function}}
|
func invalidTarget(_ result: inout NE, _ source: consuming NE) { // expected-error{{invalid duplicate target lifetime dependencies on function}}
|
||||||
result = source
|
result = source
|
||||||
}
|
}
|
||||||
@@ -62,4 +62,4 @@ do {
|
|||||||
|
|
||||||
// rdar://146401190 ([nonescapable] implement non-inout parameter dependencies)
|
// rdar://146401190 ([nonescapable] implement non-inout parameter dependencies)
|
||||||
@lifetime(span: borrow holder)
|
@lifetime(span: borrow holder)
|
||||||
func testParameterDep(holder: Holder, span: Span<Int>) {} // expected-error {{lifetime-dependent parameter must be 'inout'}}
|
func testParameterDep(holder: AnyObject, span: Span<Int>) {} // expected-error{{lifetime-dependent parameter must be 'inout'}}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
// RUN: %target-typecheck-verify-swift -disable-availability-checking
|
// RUN: %target-typecheck-verify-swift -disable-availability-checking
|
||||||
// REQUIRES: asserts
|
// REQUIRES: asserts
|
||||||
|
|
||||||
struct NE : ~Escapable {
|
struct NE : ~Escapable { // expected-error{{an implicit initializer with a ~Escapable result requires '-enable-experimental-feature LifetimeDependence'}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(ne) // expected-error{{'@lifetime' attribute is only valid when experimental feature LifetimeDependence is enabled}} expected-error{{expected declaration}}
|
@lifetime(copy ne) // expected-error{{'@lifetime' attribute is only valid when experimental feature LifetimeDependence is enabled}} expected-error{{expected declaration}}
|
||||||
func derive(_ ne: NE) -> NE { // expected-error{{returning ~Escapable type requires '-enable-experimental-feature LifetimeDependence'}}
|
func derive(_ ne: NE) -> NE { // expected-error{{a function with a ~Escapable result requires '-enable-experimental-feature LifetimeDependence'}}
|
||||||
ne
|
ne
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ struct EscapableTrivialSelf {
|
|||||||
|
|
||||||
mutating func mutatingMethodOneParam(_: Int) -> NEImmortal { NEImmortal() } // expected-error{{a mutating method with a ~Escapable result requires '@lifetime(...)'}}
|
mutating func mutatingMethodOneParam(_: Int) -> NEImmortal { NEImmortal() } // expected-error{{a mutating method with a ~Escapable result requires '@lifetime(...)'}}
|
||||||
|
|
||||||
@lifetime(borrow self)
|
@lifetime(self)
|
||||||
mutating func mutatingMethodOneParamLifetime(_: Int) -> NEImmortal { NEImmortal() }
|
mutating func mutatingMethodOneParamLifetime(_: Int) -> NEImmortal { NEImmortal() }
|
||||||
|
|
||||||
@lifetime(copy self) // expected-error{{cannot copy the lifetime of an Escapable type, use '@lifetime(borrow self)' instead}}
|
@lifetime(copy self) // expected-error{{cannot copy the lifetime of an Escapable type, use '@lifetime(borrow self)' instead}}
|
||||||
@@ -135,7 +135,7 @@ struct EscapableNonTrivialSelf {
|
|||||||
|
|
||||||
func mutatingMethodNoParam() -> NEImmortal { NEImmortal() }
|
func mutatingMethodNoParam() -> NEImmortal { NEImmortal() }
|
||||||
|
|
||||||
@lifetime(borrow self)
|
@lifetime(self)
|
||||||
mutating func mutatingMethodNoParamLifetime() -> NEImmortal { NEImmortal() }
|
mutating func mutatingMethodNoParamLifetime() -> NEImmortal { NEImmortal() }
|
||||||
|
|
||||||
@lifetime(copy self) // expected-error{{cannot copy the lifetime of an Escapable type, use '@lifetime(borrow self)' instead}}
|
@lifetime(copy self) // expected-error{{cannot copy the lifetime of an Escapable type, use '@lifetime(borrow self)' instead}}
|
||||||
@@ -329,6 +329,7 @@ struct NonescapableSelfAccessors: ~Escapable {
|
|||||||
yield ne
|
yield ne
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(borrow self)
|
||||||
_modify {
|
_modify {
|
||||||
yield &ne
|
yield &ne
|
||||||
}
|
}
|
||||||
@@ -407,7 +408,7 @@ struct NonescapableSelfAccessors: ~Escapable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NoncopyableSelfAccessors: ~Copyable & ~Escapable { // expected-error{{cannot infer the lifetime dependence scope on an implicit initializer with a ~Escapable parameter, specify '@lifetime(borrow ne)' or '@lifetime(copy ne)'}}
|
struct NoncopyableSelfAccessors: ~Copyable & ~Escapable {
|
||||||
var ne: NE
|
var ne: NE
|
||||||
|
|
||||||
var neComputed: NE {
|
var neComputed: NE {
|
||||||
@@ -425,6 +426,7 @@ struct NoncopyableSelfAccessors: ~Copyable & ~Escapable { // expected-error{{can
|
|||||||
yield ne
|
yield ne
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(borrow self)
|
||||||
_modify {
|
_modify {
|
||||||
yield &ne
|
yield &ne
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,14 +13,17 @@ struct NE: ~Escapable {
|
|||||||
init() {}
|
init() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(copy ne)
|
||||||
func transfer(_ ne: NE) -> NE {
|
func transfer(_ ne: NE) -> NE {
|
||||||
ne
|
ne
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(copy ne)
|
||||||
func applyAnnotatedTransfer(ne: NE, @lifetime(0) transfer: (NE) -> NE) -> NE { // expected-error{{'@lifetime' attribute cannot be applied to this declaration}}
|
func applyAnnotatedTransfer(ne: NE, @lifetime(0) transfer: (NE) -> NE) -> NE { // expected-error{{'@lifetime' attribute cannot be applied to this declaration}}
|
||||||
transfer(ne)
|
transfer(ne)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(copy ne)
|
||||||
func applyTransfer(ne: NE, transfer: (NE) -> NE) -> NE {
|
func applyTransfer(ne: NE, transfer: (NE) -> NE) -> NE {
|
||||||
transfer(ne)
|
transfer(ne)
|
||||||
}
|
}
|
||||||
@@ -36,6 +39,7 @@ func borrow(_ nc: borrowing NC) -> NE {
|
|||||||
nc.ne
|
nc.ne
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(borrow nc)
|
||||||
func applyBorrow(nc: borrowing NC, borrow: (borrowing NC) -> NE) -> NE {
|
func applyBorrow(nc: borrowing NC, borrow: (borrowing NC) -> NE) -> NE {
|
||||||
borrow(nc)
|
borrow(nc)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ public struct BufferView : ~Escapable {
|
|||||||
public init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array<Int>) {
|
public init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array<Int>) {
|
||||||
self.ptr = ptr
|
self.ptr = ptr
|
||||||
}
|
}
|
||||||
@lifetime(a)
|
@lifetime(copy a)
|
||||||
public init(_ ptr: UnsafeRawBufferPointer, _ a: consuming AnotherView) {
|
public init(_ ptr: UnsafeRawBufferPointer, _ a: consuming AnotherView) {
|
||||||
self.ptr = ptr
|
self.ptr = ptr
|
||||||
}
|
}
|
||||||
@lifetime(a, borrow b)
|
@lifetime(copy a, borrow b)
|
||||||
public init(_ ptr: UnsafeRawBufferPointer, _ a: consuming AnotherView, _ b: borrowing Array<Int>) {
|
public init(_ ptr: UnsafeRawBufferPointer, _ a: consuming AnotherView, _ b: borrowing Array<Int>) {
|
||||||
self.ptr = ptr
|
self.ptr = ptr
|
||||||
}
|
}
|
||||||
@@ -48,12 +48,12 @@ public func borrowAndCreate(_ view: borrowing BufferView) -> BufferView {
|
|||||||
return BufferView(view.ptr)
|
return BufferView(view.ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(view)
|
@lifetime(copy view)
|
||||||
public func consumeAndCreate(_ view: consuming BufferView) -> BufferView {
|
public func consumeAndCreate(_ view: consuming BufferView) -> BufferView {
|
||||||
return BufferView(view.ptr)
|
return BufferView(view.ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@lifetime(borrow this, that)
|
@lifetime(borrow this, copy that)
|
||||||
public func deriveThisOrThat(_ this: borrowing BufferView, _ that: borrowing BufferView) -> BufferView {
|
public func deriveThisOrThat(_ this: borrowing BufferView, _ that: borrowing BufferView) -> BufferView {
|
||||||
if (Int.random(in: 1..<100) == 0) {
|
if (Int.random(in: 1..<100) == 0) {
|
||||||
return BufferView(this.ptr)
|
return BufferView(this.ptr)
|
||||||
@@ -63,13 +63,16 @@ public func deriveThisOrThat(_ this: borrowing BufferView, _ that: borrowing Buf
|
|||||||
|
|
||||||
public struct Wrapper : ~Escapable {
|
public struct Wrapper : ~Escapable {
|
||||||
var _view: BufferView
|
var _view: BufferView
|
||||||
|
@lifetime(copy view)
|
||||||
public init(_ view: consuming BufferView) {
|
public init(_ view: consuming BufferView) {
|
||||||
self._view = view
|
self._view = view
|
||||||
}
|
}
|
||||||
public var view: BufferView {
|
public var view: BufferView {
|
||||||
|
@lifetime(copy self)
|
||||||
_read {
|
_read {
|
||||||
yield _view
|
yield _view
|
||||||
}
|
}
|
||||||
|
@lifetime(borrow self)
|
||||||
_modify {
|
_modify {
|
||||||
yield &_view
|
yield &_view
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ public struct BufferView : ~Escapable {
|
|||||||
self.c = c
|
self.c = c
|
||||||
}
|
}
|
||||||
@inlinable
|
@inlinable
|
||||||
|
@lifetime(copy otherBV)
|
||||||
public init(_ otherBV: borrowing BufferView) {
|
public init(_ otherBV: borrowing BufferView) {
|
||||||
self.ptr = otherBV.ptr
|
self.ptr = otherBV.ptr
|
||||||
self.c = otherBV.c
|
self.c = otherBV.c
|
||||||
@@ -24,14 +25,17 @@ public struct MutableBufferView : ~Escapable, ~Copyable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@inlinable
|
@inlinable
|
||||||
|
@lifetime(copy x)
|
||||||
public func derive(_ x: borrowing BufferView) -> BufferView {
|
public func derive(_ x: borrowing BufferView) -> BufferView {
|
||||||
return BufferView(x.ptr, x.c)
|
return BufferView(x.ptr, x.c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(copy view)
|
||||||
public func borrowAndCreate(_ view: borrowing BufferView) -> BufferView {
|
public func borrowAndCreate(_ view: borrowing BufferView) -> BufferView {
|
||||||
return BufferView(view.ptr, view.c )
|
return BufferView(view.ptr, view.c )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lifetime(copy view)
|
||||||
public func consumeAndCreate(_ view: consuming BufferView) -> BufferView {
|
public func consumeAndCreate(_ view: consuming BufferView) -> BufferView {
|
||||||
return BufferView(view.ptr, view.c)
|
return BufferView(view.ptr, view.c)
|
||||||
}
|
}
|
||||||
@@ -54,13 +58,16 @@ public struct Container : ~Copyable {
|
|||||||
public struct Wrapper : ~Escapable {
|
public struct Wrapper : ~Escapable {
|
||||||
var _view: BufferView
|
var _view: BufferView
|
||||||
public var view: BufferView {
|
public var view: BufferView {
|
||||||
|
@lifetime(copy self)
|
||||||
_read {
|
_read {
|
||||||
yield _view
|
yield _view
|
||||||
}
|
}
|
||||||
|
@lifetime(borrow self)
|
||||||
_modify {
|
_modify {
|
||||||
yield &_view
|
yield &_view
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@lifetime(copy view)
|
||||||
public init(_ view: consuming BufferView) {
|
public init(_ view: consuming BufferView) {
|
||||||
self._view = view
|
self._view = view
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user