Contents

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 outputHash.Value = Tagged<Hash, Int> distinguishes hash values from arbitrary integers. The phantom Hash tag (the namespace itself, reused as the tag) prevents accidental misuse — hashes can't be confused with offsets, counts, or magic constants.
  • Move-only hashingHash.Protocol lets ~Copyable types implement hash(into:) with borrowing self. The == requirement is inherited from Equation.Protocol.
  • Equals/hashCode contract at the type levelHash.Protocol: Equation.Protocol enforces 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 Hashable types under Swift <6.4. On Swift 6.4+ those bridges become no-ops because Hash.Protocol IS Swift.Hashable.
  • SE-0499 dual-mode — Under Swift <6.4, the package ships its own protocol fork. Under Swift 6.4+, Hash.Protocol is a typealias to Swift.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.underlying

A 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 requirement

Installation

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