Skip to content

Commit 66adb21

Browse files
committed
[stdlib] annotate Span and RawSpan unsafe initializers
1 parent bd32aa5 commit 66adb21

File tree

2 files changed

+61
-36
lines changed

2 files changed

+61
-36
lines changed

stdlib/public/core/Span/RawSpan.swift

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public struct RawSpan: ~Escapable, Copyable, BitwiseCopyable {
4646
internal let _count: Int
4747

4848
/// FIXME: Remove once supported old compilers can recognize lifetime dependence
49+
@unsafe
4950
@_unsafeNonescapableResult
5051
@_alwaysEmitIntoClient
5152
@inline(__always)
@@ -67,6 +68,7 @@ public struct RawSpan: ~Escapable, Copyable, BitwiseCopyable {
6768
/// - Parameters:
6869
/// - pointer: a pointer to the first initialized byte.
6970
/// - byteCount: the number of initialized bytes in the span.
71+
@unsafe
7072
@_alwaysEmitIntoClient
7173
@inline(__always)
7274
@lifetime(borrow pointer)
@@ -93,13 +95,14 @@ extension RawSpan {
9395
///
9496
/// - Parameters:
9597
/// - buffer: an `UnsafeRawBufferPointer` to initialized memory.
98+
@unsafe
9699
@_alwaysEmitIntoClient
97100
@lifetime(borrow buffer)
98101
public init(
99102
_unsafeBytes buffer: UnsafeRawBufferPointer
100103
) {
101104
let baseAddress = buffer.baseAddress
102-
let span = RawSpan(_unchecked: baseAddress, byteCount: buffer.count)
105+
let span = unsafe RawSpan(_unchecked: baseAddress, byteCount: buffer.count)
103106
// As a trivial value, 'baseAddress' does not formally depend on the
104107
// lifetime of 'buffer'. Make the dependence explicit.
105108
self = unsafe _overrideLifetime(span, borrowing: buffer)
@@ -113,13 +116,14 @@ extension RawSpan {
113116
///
114117
/// - Parameters:
115118
/// - buffer: an `UnsafeRawBufferPointer` to initialized memory.
119+
@unsafe
116120
@_alwaysEmitIntoClient
117121
@lifetime(borrow buffer)
118122
public init(
119123
_unsafeBytes buffer: borrowing Slice<UnsafeRawBufferPointer>
120124
) {
121125
let rawBuffer = unsafe UnsafeRawBufferPointer(rebasing: buffer)
122-
let span = RawSpan(_unsafeBytes: rawBuffer)
126+
let span = unsafe RawSpan(_unsafeBytes: rawBuffer)
123127
// As a trivial value, 'rawBuffer' does not formally depend on the
124128
// lifetime of 'buffer'. Make the dependence explicit.
125129
self = unsafe _overrideLifetime(span, borrowing: buffer)
@@ -133,18 +137,28 @@ extension RawSpan {
133137
///
134138
/// - Parameters:
135139
/// - buffer: an `UnsafeRawBufferPointer` to initialized memory.
140+
@unsafe
136141
@_alwaysEmitIntoClient
137142
@lifetime(borrow buffer)
138143
public init(
139144
_unsafeBytes buffer: UnsafeMutableRawBufferPointer
140145
) {
141146
let rawBuffer = UnsafeRawBufferPointer(buffer)
142-
let span = RawSpan(_unsafeBytes: rawBuffer)
147+
let span = unsafe RawSpan(_unsafeBytes: rawBuffer)
143148
// As a trivial value, 'rawBuffer' does not formally depend on the
144149
// lifetime of 'buffer'. Make the dependence explicit.
145150
self = unsafe _overrideLifetime(span, borrowing: buffer)
146151
}
147152

153+
/// Unsafely create a `RawSpan` over initialized memory.
154+
///
155+
/// The memory in `buffer` must remain valid, initialized and immutable
156+
/// throughout the lifetime of the newly-created `RawSpan`.
157+
/// Failure to maintain this invariant results in undefined behaviour.
158+
///
159+
/// - Parameters:
160+
/// - buffer: an `UnsafeRawBufferPointer` to initialized memory.
161+
@unsafe
148162
@_alwaysEmitIntoClient
149163
@lifetime(borrow buffer)
150164
public init(
@@ -153,7 +167,7 @@ extension RawSpan {
153167
let rawBuffer = UnsafeRawBufferPointer(
154168
unsafe UnsafeMutableRawBufferPointer(rebasing: buffer)
155169
)
156-
let span = RawSpan(_unsafeBytes: rawBuffer)
170+
let span = unsafe RawSpan(_unsafeBytes: rawBuffer)
157171
// As a trivial value, 'rawBuffer' does not formally depend on the
158172
// lifetime of 'buffer'. Make the dependence explicit.
159173
self = unsafe _overrideLifetime(span, borrowing: buffer)
@@ -169,14 +183,15 @@ extension RawSpan {
169183
/// - Parameters:
170184
/// - pointer: a pointer to the first initialized byte.
171185
/// - byteCount: the number of initialized bytes in the span.
186+
@unsafe
172187
@_alwaysEmitIntoClient
173188
@lifetime(borrow pointer)
174189
public init(
175190
_unsafeStart pointer: UnsafeRawPointer,
176191
byteCount: Int
177192
) {
178193
_precondition(byteCount >= 0, "Count must not be negative")
179-
self.init(_unchecked: pointer, byteCount: byteCount)
194+
unsafe self.init(_unchecked: pointer, byteCount: byteCount)
180195
}
181196

182197
/// Unsafely create a `RawSpan` over initialized memory.
@@ -187,13 +202,14 @@ extension RawSpan {
187202
///
188203
/// - Parameters:
189204
/// - buffer: an `UnsafeRawBufferPointer` to initialized memory.
205+
@unsafe
190206
@_alwaysEmitIntoClient
191207
@lifetime(borrow buffer)
192208
public init<T: BitwiseCopyable>(
193209
_unsafeElements buffer: UnsafeBufferPointer<T>
194210
) {
195211
let rawBuffer = UnsafeRawBufferPointer(buffer)
196-
let span = RawSpan(_unsafeBytes: rawBuffer)
212+
let span = unsafe RawSpan(_unsafeBytes: rawBuffer)
197213
// As a trivial value, 'rawBuffer' does not formally depend on the
198214
// lifetime of 'buffer'. Make the dependence explicit.
199215
self = unsafe _overrideLifetime(span, borrowing: buffer)
@@ -207,13 +223,14 @@ extension RawSpan {
207223
///
208224
/// - Parameters:
209225
/// - buffer: an `UnsafeRawBufferPointer` to initialized memory.
226+
@unsafe
210227
@_alwaysEmitIntoClient
211228
@lifetime(borrow buffer)
212229
public init<T: BitwiseCopyable>(
213230
_unsafeElements buffer: borrowing Slice<UnsafeBufferPointer<T>>
214231
) {
215232
let rawBuffer = UnsafeRawBufferPointer(unsafe .init(rebasing: buffer))
216-
let span = RawSpan(_unsafeBytes: rawBuffer)
233+
let span = unsafe RawSpan(_unsafeBytes: rawBuffer)
217234
// As a trivial value, 'rawBuffer' does not formally depend on the
218235
// lifetime of 'buffer'. Make the dependence explicit.
219236
self = unsafe _overrideLifetime(span, borrowing: buffer)
@@ -227,13 +244,14 @@ extension RawSpan {
227244
///
228245
/// - Parameters:
229246
/// - buffer: an `UnsafeRawBufferPointer` to initialized memory.
247+
@unsafe
230248
@_alwaysEmitIntoClient
231249
@lifetime(borrow buffer)
232250
public init<T: BitwiseCopyable>(
233251
_unsafeElements buffer: UnsafeMutableBufferPointer<T>
234252
) {
235253
let rawBuffer = UnsafeRawBufferPointer(buffer)
236-
let span = RawSpan(_unsafeBytes: rawBuffer)
254+
let span = unsafe RawSpan(_unsafeBytes: rawBuffer)
237255
// As a trivial value, 'rawBuffer' does not formally depend on the
238256
// lifetime of 'buffer'. Make the dependence explicit.
239257
self = unsafe _overrideLifetime(span, borrowing: buffer)
@@ -247,6 +265,7 @@ extension RawSpan {
247265
///
248266
/// - Parameters:
249267
/// - buffer: an `UnsafeRawBufferPointer` to initialized memory.
268+
@unsafe
250269
@_alwaysEmitIntoClient
251270
@lifetime(borrow buffer)
252271
public init<T: BitwiseCopyable>(
@@ -255,7 +274,7 @@ extension RawSpan {
255274
let rawBuffer = UnsafeRawBufferPointer(
256275
unsafe UnsafeMutableBufferPointer(rebasing: buffer)
257276
)
258-
let span = RawSpan(_unsafeBytes: rawBuffer)
277+
let span = unsafe RawSpan(_unsafeBytes: rawBuffer)
259278
// As a trivial value, 'rawBuffer' does not formally depend on the
260279
// lifetime of 'buffer'. Make the dependence explicit.
261280
self = unsafe _overrideLifetime(span, borrowing: buffer)
@@ -271,14 +290,15 @@ extension RawSpan {
271290
/// - Parameters:
272291
/// - pointer: a pointer to the first initialized byte.
273292
/// - byteCount: the number of initialized bytes in the span.
293+
@unsafe
274294
@_alwaysEmitIntoClient
275295
@lifetime(borrow pointer)
276296
public init<T: BitwiseCopyable>(
277297
_unsafeStart pointer: UnsafePointer<T>,
278298
count: Int
279299
) {
280300
_precondition(count >= 0, "Count must not be negative")
281-
self.init(
301+
unsafe self.init(
282302
_unchecked: pointer, byteCount: count * MemoryLayout<T>.stride
283303
)
284304
}
@@ -293,7 +313,7 @@ extension RawSpan {
293313
public init<Element: BitwiseCopyable>(
294314
_elements span: borrowing Span<Element>
295315
) {
296-
self.init(
316+
unsafe self.init(
297317
_unchecked: span._pointer,
298318
byteCount: span.count &* MemoryLayout<Element>.stride
299319
)
@@ -376,7 +396,7 @@ extension RawSpan {
376396
@lifetime(self)
377397
public func _extracting(unchecked bounds: Range<Int>) -> Self {
378398
let newStart = unsafe _pointer?.advanced(by: bounds.lowerBound)
379-
let newSpan = RawSpan(_unchecked: newStart, byteCount: bounds.count)
399+
let newSpan = unsafe RawSpan(_unchecked: newStart, byteCount: bounds.count)
380400
return unsafe _overrideLifetime(newSpan, copying: self)
381401
}
382402

@@ -494,7 +514,7 @@ extension RawSpan {
494514
as type: T.Type
495515
) -> Span<T> {
496516
let rawBuffer = unsafe UnsafeRawBufferPointer(start: _pointer, count: _count)
497-
let newSpan = Span<T>(_unsafeBytes: rawBuffer)
517+
let newSpan = unsafe Span<T>(_unsafeBytes: rawBuffer)
498518
// As a trivial value, 'rawBuffer' does not formally depend on the
499519
// lifetime of 'self'. Make the dependence explicit.
500520
return unsafe _overrideLifetime(newSpan, copying: self)
@@ -673,7 +693,7 @@ extension RawSpan {
673693
public func _extracting(first maxLength: Int) -> Self {
674694
_precondition(maxLength >= 0, "Can't have a prefix of negative length")
675695
let newCount = min(maxLength, byteCount)
676-
return Self(_unchecked: _pointer, byteCount: newCount)
696+
return unsafe Self(_unchecked: _pointer, byteCount: newCount)
677697
}
678698

679699
/// Returns a span over all but the given number of trailing bytes.
@@ -695,7 +715,8 @@ extension RawSpan {
695715
public func _extracting(droppingLast k: Int) -> Self {
696716
_precondition(k >= 0, "Can't drop a negative number of bytes")
697717
let droppedCount = min(k, byteCount)
698-
return Self(_unchecked: _pointer, byteCount: byteCount &- droppedCount)
718+
let count = byteCount &- droppedCount
719+
return unsafe Self(_unchecked: _pointer, byteCount: count)
699720
}
700721

701722
/// Returns a span containing the trailing bytes of the span,
@@ -719,7 +740,7 @@ extension RawSpan {
719740
_precondition(maxLength >= 0, "Can't have a suffix of negative length")
720741
let newCount = min(maxLength, byteCount)
721742
let newStart = unsafe _pointer?.advanced(by: byteCount &- newCount)
722-
let newSpan = Self(_unchecked: newStart, byteCount: newCount)
743+
let newSpan = unsafe Self(_unchecked: newStart, byteCount: newCount)
723744
// As a trivial value, 'newStart' does not formally depend on the
724745
// lifetime of 'self'. Make the dependence explicit.
725746
return unsafe _overrideLifetime(newSpan, copying: self)
@@ -743,9 +764,10 @@ extension RawSpan {
743764
@lifetime(self)
744765
public func _extracting(droppingFirst k: Int) -> Self {
745766
_precondition(k >= 0, "Can't drop a negative number of bytes")
746-
let dropped = min(k, byteCount)
747-
let newStart = unsafe _pointer?.advanced(by: dropped)
748-
let newSpan = Self(_unchecked: newStart, byteCount: byteCount &- dropped)
767+
let droppedCount = min(k, byteCount)
768+
let newStart = unsafe _pointer?.advanced(by: droppedCount)
769+
let newCount = byteCount &- droppedCount
770+
let newSpan = unsafe Self(_unchecked: newStart, byteCount: newCount)
749771
// As a trivial value, 'newStart' does not formally depend on the
750772
// lifetime of 'self'. Make the dependence explicit.
751773
return unsafe _overrideLifetime(newSpan, copying: self)

0 commit comments

Comments
 (0)