Hi everyone, I have a short pitch to add a RawSpan primitive to Hasher to mirror the existing unsafe buffer pointer API. The swift-evolution PR is up at Add RawSpan primitive to Hasher by jmschonfeld · Pull Request #3490 · swiftlang/swift-evolution · GitHub and the contents of the proposal are below.
Add RawSpan primitive to Hasher
- Proposal: SE-NNNN
- Author: Jeremy Schonfeld
- Review Manager: TBD
- Status: Awaiting implementation
- Implementation: Not yet implemented
Summary of changes
Adds a new primitive API to Hasher for mixing the bytes of a RawSpan into the hasher's state.
Motivation
Today, Hasher offers two main APIs for mixing data into its state:
- A generic API that accepts any
Hashablevalue, deferring to that value'shash(into:)implementation. - A primitive API that accepts an
UnsafeRawBufferPointerand mixes in the contents of the buffer directly.
Swift now has the RawSpan type, a safe alternative to UnsafeRawBufferPointer. Developers should be able to use Hasher's primitive API without depending on unsafe APIs.
Proposed solution
Add a new primitive API to Hasher that accepts a RawSpan as its argument. The new API can be used as follows:
var values: InlineArray<_, UInt8> = /* ... */
var hasher = Hasher()
hasher.combine(bytes: values.bytes)
Detailed design
extension Hasher {
@export(implementation)
public mutating func combine(bytes: RawSpan)
}
Source compatibility
This change should have no impact on source compatibility. The new API overloads an existing one, but UnsafeRawBufferPointer and RawSpan are not ambiguous with each other, and any client-provided implementation of this API will shadow the version provided by the standard library.
ABI compatibility
No impact on ABI compatibility.
Implications on adoption
This API can be freely adopted and unadopted in source code, assuming a deployment target new enough to use the RawSpan type itself.
Future directions
RawSpan Hashable conformance
We may want to conform RawSpan itself to Hashable in the future. While that is worth investigating, this proposal is focused solely on bringing the existing Hasher primitives to parity with newer standard library types. If RawSpan were to gain a Hashable conformance, it would also become possible to pass a RawSpan to the existing combine<H: Hashable>(_:) API. That would not obsolete the API proposed here: even if RawSpan is a valid argument to the generic combine, it remains important to provide a primitive API for hashing bytes that does not require the use of unsafe APIs.