You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: proposals/0458-strict-memory-safety.md
+37Lines changed: 37 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -411,6 +411,42 @@ func passUnsafe() {
411
411
}
412
412
```
413
413
414
+
### `for..in` loops
415
+
416
+
Swift's `for..in` loops are effectively implemented as syntactic sugar over the `Sequence` and `IteratorProtocol` protocols, where the `for..in` creates a new iterator (with `Sequence.makeIterator()`) and then calls its `next()` operation for each loop iteration. If the conformances to `Sequence` are `IteratorProtocol` is `@unsafe`, the loop will introduce a warning:
417
+
418
+
```swift
419
+
let someUnsafeBuffer: UnsafeBufferPointer<Element> = unsafe ...
420
+
for x in someBuffer { // warning: use of unsafe conformance of 'UnsafeBufferPointer' to 'Sequence'
421
+
// and someBuffer has unsafe type 'UnsafeBufferPointer'
422
+
// ...
423
+
}
424
+
```
425
+
426
+
Following the precedent set by [SE-0298](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0298-asyncsequence.md), which introduced effects in loops, the `unsafe` keyword that acknowledges unsafe behavior in the iteration will follow the `for`:
427
+
428
+
```swift
429
+
let someUnsafeBuffer: UnsafeBufferPointer<Element> = unsafe ...
430
+
for unsafe x in someBuffer { // still warns that someBuffer has unsafe type 'UnsafeBufferPointer'
431
+
// ...
432
+
}
433
+
```
434
+
435
+
This may not be the only unsafe behavior in the `for..in` loop. For example, the expression that produces the sequence itself (via the reference to `someBuffer`) is also unsafe, so it needs to be acknowledged:
436
+
437
+
```swift
438
+
let someUnsafeBuffer: UnsafeBufferPointer<Element> = unsafe ...
439
+
for unsafe x in unsafe someBuffer {
440
+
// ...
441
+
}
442
+
```
443
+
444
+
This repeated `unsafe` also occurs with the other effects: if an `async throws` function `getAsyncSequence()` produces an `AsyncSequence` whose iteration can throw, one will end up with two `try` and `await` keywords:
445
+
446
+
```swift
447
+
fortryawait x intryawaitgetAsyncSequence() { ... }
448
+
```
449
+
414
450
### Strict safety mode and escalatable warnings
415
451
416
452
The strict memory safety mode can be enabled with the new compiler flag `-strict-memory-safety`.
@@ -733,6 +769,7 @@ We could introduce an optional `message` argument to the `@unsafe` attribute, wh
733
769
734
770
***Revision 3 (following second review eextension)**
735
771
* Do not require declarations with unsafe types in their signature to be marked `@unsafe`; it is implied. They may be marked `@safe` to indicate that they are actually safe.
772
+
* Add `unsafe` for iteration via the `for..in` syntax.
736
773
737
774
***Revision 2 (following first review extension)**
738
775
* Specified that variables of unsafe type passed in to uses of `@safe` declarations (e.g., calls, property accesses) are not diagnosed as themselves being unsafe. This makes means that expressions like `unsafeBufferePointer.count` will be considered safe.
0 commit comments