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
sum
function as@unsafe
, propagating the "unsafe" checking out to callers ofsum
; or - Mark the
sum
function as@safe(unchecked)
, taking responsibility for the safety of the code within the body. Here, one needs to verify that theUnsafeBufferPointer
itself is being used safely (i.e., accesses are in-bounds and the buffer doesn't escape the closure) and thatc_library_sum_function
does the same with the pointer and bounds it is given.
Lots more details are in the proposal.
Doug