swift-primitives/swift-hash-primitives
Hash.Value — a typed wrapper for hash output that prevents accidental misuse of arbitrary integers as hashes — and Hash.Protocol, a hashing protocol that admits ~Copyable types via borrowing parameters. Mirrors Swift.Hashable and, on Swift 6.4 and later, is `Swift.Has
Key Features
- Typed hash output —
Hash.Value = Tagged<Hash, Int>distinguishes hash values from arbitrary integers. The phantomHashtag (the namespace itself, reused as the tag) prevents accidental misuse — hashes can't be confused with offsets, counts, or magic constants. - Move-only hashing —
Hash.Protocollets~Copyabletypes implementhash(into:)withborrowing self. The==requirement is inherited fromEquation.Protocol. - Equals/hashCode contract at the type level —
Hash.Protocol: Equation.Protocolenforces that hashable types support equality. Equal values must produce equal hashes (the semantic invariant remains your responsibility, but the type system stops you from declaring a hash without an equality). - Stdlib bridges included — Standard Library Integration target re-conforms common stdlib
Hashabletypes under Swift <6.4. On Swift 6.4+ those bridges become no-ops becauseHash.ProtocolISSwift.Hashable. - SE-0499 dual-mode — Under Swift <6.4, the package ships its own protocol fork. Under Swift 6.4+,
Hash.Protocolis a typealias toSwift.Hashable. Conformances written today work on both compiler families.
Quick Start
A move-only token type conforms with borrowing == and hash(into:):
import Hash_Primitives
struct Token: ~Copyable {
let id: Int
}
extension Token: Hash.`Protocol` {
static func == (lhs: borrowing Token, rhs: borrowing Token) -> Bool {
lhs.id == rhs.id
}
borrowing func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}Hash.Value is the typed wrapper for hash output:
let value: Hash.Value = .init(42)
let raw: Int = value.underlyingA Copyable type that already conforms to Swift.Hashable conforms with an empty extension under Swift <6.4 — and skips the conformance entirely under Swift 6.4+, because Hash.Protocol IS Swift.Hashable there:
struct UserID: Hashable, Hash.`Protocol` {
let value: UInt64
}
// no body required — Swift.Hashable's hash(into:) satisfies the requirementInstallation
Add the dependency to your Package.swift:
dependencies: [
.package(url: "https://github.com/swift-primitives/swift-hash-primitives.git", branch: "main")
]Add the umbrella product to your target:
.target(
name: "App",
dependencies: [
.product(name: "Hash Primitives", package: "swift-hash-primitives")
]
)For narrower surface, depend on Hash Primitives Core alone (typed wrapper + protocol, no stdlib bridge).
Requires Swift 6.3.1 and macOS 26 / iOS 26 / tvOS 26 / watchOS 26 / visionOS 26 (or the corresponding Linux / Windows toolchain).
Architecture
Four library products plus a Test Support target:
| Product | Contents | When to import | |---------|----------|----------------| | Hash Primitives | Umbrella — re-exports Core + Standard Library Integration | Most consumers | | Hash Primitives Core | Hash namespace, Hash.Value, Hash.Protocol | Embedded contexts, or when stdlib bridges are unwanted | | Hash Primitives Standard Library Integration | Re-conformance of stdlib types under Swift <6.4 | Pulled in transitively by the umbrella | | Hash Primitives Test Support | Re-export of upstream Test Support modules | Test target only |
The Standard Library Integration target's bridges are gated behind #if swift(<6.4). Under Swift 6.4 and later, stdlib types already conform to Swift.Hashable (which Hash.Protocol typealiases to) and the bridges become no-ops.
Stability
Pre-1.0. The 0.1.0 surface — Hash.Value typed wrapper, Hash.Protocol, the equals/hashCode refinement on Equation.Protocol — is committed to source-compatibility through the dual-mode bridge. The typed wrapper Hash.Value is independent of the SE-0499-driven protocol question and remains regardless of which compiler your consumer ships against. The eventual long-term shape, post-Swift-6.4-ecosystem-floor, is the protocol's typealias-to-stdlib reduction; the typed wrapper stays.
Platform Support
| Platform | CI | Status | |------------------|-----|--------------| | macOS 26 | Yes | Full support | | Linux | Yes | Full support | | Windows | Yes | Full support | | iOS/tvOS/watchOS | — | Supported | | Swift Embedded | — | Supported |
License
Apache 2.0. See LICENSE.md.
Package Metadata
Repository: swift-primitives/swift-hash-primitives
Default branch: main
README: README.md