fix: trim-resolvable UID construction#1
Open
quinnj wants to merge 3 commits into
Open
Conversation
Julia doesn't specialize methods on unparameterized Type arguments
(::Type{<:Union{...}}), so every UID(...; uid_type=...) call funneled into
one instance where uid_type is a runtime DataType — type-unstable, and
unresolvable dynamic dispatch under juliac --trim. A where-param keeps
dispatch identical and makes each uid_type a compile-time constant (the
if-else ladder in the body folds per instance).
…evel String fast path)
- UID constructors take the uid type as a where-param and forward to
_uid_impl positionally: julia doesn't specialize on unparameterized
Type arguments, and kwarg NamedTuples type a Type value as a bare
DataType — either way every call funneled into one instance with a
runtime DataType, unresolvable under juliac --trim.
- Single-word String fast path: the generic path wraps strings as
StringN{length(s)} — a runtime type parameter — making the encode
machinery runtime dispatch. The value-level path produces bit-identical
results (verified seed-for-seed against the generic path for
UID2/4/8/16) and tags the result UID{String, U}. Multi-word types fall
through to the generic method.
Found in passing: the generic path throws for UID24 with a 16-char
string (its words vector promotes to Vector{UInt128}, then the UID24
constructor rejects (UInt128, UInt128)) — pre-existing, not addressed
here.
repeat(String, Int) is an unresolved invoke under juliac --trim; an explicit byte fill produces the same string.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three commits that make
UIDgeneration compile cleanly underjuliac --trim(found while trim-compiling an HTTP server whose id generation funnels through Encid):1. Specialize the constructors on the uid type
Julia doesn't specialize methods on unparameterized
::Type{<:Union{...}}arguments, and kwarg NamedTuples type a Type value as a bareDataType— either way everyUID(...)call funneled into one instance whereuid_typeis a runtimeDataType: type-unstable, and unresolvable dynamic dispatch under--trim. Both entry points now take::Type{U} ... where Uand forward positionally to_uid_impl, so the body'suid_type == UIDnladder folds per instance.2. Value-level String fast path (single-word uid types)
The generic path wraps strings as
StringN{length(s)}— a runtime type parameter — which makes the whole encode machinery runtime dispatch. Generation only needs the length's value, soUID(::Type{U}, s::String)forU ∈ {UID2, UID4, UID8, UID16}does the same bit surgery value-level. Bit-identical output verified seed-for-seed against the generic path for all four types. Multi-word types fall through to the generic method unchanged. Note: the result is taggedUID{String, U}rather thanUID{Tuple{StringN{N}}, U}— printing/generation identical; callers that decode by type should use the generic constructor.3. base58: byte fill instead of
"1"^nrepeat(::String, ::Int)is an unresolved invoke under--trim;String(fill(UInt8('1'), n))produces the same padding (roundtrip verified, e.g.[0,0,5,1] → "11P6" → [0,0,5,1]).Found in passing (not addressed here)
The generic path throws for
UID24with a 16-char string: its words vector[UInt128(t[1]), UInt64(t[2])]promotes toVector{UInt128}, and theUID24((words[1], words[2]))construction then rejects(UInt128, UInt128). Pre-existing; worth its own fix.Tests green; with this + the JSON/StructUtils/Parsers/HTTP trim PRs, a 30+ package server graph's id-generation path contributes zero verifier errors.
🤖 Generated with Claude Code