Hello!
Following the discussion of the prospective vision for opt-in strict memory safety checking, here's a proposal that introduces the @unsafe and @safe(unchecked) attributes and strict memory safety checking mode.
Here's a quick summary from the proposal of how we expect it to work for users:
The UnsafeBufferPointer type will be marked with @unsafe in the Standard library, as will the other unsafe types (e.g., UnsafePointer, UnsafeRawPointer):
@unsafe
public struct UnsafeBufferPointer<Element> { ... }
This indicates that use of this type is not memory-safe. Any declaration that has UnsafeBufferPointer as part of its type is also unsafe, and would produce a warning under this strict safety mode, e.g.,
extension Array {
// warning on next line: reference to unsafe generic struct 'UnsafeBufferPointer'
func withUnsafeBufferPointerSimplified<T>(_ body: (UnsafeBufferPointer<Element>) -> T) -> T {
// ...
}
}
This warning can be suppressed by marking the function as @unsafe:
extension Array {
@unsafe
func withUnsafeBufferPointerSimplified<T>(_ body: (UnsafeBufferPointer<Element>) -> T) -> T {
// ...
}
}
Users of this function that also enable strict safety checking will see warnings when using it. For example:
extension Array<Int> {
func sum() -> Int {
// warning: use of unsafe function 'withUnsafeBufferPointerSimplified'
withUnsafeBufferPointerSimplified { buffer in
c_library_sum_function(buffer.baseAddress, buffer.count, 0)
}
}
}
Both the call to withUnsafeBufferPointerSimplified (which is @unsafe) and the call to c_library_sum_function (which has a parameter of @unsafe type UnsafePointer) would trigger warnings about uses of unsafe constructs. The author of sum has a choice to suppress the warnings:
- Mark the
sumfunction as@unsafe, propagating the "unsafe" checking out to callers ofsum; or - Mark the
sumfunction as@safe(unchecked), taking responsibility for the safety of the code within the body. Here, one needs to verify that theUnsafeBufferPointeritself is being used safely (i.e., accesses are in-bounds and the buffer doesn't escape the closure) and thatc_library_sum_functiondoes the same with the pointer and bounds it is given.
Lots more details are in the proposal.
Doug