Bug
On 32-bit Julia (UInt == UInt32), loading SymbolicUtils fails at precompile time:
julia> using SymbolicUtils
ERROR: LoadError: InexactError: trunc(UInt32, 0x8b4142913acd1c23)
[6] hash_bsimpl(...) @ SymbolicUtils hashconsing.jl:467
...
[22] top-level scope @ SymbolicUtils/src/SymbolicUtils.jl:178 # @compile_workload
Fires inside the @compile_workload block, so every downstream package fails to precompile on 32-bit too.
Root cause
src/hashconsing.jl:310 declares FNTYPE_SEED as a raw UInt64 literal, unlike SYM_SALT/DIV_SALT on lines 225–226 which correctly coerce with % UInt:
const FNTYPE_SEED = 0x8b414291138f6c45 # line 310 — bug
const SYM_SALT = 0x4de7d7c66d41da43 % UInt # line 225 — correct
On 32-bit, FNTYPE_SEED is UInt64. Its only use (line 351) is hash(...)::UInt ⊻ FNTYPE_SEED — the ::UInt only constrains the inner hash call, so the XOR widens the result to UInt64, which then fails to fit back into a ::UInt field.
Sanity check: 0x8b414291138f6c45 ⊻ 0x8b4142913acd1c23 = 0x0000000029427066 — upper 32 bits unchanged, which is exactly what XOR'ing a zero-extended UInt32 into a UInt64 looks like.
Fix
-const FNTYPE_SEED = 0x8b414291138f6c45
+const FNTYPE_SEED = 0x8b414291138f6c45 % UInt
No-op on 64-bit; truncates the constant to UInt32 on 32-bit. Happy to send a PR.
Versions
SymbolicUtils 4.24.2 (also 4.21.0); Julia 1.12 stable and nightly; Linux x86 and Windows x86. Not reproduced on any x64 target. Hit initially in CI for ReversePropagation.jl.
CI note
This regression escaped because ci.yml tests only ubuntu-latest × x64 — no arch key in the matrix, so 32-bit targets are never exercised. Adding arch: [x64, x86] (with a macOS-x86 exclude) would have caught it.
Bug
On 32-bit Julia (
UInt == UInt32), loading SymbolicUtils fails at precompile time:julia> using SymbolicUtils ERROR: LoadError: InexactError: trunc(UInt32, 0x8b4142913acd1c23) [6] hash_bsimpl(...) @ SymbolicUtils hashconsing.jl:467 ... [22] top-level scope @ SymbolicUtils/src/SymbolicUtils.jl:178 # @compile_workloadFires inside the
@compile_workloadblock, so every downstream package fails to precompile on 32-bit too.Root cause
src/hashconsing.jl:310declaresFNTYPE_SEEDas a rawUInt64literal, unlikeSYM_SALT/DIV_SALTon lines 225–226 which correctly coerce with% UInt:On 32-bit,
FNTYPE_SEEDisUInt64. Its only use (line 351) ishash(...)::UInt ⊻ FNTYPE_SEED— the::UIntonly constrains the innerhashcall, so the XOR widens the result toUInt64, which then fails to fit back into a::UIntfield.Sanity check:
0x8b414291138f6c45 ⊻ 0x8b4142913acd1c23 = 0x0000000029427066— upper 32 bits unchanged, which is exactly what XOR'ing a zero-extendedUInt32into aUInt64looks like.Fix
No-op on 64-bit; truncates the constant to
UInt32on 32-bit. Happy to send a PR.Versions
SymbolicUtils 4.24.2 (also 4.21.0); Julia 1.12 stable and nightly; Linux x86 and Windows x86. Not reproduced on any x64 target. Hit initially in CI for ReversePropagation.jl.
CI note
This regression escaped because
ci.ymltests onlyubuntu-latest × x64— noarchkey in the matrix, so 32-bit targets are never exercised. Addingarch: [x64, x86](with a macOS-x86 exclude) would have caught it.