3
3
// RUN: -verify \
4
4
// RUN: -sil-verify-all \
5
5
// RUN: -module-name test \
6
+ // RUN: -enable-builtin-module \
6
7
// RUN: -enable-experimental-feature LifetimeDependence \
7
8
// RUN: -enable-experimental-feature AddressableParameters \
8
9
// RUN: -enable-experimental-feature AddressableTypes
9
10
10
11
// REQUIRES: swift_in_compiler
11
12
// REQUIRES: swift_feature_LifetimeDependence
13
+ // REQUIRES: swift_feature_AddressableParameters
14
+ // REQUIRES: swift_feature_AddressableTypes
15
+
16
+ import Builtin
12
17
13
18
@_unsafeNonescapableResult
14
19
@_transparent
@@ -69,6 +74,12 @@ public struct Span<T>: ~Escapable {
69
74
self . base = base
70
75
self . count = count
71
76
}
77
+
78
+ public subscript( _ position: Int ) -> T {
79
+ unsafeAddress {
80
+ return base!. advanced ( by: position)
81
+ }
82
+ }
72
83
}
73
84
74
85
extension Span {
@@ -131,9 +142,24 @@ struct InnerTrivial {
131
142
}
132
143
}
133
144
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
+
134
157
struct Holder {
135
158
let object : AnyObject
136
159
var p : UnsafePointer < Int >
160
+ var pa : UnsafePointer < AddressableInt >
161
+
162
+ var addressableInt : AddressableInt { unsafeAddress { pa } }
137
163
138
164
@lifetime ( borrow self)
139
165
borrowing func span( ) -> Span < Int > {
@@ -143,10 +169,11 @@ struct Holder {
143
169
144
170
@_addressableForDependencies
145
171
struct AddressableInt {
146
- let object : AnyObject
172
+ let value : Int
147
173
148
174
@lifetime ( borrow self)
149
175
borrowing func span( ) -> Span < Int > {
176
+ // TODO: we actually want the address of self.value
150
177
let p = UnsafePointer < Int > ( Builtin . unprotectedAddressOfBorrow ( self ) )
151
178
let span = Span ( base: p, count: 1 )
152
179
return _overrideLifetime ( span, borrowing: self )
@@ -159,6 +186,7 @@ struct AddressableObject {
159
186
160
187
@lifetime ( borrow self)
161
188
borrowing func span( ) -> Span < AnyObject > {
189
+ // TODO: we actually want the address of self.object
162
190
let p = UnsafePointer < AnyObject > ( Builtin . unprotectedAddressOfBorrow ( self ) )
163
191
let span = Span ( base: p, count: 1 )
164
192
return _overrideLifetime ( span, borrowing: self )
@@ -506,29 +534,69 @@ func testReturnObjectTemp(outer: Outer) -> Span<Int> {
506
534
// Scoped dependence on addressable parameters
507
535
// =============================================================================
508
536
537
+ // @_addressableForDependencies supports returning a Span.
509
538
@lifetime ( borrow arg)
510
539
func testAddressableInt( arg: AddressableInt ) -> Span < Int > {
511
540
arg. span ( )
512
541
}
513
542
543
+ // @_addressableForDependencies supports returning a Span.
514
544
@lifetime ( borrow arg)
515
545
func testAddressableObject( arg: AddressableObject ) -> Span < AnyObject > {
516
546
arg. span ( )
517
547
}
518
548
549
+ // Helper: create a dependence on the argument's address.
519
550
@lifetime ( borrow arg)
520
- func borrowAddressHelper ( arg: @addressable Holder ) -> Span < Int > {
551
+ func dependsOnTrivialAddressHelper ( arg: @_addressable TrivialHolder ) -> Span < Int > {
521
552
arg. span ( )
522
553
}
523
554
555
+ // Helper: create a dependence on the argument's address.
524
556
@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 ( )
527
559
}
528
560
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
+
529
580
/* TODO: rdar://145872854 (SILGen: @addressable inout arguments are copied)
530
581
@lifetime(borrow arg)
531
582
func test(arg: inout AddressableInt) -> Span<Int> {
532
583
arg.span()
533
584
}
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
+
534
602
*/
0 commit comments