Skip to content

Commit 48c0994

Browse files
committed
SE-0458: Move the @safe attribute into the section on acknowledging unsafety
1 parent 682c8ac commit 48c0994

File tree

1 file changed

+39
-39
lines changed

1 file changed

+39
-39
lines changed

proposals/0458-strict-memory-safety.md

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,45 @@ struct ListNode {
288288

289289
Note that C `enum`s will never be inferred to be `@unsafe` because they don't carry any values other than their underlying integral type, which is always a safe type.
290290

291-
### `@safe` attribute
291+
### Acknowledging unsafety
292+
293+
All of the features described above are available in Swift regardless of whether strict memory safety checking is enabled. When strict memory safety checking is enabled, each use of an unsafe construct of any form must be ackwnowledged in the source code with one of the forms below, which provides an in-source auditable indication of where memory unsafety issues can arise. The following section describes each of the features for acknowledging memory unsafety.
294+
295+
#### `unsafe` expression
296+
297+
Any time there is executable code that makes use of unsafe constructs, the compiler will produce a diagnostic that indicates the use of those unsafe constructs unless it is within an `unsafe` expression. For example, consider the `DataWrapper` example from an earlier section:
298+
299+
```swift
300+
public struct DataWrapper {
301+
var buffer: UnsafeBufferPointer<UInt8>
302+
}
303+
304+
extension DataWrapper {
305+
public func checksum() -> Int32 {
306+
crc32(0, buffer.baseAddress, buffer.count)
307+
}
308+
}
309+
```
310+
311+
The property `buffer` uses an unsafe type, `UnsafeBufferPointer`. When using that property in the implementation of `checksum`, the Swift compiler will produce a warning when strict memory safety checking is enabled:
312+
313+
```swift
314+
warning: expression uses unsafe constructs but is not marked with 'unsafe'
315+
```
316+
317+
This warning can be suppressed using the `unsafe` expression, as follows:
318+
319+
```swift
320+
extension DataWrapper {
321+
public func checksum() -> Int32 {
322+
unsafe crc32(0, buffer.baseAddress, buffer.count)
323+
}
324+
}
325+
```
326+
327+
The `unsafe` expression is much like `try` and `await`, in that it acknowledges that unsafe constructs (`buffer`) are used within the subexpression but otherwise does not change the type. Unlike `try` and `await`, which require the enclosing context to handle throwing or be asynchronous, respectively, the `unsafe` expression does not imply any requirements about the enclosing block: it is purely a marker to indicate the presence of unsafe code, silencing a diagnostic.
328+
329+
#### `@safe` attribute
292330

293331
The `@safe` attribute is used on declarations whose signatures involve unsafe types but are, nonetheless, safe to use. For example, marking `UnsafeBufferPointer` as `@unsafe` means that all operations involving an unsafe buffer pointer are implicitly considered `@unsafe`. The `@safe` attribute can be used to say that those certain operations are actually safe. For example, any operation involving buffer indices or count are safe, because they don't touch the memory itself. This can be indicated by marking these APIs `@safe`:
294332

@@ -336,44 +374,6 @@ extension Array<Int> {
336374
}
337375
```
338376

339-
### Acknowledging unsafety
340-
341-
All of the features described above are available in Swift regardless of whether strict memory safety checking is enabled. When strict memory safety checking is enabled, each use of an unsafe construct of any form must be ackwnowledged in the source code with one of the forms below, which provides an in-source auditable indication of where memory unsafety issues can arise. The following section describes each of the features for acknowledging memory unsafety.
342-
343-
#### `unsafe` expression
344-
345-
Any time there is executable code that makes use of unsafe constructs, the compiler will produce a diagnostic that indicates the use of those unsafe constructs unless it is within an `unsafe` expression. For example, consider the `DataWrapper` example from an earlier section:
346-
347-
```swift
348-
public struct DataWrapper {
349-
var buffer: UnsafeBufferPointer<UInt8>
350-
}
351-
352-
extension DataWrapper {
353-
public func checksum() -> Int32 {
354-
crc32(0, buffer.baseAddress, buffer.count)
355-
}
356-
}
357-
```
358-
359-
The property `buffer` uses an unsafe type, `UnsafeBufferPointer`. When using that property in the implementation of `checksum`, the Swift compiler will produce a warning when strict memory safety checking is enabled:
360-
361-
```swift
362-
warning: expression uses unsafe constructs but is not marked with 'unsafe'
363-
```
364-
365-
This warning can be suppressed using the `unsafe` expression, as follows:
366-
367-
```swift
368-
extension DataWrapper {
369-
public func checksum() -> Int32 {
370-
unsafe crc32(0, buffer.baseAddress, buffer.count)
371-
}
372-
}
373-
```
374-
375-
The `unsafe` expression is much like `try` and `await`, in that it acknowledges that unsafe constructs (`buffer`) are used within the subexpression but otherwise does not change the type. Unlike `try` and `await`, which require the enclosing context to handle throwing or be asynchronous, respectively, the `unsafe` expression does not imply any requirements about the enclosing block: it is purely a marker to indicate the presence of unsafe code, silencing a diagnostic.
376-
377377
#### Types with unsafe storage
378378

379379
Types that wrap unsafe types will often encapsulate the unsafe behavior to provide safe interfaces. However, this requires deliberate design and implementation, potentially involving adding specific preconditions. When strict safety checking is enabled, a type whose storage includes any unsafe types or conformances will be diagnosed as involving unsafe code. For example, the `DataWrapper` struct from the prior section

0 commit comments

Comments
 (0)