Skip to content

Commit 8553f99

Browse files
authored
Merge pull request swiftlang#77912 from atrick/fix-span-deps
Add `unsafeLifetime` APIs and fix RawSpan initializer lifetime dependencies
2 parents 9bf17e8 + 0b7a9dd commit 8553f99

File tree

3 files changed

+162
-38
lines changed

3 files changed

+162
-38
lines changed

stdlib/public/core/LifetimeManager.swift

+36
Original file line numberDiff line numberDiff line change
@@ -283,3 +283,39 @@ extension String {
283283
public func _copy<T>(_ value: T) -> T {
284284
copy value
285285
}
286+
287+
/// Unsafely discard any lifetime dependency on the `dependent` argument. Return
288+
/// a value identical to `dependent` with a lifetime dependency on the caller's
289+
/// borrow scope of the `source` argument.
290+
@unsafe
291+
@_unsafeNonescapableResult
292+
@_alwaysEmitIntoClient
293+
@_transparent
294+
@lifetime(borrow source)
295+
internal func _overrideLifetime<
296+
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
297+
>(
298+
_ dependent: consuming T, borrowing source: borrowing U
299+
) -> T {
300+
// TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence
301+
// should be expressed by a builtin that is hidden within the function body.
302+
dependent
303+
}
304+
305+
/// Unsafely discard any lifetime dependency on the `dependent` argument. Return
306+
/// a value identical to `dependent` that inherits all lifetime dependencies from
307+
/// the `source` argument.
308+
@unsafe
309+
@_unsafeNonescapableResult
310+
@_alwaysEmitIntoClient
311+
@_transparent
312+
@lifetime(source)
313+
internal func _overrideLifetime<
314+
T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable
315+
>(
316+
_ dependent: consuming T, copying source: borrowing U
317+
) -> T {
318+
// TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence
319+
// should be expressed by a builtin that is hidden within the function body.
320+
dependent
321+
}

stdlib/public/core/Span/RawSpan.swift

+58-21
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,11 @@ extension RawSpan {
9797
public init(
9898
_unsafeBytes buffer: UnsafeRawBufferPointer
9999
) {
100-
self.init(
101-
_unchecked: buffer.baseAddress, byteCount: buffer.count
102-
)
100+
let baseAddress = buffer.baseAddress
101+
let span = RawSpan(_unchecked: baseAddress, byteCount: buffer.count)
102+
// As a trivial value, 'baseAddress' does not formally depend on the
103+
// lifetime of 'buffer'. Make the dependence explicit.
104+
self = _overrideLifetime(span, borrowing: buffer)
103105
}
104106

105107
/// Unsafely create a `RawSpan` over initialized memory.
@@ -115,7 +117,11 @@ extension RawSpan {
115117
public init(
116118
_unsafeBytes buffer: borrowing Slice<UnsafeRawBufferPointer>
117119
) {
118-
self.init(_unsafeBytes: UnsafeRawBufferPointer(rebasing: buffer))
120+
let rawBuffer = UnsafeRawBufferPointer(rebasing: buffer)
121+
let span = RawSpan(_unsafeBytes: rawBuffer)
122+
// As a trivial value, 'rawBuffer' does not formally depend on the
123+
// lifetime of 'buffer'. Make the dependence explicit.
124+
self = _overrideLifetime(span, borrowing: buffer)
119125
}
120126

121127
/// Unsafely create a `RawSpan` over initialized memory.
@@ -131,15 +137,24 @@ extension RawSpan {
131137
public init(
132138
_unsafeBytes buffer: UnsafeMutableRawBufferPointer
133139
) {
134-
self.init(_unsafeBytes: UnsafeRawBufferPointer(buffer))
140+
let rawBuffer = UnsafeRawBufferPointer(buffer)
141+
let span = RawSpan(_unsafeBytes: rawBuffer)
142+
// As a trivial value, 'rawBuffer' does not formally depend on the
143+
// lifetime of 'buffer'. Make the dependence explicit.
144+
self = _overrideLifetime(span, borrowing: buffer)
135145
}
136146

137147
@_alwaysEmitIntoClient
138148
@lifetime(borrow buffer)
139149
public init(
140150
_unsafeBytes buffer: borrowing Slice<UnsafeMutableRawBufferPointer>
141151
) {
142-
self.init(_unsafeBytes: UnsafeRawBufferPointer(rebasing: buffer))
152+
let rawBuffer =
153+
UnsafeRawBufferPointer(UnsafeMutableRawBufferPointer(rebasing: buffer))
154+
let span = RawSpan(_unsafeBytes: rawBuffer)
155+
// As a trivial value, 'rawBuffer' does not formally depend on the
156+
// lifetime of 'buffer'. Make the dependence explicit.
157+
self = _overrideLifetime(span, borrowing: buffer)
143158
}
144159

145160
/// Unsafely create a `RawSpan` over initialized memory.
@@ -175,7 +190,11 @@ extension RawSpan {
175190
public init<T: BitwiseCopyable>(
176191
_unsafeElements buffer: UnsafeBufferPointer<T>
177192
) {
178-
self.init(_unsafeBytes: UnsafeRawBufferPointer(buffer))
193+
let rawBuffer = UnsafeRawBufferPointer(buffer)
194+
let span = RawSpan(_unsafeBytes: rawBuffer)
195+
// As a trivial value, 'rawBuffer' does not formally depend on the
196+
// lifetime of 'buffer'. Make the dependence explicit.
197+
self = _overrideLifetime(span, borrowing: buffer)
179198
}
180199

181200
/// Unsafely create a `RawSpan` over initialized memory.
@@ -191,9 +210,11 @@ extension RawSpan {
191210
public init<T: BitwiseCopyable>(
192211
_unsafeElements buffer: borrowing Slice<UnsafeBufferPointer<T>>
193212
) {
194-
self.init(
195-
_unsafeBytes: .init(UnsafeBufferPointer(rebasing: buffer))
196-
)
213+
let rawBuffer = UnsafeRawBufferPointer(UnsafeBufferPointer(rebasing: buffer))
214+
let span = RawSpan(_unsafeBytes: rawBuffer)
215+
// As a trivial value, 'rawBuffer' does not formally depend on the
216+
// lifetime of 'buffer'. Make the dependence explicit.
217+
self = _overrideLifetime(span, borrowing: buffer)
197218
}
198219

199220
/// Unsafely create a `RawSpan` over initialized memory.
@@ -209,7 +230,11 @@ extension RawSpan {
209230
public init<T: BitwiseCopyable>(
210231
_unsafeElements buffer: UnsafeMutableBufferPointer<T>
211232
) {
212-
self.init(_unsafeElements: UnsafeBufferPointer(buffer))
233+
let rawBuffer = UnsafeRawBufferPointer(buffer)
234+
let span = RawSpan(_unsafeBytes: rawBuffer)
235+
// As a trivial value, 'rawBuffer' does not formally depend on the
236+
// lifetime of 'buffer'. Make the dependence explicit.
237+
self = _overrideLifetime(span, borrowing: buffer)
213238
}
214239

215240
/// Unsafely create a `RawSpan` over initialized memory.
@@ -225,9 +250,12 @@ extension RawSpan {
225250
public init<T: BitwiseCopyable>(
226251
_unsafeElements buffer: borrowing Slice<UnsafeMutableBufferPointer<T>>
227252
) {
228-
self.init(
229-
_unsafeBytes: .init(UnsafeBufferPointer(rebasing: buffer))
230-
)
253+
let rawBuffer =
254+
UnsafeRawBufferPointer(UnsafeMutableBufferPointer(rebasing: buffer))
255+
let span = RawSpan(_unsafeBytes: rawBuffer)
256+
// As a trivial value, 'rawBuffer' does not formally depend on the
257+
// lifetime of 'buffer'. Make the dependence explicit.
258+
self = _overrideLifetime(span, borrowing: buffer)
231259
}
232260

233261
/// Unsafely create a `RawSpan` over initialized memory.
@@ -344,10 +372,9 @@ extension RawSpan {
344372
@_alwaysEmitIntoClient
345373
@lifetime(self)
346374
public func _extracting(unchecked bounds: Range<Int>) -> Self {
347-
RawSpan(
348-
_unchecked: _pointer?.advanced(by: bounds.lowerBound),
349-
byteCount: bounds.count
350-
)
375+
let newStart = _pointer?.advanced(by: bounds.lowerBound)
376+
let newSpan = RawSpan(_unchecked: newStart, byteCount: bounds.count)
377+
return _overrideLifetime(newSpan, copying: self)
351378
}
352379

353380
/// Constructs a new span over the bytes within the supplied range of
@@ -457,7 +484,11 @@ extension RawSpan {
457484
consuming public func _unsafeView<T: BitwiseCopyable>(
458485
as type: T.Type
459486
) -> Span<T> {
460-
Span(_unsafeBytes: .init(start: _pointer, count: _count))
487+
let rawBuffer = UnsafeRawBufferPointer(start: _pointer, count: _count)
488+
let newSpan = Span<T>(_unsafeBytes: rawBuffer)
489+
// As a trivial value, 'rawBuffer' does not formally depend on the
490+
// lifetime of 'self'. Make the dependence explicit.
491+
return _overrideLifetime(newSpan, copying: self)
461492
}
462493
}
463494

@@ -677,7 +708,10 @@ extension RawSpan {
677708
_precondition(maxLength >= 0, "Can't have a suffix of negative length")
678709
let newCount = min(maxLength, byteCount)
679710
let newStart = _pointer?.advanced(by: byteCount &- newCount)
680-
return Self(_unchecked: newStart, byteCount: newCount)
711+
let newSpan = RawSpan(_unchecked: newStart, byteCount: newCount)
712+
// As a trivial value, 'newStart' does not formally depend on the
713+
// lifetime of 'self'. Make the dependence explicit.
714+
return _overrideLifetime(newSpan, copying: self)
681715
}
682716

683717
/// Returns a span over all but the given number of initial bytes.
@@ -700,6 +734,9 @@ extension RawSpan {
700734
_precondition(k >= 0, "Can't drop a negative number of elements")
701735
let droppedCount = min(k, byteCount)
702736
let newStart = _pointer?.advanced(by: droppedCount)
703-
return Self(_unchecked: newStart, byteCount: byteCount &- droppedCount)
737+
let newSpan = RawSpan(_unchecked: newStart, byteCount: byteCount &- droppedCount)
738+
// As a trivial value, 'newStart' does not formally depend on the
739+
// lifetime of 'self'. Make the dependence explicit.
740+
return _overrideLifetime(newSpan, copying: self)
704741
}
705742
}

stdlib/public/core/Span/Span.swift

+68-17
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,16 @@ extension Span where Element: ~Copyable {
100100
_unsafeElements buffer: UnsafeBufferPointer<Element>
101101
) {
102102
//FIXME: Workaround for https://github.com/swiftlang/swift/issues/77235
103-
let baseAddress = buffer.baseAddress
103+
let baseAddress = UnsafeRawPointer(buffer.baseAddress)
104104
_precondition(
105105
((Int(bitPattern: baseAddress) &
106106
(MemoryLayout<Element>.alignment &- 1)) == 0),
107107
"baseAddress must be properly aligned to access Element"
108108
)
109-
self.init(_unchecked: baseAddress, count: buffer.count)
109+
let span = Span(_unchecked: baseAddress, count: buffer.count)
110+
// As a trivial value, 'baseAddress' does not formally depend on the
111+
// lifetime of 'buffer'. Make the dependence explicit.
112+
self = _overrideLifetime(span, borrowing: buffer)
110113
}
111114

112115
/// Unsafely create a `Span` over initialized memory.
@@ -122,7 +125,11 @@ extension Span where Element: ~Copyable {
122125
public init(
123126
_unsafeElements buffer: UnsafeMutableBufferPointer<Element>
124127
) {
125-
self.init(_unsafeElements: UnsafeBufferPointer(buffer))
128+
let buf = UnsafeBufferPointer(buffer)
129+
let span = Span(_unsafeElements: buf)
130+
// As a trivial value, 'buf' does not formally depend on the
131+
// lifetime of 'buffer'. Make the dependence explicit.
132+
self = _overrideLifetime(span, borrowing: buffer)
126133
}
127134

128135
/// Unsafely create a `Span` over initialized memory.
@@ -142,7 +149,11 @@ extension Span where Element: ~Copyable {
142149
count: Int
143150
) {
144151
_precondition(count >= 0, "Count must not be negative")
145-
self.init(_unsafeElements: .init(start: pointer, count: count))
152+
let buf = UnsafeBufferPointer(start: pointer, count: count)
153+
let span = Span(_unsafeElements: buf)
154+
// As a trivial value, 'buf' does not formally depend on the
155+
// lifetime of 'pointer'. Make the dependence explicit.
156+
self = _overrideLifetime(span, borrowing: pointer)
146157
}
147158
}
148159

@@ -162,7 +173,11 @@ extension Span {
162173
public init(
163174
_unsafeElements buffer: borrowing Slice<UnsafeBufferPointer<Element>>
164175
) {
165-
self.init(_unsafeElements: UnsafeBufferPointer(rebasing: buffer))
176+
let buf = UnsafeBufferPointer(rebasing: buffer)
177+
let span = Span(_unsafeElements: buf)
178+
// As a trivial value, 'buf' does not formally depend on the
179+
// lifetime of 'buffer'. Make the dependence explicit.
180+
self = _overrideLifetime(span, borrowing: buffer)
166181
}
167182

168183
/// Unsafely create a `Span` over initialized memory.
@@ -178,7 +193,11 @@ extension Span {
178193
public init(
179194
_unsafeElements buffer: borrowing Slice<UnsafeMutableBufferPointer<Element>>
180195
) {
181-
self.init(_unsafeElements: UnsafeBufferPointer(rebasing: buffer))
196+
let buf = UnsafeBufferPointer(rebasing: buffer)
197+
let span = Span(_unsafeElements: buf)
198+
// As a trivial value, 'buf' does not formally depend on the
199+
// lifetime of 'buffer'. Make the dependence explicit.
200+
self = _overrideLifetime(span, borrowing: buffer)
182201
}
183202
}
184203

@@ -214,7 +233,10 @@ extension Span where Element: BitwiseCopyable {
214233
_precondition(
215234
remainder == 0, "Span must contain a whole number of elements"
216235
)
217-
self.init(_unchecked: baseAddress, count: count)
236+
let span = Span(_unchecked: baseAddress, count: count)
237+
// As a trivial value, 'baseAddress' does not formally depend on the
238+
// lifetime of 'buffer'. Make the dependence explicit.
239+
self = _overrideLifetime(span, borrowing: buffer)
218240
}
219241

220242
/// Unsafely create a `Span` over initialized memory.
@@ -234,7 +256,11 @@ extension Span where Element: BitwiseCopyable {
234256
public init(
235257
_unsafeBytes buffer: UnsafeMutableRawBufferPointer
236258
) {
237-
self.init(_unsafeBytes: UnsafeRawBufferPointer(buffer))
259+
let rawBuffer = UnsafeRawBufferPointer(buffer)
260+
let span = Span(_unsafeBytes: rawBuffer)
261+
// As a trivial value, 'buf' does not formally depend on the
262+
// lifetime of 'buffer'. Make the dependence explicit.
263+
self = _overrideLifetime(span, borrowing: buffer)
238264
}
239265

240266
/// Unsafely create a `Span` over initialized memory.
@@ -258,7 +284,11 @@ extension Span where Element: BitwiseCopyable {
258284
byteCount: Int
259285
) {
260286
_precondition(byteCount >= 0, "Count must not be negative")
261-
self.init(_unsafeBytes: .init(start: pointer, count: byteCount))
287+
let rawBuffer = UnsafeRawBufferPointer(start: pointer, count: byteCount)
288+
let span = Span(_unsafeBytes: rawBuffer)
289+
// As a trivial value, 'rawBuffer' does not formally depend on the
290+
// lifetime of 'pointer'. Make the dependence explicit.
291+
self = _overrideLifetime(span, borrowing: pointer)
262292
}
263293

264294
/// Unsafely create a `Span` over initialized memory.
@@ -278,7 +308,11 @@ extension Span where Element: BitwiseCopyable {
278308
public init(
279309
_unsafeBytes buffer: borrowing Slice<UnsafeRawBufferPointer>
280310
) {
281-
self.init(_unsafeBytes: UnsafeRawBufferPointer(rebasing: buffer))
311+
let rawBuffer = UnsafeRawBufferPointer(rebasing: buffer)
312+
let span = Span(_unsafeBytes: rawBuffer)
313+
// As a trivial value, 'rawBuffer' does not formally depend on the
314+
// lifetime of 'buffer'. Make the dependence explicit.
315+
self = _overrideLifetime(span, borrowing: buffer)
282316
}
283317

284318
/// Unsafely create a `Span` over initialized memory.
@@ -298,7 +332,11 @@ extension Span where Element: BitwiseCopyable {
298332
public init(
299333
_unsafeBytes buffer: borrowing Slice<UnsafeMutableRawBufferPointer>
300334
) {
301-
self.init(_unsafeBytes: UnsafeRawBufferPointer(rebasing: buffer))
335+
let rawBuffer = UnsafeRawBufferPointer(rebasing: buffer)
336+
let span = Span(_unsafeBytes: rawBuffer)
337+
// As a trivial value, 'rawBuffer' does not formally depend on the
338+
// lifetime of 'buffer'. Make the dependence explicit.
339+
self = _overrideLifetime(span, borrowing: buffer)
302340
}
303341

304342
/// Create a `Span` over the bytes represented by a `RawSpan`
@@ -309,9 +347,12 @@ extension Span where Element: BitwiseCopyable {
309347
@_alwaysEmitIntoClient
310348
@lifetime(bytes)
311349
public init(_bytes bytes: consuming RawSpan) {
312-
self.init(
313-
_unsafeBytes: .init(start: bytes._pointer, count: bytes.byteCount)
314-
)
350+
let rawBuffer =
351+
UnsafeRawBufferPointer(start: bytes._pointer, count: bytes.byteCount)
352+
let span = Span(_unsafeBytes: rawBuffer)
353+
// As a trivial value, 'rawBuffer' does not formally depend on the
354+
// lifetime of 'bytes'. Make the dependence explicit.
355+
self = _overrideLifetime(span, copying: bytes)
315356
}
316357
}
317358

@@ -481,7 +522,11 @@ extension Span where Element: ~Copyable {
481522
@lifetime(self)
482523
public func _extracting(unchecked bounds: Range<Index>) -> Self {
483524
let delta = bounds.lowerBound &* MemoryLayout<Element>.stride
484-
return Span(_unchecked: _pointer?.advanced(by: delta), count: bounds.count)
525+
let newStart = _pointer?.advanced(by: delta)
526+
let newSpan = Span(_unchecked: newStart, count: bounds.count)
527+
// As a trivial value, 'newStart' does not formally depend on the
528+
// lifetime of 'self'. Make the dependence explicit.
529+
return _overrideLifetime(newSpan, copying: self)
485530
}
486531

487532
/// Constructs a new span over the items within the supplied range of
@@ -704,7 +749,10 @@ extension Span where Element: ~Copyable {
704749
let newCount = min(maxLength, count)
705750
let offset = (count &- newCount) * MemoryLayout<Element>.stride
706751
let newStart = _pointer?.advanced(by: offset)
707-
return Self(_unchecked: newStart, count: newCount)
752+
let newSpan = Span(_unchecked: newStart, count: newCount)
753+
// As a trivial value, 'newStart' does not formally depend on the
754+
// lifetime of 'buffer'. Make the dependence explicit.
755+
return _overrideLifetime(newSpan, copying: self)
708756
}
709757

710758
/// Returns a span over all but the given number of initial elements.
@@ -728,6 +776,9 @@ extension Span where Element: ~Copyable {
728776
let droppedCount = min(k, count)
729777
let offset = droppedCount * MemoryLayout<Element>.stride
730778
let newStart = _pointer?.advanced(by: offset)
731-
return Self(_unchecked: newStart, count: count &- droppedCount)
779+
let newSpan = Span(_unchecked: newStart, count: count &- droppedCount)
780+
// As a trivial value, 'newStart' does not formally depend on the
781+
// lifetime of 'buffer'. Make the dependence explicit.
782+
return _overrideLifetime(newSpan, copying: self)
732783
}
733784
}

0 commit comments

Comments
 (0)