Skip to content

Commit 457eb4c

Browse files
committed
[Strict memory safety] Update standard library for nested safe/unsafe types
Use this to mark a few internal types @safe now that it works properly.
1 parent 53ca902 commit 457eb4c

18 files changed

+326
-315
lines changed

stdlib/public/core/Bitset.swift

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ extension _UnsafeBitset {
4545
_internalInvariant(element >= 0)
4646
// Note: We perform on UInts to get faster unsigned math (shifts).
4747
let element = UInt(bitPattern: element)
48-
let capacity = unsafe UInt(bitPattern: Word.capacity)
48+
let capacity = UInt(bitPattern: Word.capacity)
4949
return Int(bitPattern: element / capacity)
5050
}
5151

@@ -55,7 +55,7 @@ extension _UnsafeBitset {
5555
_internalInvariant(element >= 0)
5656
// Note: We perform on UInts to get faster unsigned math (masking).
5757
let element = UInt(bitPattern: element)
58-
let capacity = unsafe UInt(bitPattern: Word.capacity)
58+
let capacity = UInt(bitPattern: Word.capacity)
5959
return Int(bitPattern: element % capacity)
6060
}
6161

@@ -68,8 +68,8 @@ extension _UnsafeBitset {
6868
@inlinable
6969
@inline(__always)
7070
internal static func join(word: Int, bit: Int) -> Int {
71-
unsafe _internalInvariant(bit >= 0 && bit < Word.capacity)
72-
return unsafe word &* Word.capacity &+ bit
71+
_internalInvariant(bit >= 0 && bit < Word.capacity)
72+
return word &* Word.capacity &+ bit
7373
}
7474
}
7575

@@ -84,7 +84,7 @@ extension _UnsafeBitset {
8484
internal var capacity: Int {
8585
@inline(__always)
8686
get {
87-
return unsafe wordCount &* Word.capacity
87+
return wordCount &* Word.capacity
8888
}
8989
}
9090

@@ -199,7 +199,7 @@ extension _UnsafeBitset {
199199

200200
@inlinable
201201
internal init(_ value: UInt) {
202-
unsafe self.value = value
202+
self.value = value
203203
}
204204
}
205205
}
@@ -217,7 +217,7 @@ extension _UnsafeBitset.Word {
217217
@inline(__always)
218218
internal func uncheckedContains(_ bit: Int) -> Bool {
219219
_internalInvariant(bit >= 0 && bit < UInt.bitWidth)
220-
return unsafe value & (1 &<< bit) != 0
220+
return value & (1 &<< bit) != 0
221221
}
222222

223223
@inlinable
@@ -226,8 +226,8 @@ extension _UnsafeBitset.Word {
226226
internal mutating func uncheckedInsert(_ bit: Int) -> Bool {
227227
_internalInvariant(bit >= 0 && bit < UInt.bitWidth)
228228
let mask: UInt = 1 &<< bit
229-
let inserted = unsafe value & mask == 0
230-
unsafe value |= mask
229+
let inserted = value & mask == 0
230+
value |= mask
231231
return inserted
232232
}
233233

@@ -237,8 +237,8 @@ extension _UnsafeBitset.Word {
237237
internal mutating func uncheckedRemove(_ bit: Int) -> Bool {
238238
_internalInvariant(bit >= 0 && bit < UInt.bitWidth)
239239
let mask: UInt = 1 &<< bit
240-
let removed = unsafe value & mask != 0
241-
unsafe value &= ~mask
240+
let removed = value & mask != 0
241+
value &= ~mask
242242
return removed
243243
}
244244
}
@@ -248,50 +248,50 @@ extension _UnsafeBitset.Word {
248248
var minimum: Int? {
249249
@inline(__always)
250250
get {
251-
guard unsafe value != 0 else { return nil }
252-
return unsafe value.trailingZeroBitCount
251+
guard value != 0 else { return nil }
252+
return value.trailingZeroBitCount
253253
}
254254
}
255255

256256
@inlinable
257257
var maximum: Int? {
258258
@inline(__always)
259259
get {
260-
guard unsafe value != 0 else { return nil }
261-
return unsafe _UnsafeBitset.Word.capacity &- 1 &- value.leadingZeroBitCount
260+
guard value != 0 else { return nil }
261+
return _UnsafeBitset.Word.capacity &- 1 &- value.leadingZeroBitCount
262262
}
263263
}
264264

265265
@inlinable
266266
var complement: _UnsafeBitset.Word {
267267
@inline(__always)
268268
get {
269-
return unsafe _UnsafeBitset.Word(~value)
269+
return _UnsafeBitset.Word(~value)
270270
}
271271
}
272272

273273
@inlinable
274274
@inline(__always)
275275
internal func subtracting(elementsBelow bit: Int) -> _UnsafeBitset.Word {
276-
unsafe _internalInvariant(bit >= 0 && bit < _UnsafeBitset.Word.capacity)
276+
_internalInvariant(bit >= 0 && bit < _UnsafeBitset.Word.capacity)
277277
let mask = UInt.max &<< bit
278-
return unsafe _UnsafeBitset.Word(value & mask)
278+
return _UnsafeBitset.Word(value & mask)
279279
}
280280

281281
@inlinable
282282
@inline(__always)
283283
internal func intersecting(elementsBelow bit: Int) -> _UnsafeBitset.Word {
284-
unsafe _internalInvariant(bit >= 0 && bit < _UnsafeBitset.Word.capacity)
284+
_internalInvariant(bit >= 0 && bit < _UnsafeBitset.Word.capacity)
285285
let mask: UInt = (1 as UInt &<< bit) &- 1
286-
return unsafe _UnsafeBitset.Word(value & mask)
286+
return _UnsafeBitset.Word(value & mask)
287287
}
288288

289289
@inlinable
290290
@inline(__always)
291291
internal func intersecting(elementsAbove bit: Int) -> _UnsafeBitset.Word {
292-
unsafe _internalInvariant(bit >= 0 && bit < _UnsafeBitset.Word.capacity)
292+
_internalInvariant(bit >= 0 && bit < _UnsafeBitset.Word.capacity)
293293
let mask = (UInt.max &<< bit) &<< 1
294-
return unsafe _UnsafeBitset.Word(value & mask)
294+
return _UnsafeBitset.Word(value & mask)
295295
}
296296
}
297297

@@ -300,15 +300,15 @@ extension _UnsafeBitset.Word {
300300
internal static var empty: _UnsafeBitset.Word {
301301
@inline(__always)
302302
get {
303-
return unsafe _UnsafeBitset.Word(0)
303+
return _UnsafeBitset.Word(0)
304304
}
305305
}
306306

307307
@inlinable
308308
internal static var allBits: _UnsafeBitset.Word {
309309
@inline(__always)
310310
get {
311-
return unsafe _UnsafeBitset.Word(UInt.max)
311+
return _UnsafeBitset.Word(UInt.max)
312312
}
313313
}
314314
}
@@ -324,29 +324,29 @@ extension _UnsafeBitset.Word: @unsafe Sequence, @unsafe IteratorProtocol {
324324

325325
@inlinable
326326
internal var count: Int {
327-
return unsafe value.nonzeroBitCount
327+
return value.nonzeroBitCount
328328
}
329329

330330
@inlinable
331331
internal var underestimatedCount: Int {
332-
return unsafe count
332+
return count
333333
}
334334

335335
@inlinable
336336
internal var isEmpty: Bool {
337337
@inline(__always)
338338
get {
339-
return unsafe value == 0
339+
return value == 0
340340
}
341341
}
342342

343343
/// Return the index of the lowest set bit in this word,
344344
/// and also destructively clear it.
345345
@inlinable
346346
internal mutating func next() -> Int? {
347-
guard unsafe value != 0 else { return nil }
348-
let bit = unsafe value.trailingZeroBitCount
349-
unsafe value &= value &- 1 // Clear lowest nonzero bit.
347+
guard value != 0 else { return nil }
348+
let bit = value.trailingZeroBitCount
349+
value &= value &- 1 // Clear lowest nonzero bit.
350350
return bit
351351
}
352352
}

stdlib/public/core/ContiguouslyStored.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ extension Array: _HasContiguousBytes {
4242
}
4343
}
4444
extension ContiguousArray: _HasContiguousBytes {}
45-
extension UnsafeBufferPointer: _HasContiguousBytes {
45+
extension UnsafeBufferPointer: @unsafe _HasContiguousBytes {
4646
@inlinable @inline(__always)
4747
@safe
4848
func withUnsafeBytes<R>(
@@ -53,7 +53,7 @@ extension UnsafeBufferPointer: _HasContiguousBytes {
5353
return try unsafe body(UnsafeRawBufferPointer(start: ptr, count: len))
5454
}
5555
}
56-
extension UnsafeMutableBufferPointer: _HasContiguousBytes {
56+
extension UnsafeMutableBufferPointer: @unsafe _HasContiguousBytes {
5757
@inlinable @inline(__always)
5858
@safe
5959
func withUnsafeBytes<R>(
@@ -64,7 +64,7 @@ extension UnsafeMutableBufferPointer: _HasContiguousBytes {
6464
return try unsafe body(UnsafeRawBufferPointer(start: ptr, count: len))
6565
}
6666
}
67-
extension UnsafeRawBufferPointer: _HasContiguousBytes {
67+
extension UnsafeRawBufferPointer: @unsafe _HasContiguousBytes {
6868
@inlinable @inline(__always)
6969
@safe
7070
func withUnsafeBytes<R>(
@@ -73,7 +73,7 @@ extension UnsafeRawBufferPointer: _HasContiguousBytes {
7373
return try unsafe body(self)
7474
}
7575
}
76-
extension UnsafeMutableRawBufferPointer: _HasContiguousBytes {
76+
extension UnsafeMutableRawBufferPointer: @unsafe _HasContiguousBytes {
7777
@inlinable @inline(__always)
7878
@safe
7979
func withUnsafeBytes<R>(

stdlib/public/core/Dictionary.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ extension Dictionary: ExpressibleByDictionaryLiteral {
838838
for (key, value) in elements {
839839
let (bucket, found) = native.find(key)
840840
_precondition(!found, "Dictionary literal contains duplicate keys")
841-
unsafe native._insert(at: bucket, key: key, value: value)
841+
native._insert(at: bucket, key: key, value: value)
842842
}
843843
self.init(_native: native)
844844
}
@@ -904,11 +904,11 @@ extension Dictionary {
904904
}
905905
@inline(__always)
906906
_modify {
907-
let (bucket, found) = unsafe _variant.mutatingFind(key)
907+
let (bucket, found) = _variant.mutatingFind(key)
908908
let native = _variant.asNative
909909
if !found {
910910
let value = defaultValue()
911-
unsafe native._insert(at: bucket, key: key, value: value)
911+
native._insert(at: bucket, key: key, value: value)
912912
}
913913
let address = unsafe native._values + bucket.offset
914914
defer { _fixLifetime(self) }
@@ -1458,7 +1458,7 @@ extension Dictionary {
14581458
}
14591459
_modify {
14601460
let native = _variant.ensureUniqueNative()
1461-
let bucket = unsafe native.validatedBucket(for: position)
1461+
let bucket = native.validatedBucket(for: position)
14621462
let address = unsafe native._values + bucket.offset
14631463
defer { _fixLifetime(self) }
14641464
yield unsafe &address.pointee
@@ -1491,9 +1491,9 @@ extension Dictionary {
14911491
#endif
14921492
let isUnique = _variant.isUniquelyReferenced()
14931493
let native = _variant.asNative
1494-
let a = unsafe native.validatedBucket(for: i)
1495-
let b = unsafe native.validatedBucket(for: j)
1496-
unsafe _variant.asNative.swapValuesAt(a, b, isUnique: isUnique)
1494+
let a = native.validatedBucket(for: i)
1495+
let b = native.validatedBucket(for: j)
1496+
_variant.asNative.swapValuesAt(a, b, isUnique: isUnique)
14971497
}
14981498
}
14991499
}

stdlib/public/core/DictionaryBridging.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,12 @@ final internal class _SwiftDictionaryNSEnumerator<Key: Hashable, Value>
9898

9999
@objc
100100
internal func nextObject() -> AnyObject? {
101-
if unsafe nextBucket == endBucket {
101+
if nextBucket == endBucket {
102102
return nil
103103
}
104-
let bucket = unsafe nextBucket
104+
let bucket = nextBucket
105105
unsafe nextBucket = base.hashTable.occupiedBucket(after: nextBucket)
106-
return unsafe self.bridgedKey(at: bucket)
106+
return self.bridgedKey(at: bucket)
107107
}
108108

109109
@objc(countByEnumeratingWithState:objects:count:)
@@ -119,7 +119,7 @@ final internal class _SwiftDictionaryNSEnumerator<Key: Hashable, Value>
119119
unsafe theState.mutationsPtr = _fastEnumerationStorageMutationsPtr
120120
}
121121

122-
if unsafe nextBucket == endBucket {
122+
if nextBucket == endBucket {
123123
unsafe state.pointee = theState
124124
return 0
125125
}
@@ -411,7 +411,7 @@ final internal class _SwiftDeferredNSDictionary<Key: Hashable, Value>
411411
// Only need to bridge once, so we can hoist it out of the loop.
412412
let bridgedKeys = unsafe bridgeKeys()
413413
for i in 0..<count {
414-
if unsafe bucket == endBucket { break }
414+
if bucket == endBucket { break }
415415

416416
unsafe unmanagedObjects[i] = unsafe _key(at: bucket, bridgedKeys: bridgedKeys)
417417
stored += 1

stdlib/public/core/DictionaryBuilder.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -136,47 +136,47 @@ extension _NativeDictionary {
136136
// Each iteration of the loop below processes an unprocessed element, and/or
137137
// reduces the size of the unprocessed region, while ensuring the above
138138
// invariants.
139-
var bucket = unsafe _HashTable.Bucket(offset: initializedCount - 1)
140-
while unsafe bucket.offset >= 0 {
139+
var bucket = _HashTable.Bucket(offset: initializedCount - 1)
140+
while bucket.offset >= 0 {
141141
if unsafe hashTable._isOccupied(bucket) {
142142
// We've moved an element here in a previous iteration.
143-
unsafe bucket.offset -= 1
143+
bucket.offset -= 1
144144
continue
145145
}
146146
// Find the target bucket for this entry and mark it as in use.
147147
let target: Bucket
148148
if _isDebugAssertConfiguration() || allowingDuplicates {
149149
let (b, found) = unsafe find(_keys[bucket.offset])
150150
if found {
151-
unsafe _internalInvariant(b != bucket)
151+
_internalInvariant(b != bucket)
152152
_precondition(allowingDuplicates, "Duplicate keys found")
153153
// Discard duplicate entry.
154154
unsafe uncheckedDestroy(at: bucket)
155155
unsafe _storage._count -= 1
156-
unsafe bucket.offset -= 1
156+
bucket.offset -= 1
157157
continue
158158
}
159159
unsafe hashTable.insert(b)
160-
unsafe target = unsafe b
160+
target = b
161161
} else {
162162
let hashValue = unsafe self.hashValue(for: _keys[bucket.offset])
163163
unsafe target = unsafe hashTable.insertNew(hashValue: hashValue)
164164
}
165165

166-
if unsafe target > bucket {
166+
if target > bucket {
167167
// The target is outside the unprocessed region. We can simply move the
168168
// entry, leaving behind an uninitialized bucket.
169-
unsafe moveEntry(from: bucket, to: target)
169+
moveEntry(from: bucket, to: target)
170170
// Restore invariants by lowering the region boundary.
171-
unsafe bucket.offset -= 1
172-
} else if unsafe target == bucket {
171+
bucket.offset -= 1
172+
} else if target == bucket {
173173
// Already in place.
174-
unsafe bucket.offset -= 1
174+
bucket.offset -= 1
175175
} else {
176176
// The target bucket is also in the unprocessed region. Swap the current
177177
// item into place, then try again with the swapped-in value, so that we
178178
// don't lose it.
179-
unsafe swapEntry(target, with: bucket)
179+
swapEntry(target, with: bucket)
180180
}
181181
}
182182
// When there are no more unprocessed entries, we're left with a valid

0 commit comments

Comments
 (0)