33// RUN: -verify \
44// RUN: -sil-verify-all \
55// RUN: -module-name test \
6+ // RUN: -enable-builtin-module \
67// RUN: -enable-experimental-feature LifetimeDependence \
78// RUN: -enable-experimental-feature AddressableParameters \
89// RUN: -enable-experimental-feature AddressableTypes
910
1011// REQUIRES: swift_in_compiler
1112// REQUIRES: swift_feature_LifetimeDependence
13+ // REQUIRES: swift_feature_AddressableParameters
14+ // REQUIRES: swift_feature_AddressableTypes
15+
16+ import Builtin
1217
1318@_unsafeNonescapableResult
1419@_transparent
@@ -69,6 +74,12 @@ public struct Span<T>: ~Escapable {
6974 self . base = base
7075 self . count = count
7176 }
77+
78+ public subscript( _ position: Int ) -> T {
79+ unsafeAddress {
80+ return base!. advanced ( by: position)
81+ }
82+ }
7283}
7384
7485extension Span {
@@ -131,9 +142,24 @@ struct InnerTrivial {
131142 }
132143}
133144
145+ struct TrivialHolder {
146+ var p : UnsafePointer < Int >
147+ var pa : UnsafePointer < AddressableInt >
148+
149+ var addressableInt : AddressableInt { unsafeAddress { pa } }
150+
151+ @lifetime ( borrow self)
152+ borrowing func span( ) -> Span < Int > {
153+ Span ( base: p, count: 1 )
154+ }
155+ }
156+
134157struct Holder {
135158 let object : AnyObject
136159 var p : UnsafePointer < Int >
160+ var pa : UnsafePointer < AddressableInt >
161+
162+ var addressableInt : AddressableInt { unsafeAddress { pa } }
137163
138164 @lifetime ( borrow self)
139165 borrowing func span( ) -> Span < Int > {
@@ -143,10 +169,11 @@ struct Holder {
143169
144170@_addressableForDependencies
145171struct AddressableInt {
146- let object : AnyObject
172+ let value : Int
147173
148174 @lifetime ( borrow self)
149175 borrowing func span( ) -> Span < Int > {
176+ // TODO: we actually want the address of self.value
150177 let p = UnsafePointer < Int > ( Builtin . unprotectedAddressOfBorrow ( self ) )
151178 let span = Span ( base: p, count: 1 )
152179 return _overrideLifetime ( span, borrowing: self )
@@ -159,6 +186,7 @@ struct AddressableObject {
159186
160187 @lifetime ( borrow self)
161188 borrowing func span( ) -> Span < AnyObject > {
189+ // TODO: we actually want the address of self.object
162190 let p = UnsafePointer < AnyObject > ( Builtin . unprotectedAddressOfBorrow ( self ) )
163191 let span = Span ( base: p, count: 1 )
164192 return _overrideLifetime ( span, borrowing: self )
@@ -506,29 +534,69 @@ func testReturnObjectTemp(outer: Outer) -> Span<Int> {
506534// Scoped dependence on addressable parameters
507535// =============================================================================
508536
537+ // @_addressableForDependencies supports returning a Span.
509538@lifetime ( borrow arg)
510539func testAddressableInt( arg: AddressableInt ) -> Span < Int > {
511540 arg. span ( )
512541}
513542
543+ // @_addressableForDependencies supports returning a Span.
514544@lifetime ( borrow arg)
515545func testAddressableObject( arg: AddressableObject ) -> Span < AnyObject > {
516546 arg. span ( )
517547}
518548
549+ // Helper: create a dependence on the argument's address.
519550@lifetime ( borrow arg)
520- func borrowAddressHelper ( arg: @addressable Holder ) -> Span < Int > {
551+ func dependsOnTrivialAddressHelper ( arg: @_addressable TrivialHolder ) -> Span < Int > {
521552 arg. span ( )
522553}
523554
555+ // Helper: create a dependence on the argument's address.
524556@lifetime ( borrow arg)
525- func testNonAddressable ( arg: Holder ) -> Span < Int > {
526- borrowAddressHelper ( arg: arg )
557+ func dependsOnAddressHelper ( arg: @ _addressable Holder ) -> Span < Int > {
558+ arg. span ( )
527559}
528560
561+ /* TODO: requires -enable-address-dependencies
562+
563+ // Non-addressable error returning a Span.
564+ @lifetime(borrow arg)
565+ func testTrivialNonAddressable(arg: TrivialHolder) -> Span<Int> {
566+ dependsOnTrivialAddressHelper(arg: arg)
567+ // todo-error @-1{{lifetime-dependent value escapes its scope}
568+ // todo-note @-3{{it depends on the lifetime of variable 'arg'}}
569+ } // todo-note {{this use causes the lifetime-dependent value to escape}}
570+
571+ // Non-addressable error returning a Span.
572+ @lifetime(borrow arg)
573+ func testNonAddressable(arg: Holder) -> Span<Int> {
574+ dependsOnAddressHelper(arg: arg)
575+ // todo-error @-1{{lifetime-dependent value escapes its scope}
576+ // todo-note @-3{{it depends on the lifetime of variable 'arg'}}
577+ } // todo-note {{this use causes the lifetime-dependent value to escape}}
578+ */
579+
529580/* TODO: rdar://145872854 (SILGen: @addressable inout arguments are copied)
530581@lifetime(borrow arg)
531582func test(arg: inout AddressableInt) -> Span<Int> {
532583 arg.span()
533584}
585+
586+ // unsafeAddress generates an addressable value with a local scope.
587+ @lifetime(borrow arg)
588+ func testBorrowedAddressableInt(arg: Holder) -> Int {
589+ let span = arg.addressableInt.span()
590+ return span[0]
591+ }
592+
593+ // unsafeAddress generates an addressable value.
594+ // Error returning a dependence on its local scope.
595+ @lifetime(borrow arg)
596+ func testBorrowedAddressableIntReturn(arg: Holder) -> Span<Int> {
597+ arg.addressableInt.span()
598+ // todo-error @-1{{lifetime-dependent value escapes its scope}
599+ // todo-note @-2{{it depends on the lifetime of this parent value}}
600+ } // todo-note {{this use causes the lifetime-dependent value to escape}}
601+
534602*/
0 commit comments