beacon-biosignals / StableHashTraits.jl

Compute hashes over any Julia object simply and reproducibly
MIT License
7 stars 1 forks source link

World-age issue with `julia --compiled-modules=no` #36

Closed kbarros closed 9 months ago

kbarros commented 10 months ago

Create a fresh Julia environment with StableHashTraits and CRC32c packages:

julia --compiled-modules=no
] activate --temp
add StableHashTraits, CRC32c

Execute from the REPL:

import StableHashTraits, CRC32c
StableHashTraits.stable_hash("hello"; alg=CRC32c.crc32c, version=2)

I get the following error on both Julia 1.9 and Julia 1.10-rc1:

julia> StableHashTraits.stable_hash("hello"; alg=CRC32c.crc32c, version=2)
ERROR: MethodError: no method matching cleanup_name(::String)
The applicable method may be too new: running in world age 34355, while current world is 34425.

Closest candidates are:
  cleanup_name(::Any) (method too new to be called from this world context.)
   @ StableHashTraits ~/.julia/packages/StableHashTraits/cnBjT/src/StableHashTraits.jl:530

Stacktrace:
  [1] qname_(T::Type, name::typeof(string))
    @ StableHashTraits ~/.julia/packages/StableHashTraits/cnBjT/src/StableHashTraits.jl:417
  [2] qualified_type_(x::Type{String})
    @ StableHashTraits ~/.julia/packages/StableHashTraits/cnBjT/src/StableHashTraits.jl:421
  [3] qualified_(T::Type, #unused#::Type{Val{:type}})
    @ StableHashTraits ~/.julia/packages/StableHashTraits/cnBjT/src/StableHashTraits.jl:427
  [4] #s226#10
    @ ~/.julia/packages/StableHashTraits/cnBjT/src/StableHashTraits.jl:489 [inlined]
  [5] var"#s226#10"(::Any, x::Any, of::Any)
    @ StableHashTraits ./none:0
  [6] (::Core.GeneratedFunctionStub)(::Any, ::Vararg{Any})
    @ Core ./boot.jl:602
  [7] stable_type_id
    @ ~/.julia/packages/StableHashTraits/cnBjT/src/StableHashTraits.jl:516 [inlined]
  [8] get_value_
    @ ~/.julia/packages/StableHashTraits/cnBjT/src/StableHashTraits.jl:558 [inlined]
  [9] stable_hash_helper(x::String, hash_state::StableHashTraits.BufferedHashState{StableHashTraits.RecursiveHashState{typeof(CRC32c.crc32c), UInt32}}, context::StableHashTraits.HashVersion{2}, method::StableHashTraits.FnHash{typeof(StableHashTraits.stable_type_id), StableHashTraits.WriteHash})
    @ StableHashTraits ~/.julia/packages/StableHashTraits/cnBjT/src/StableHashTraits.jl:583
 [10] hash_foreach_new(fn::StableHashTraits.var"#12#13"{String}, hash_state::StableHashTraits.BufferedHashState{StableHashTraits.RecursiveHashState{typeof(CRC32c.crc32c), UInt32}}, context::StableHashTraits.HashVersion{2}, xs::Tuple{StableHashTraits.FnHash{typeof(StableHashTraits.stable_type_id), StableHashTraits.WriteHash}, StableHashTraits.WriteHash})
    @ StableHashTraits ~/.julia/packages/StableHashTraits/cnBjT/src/StableHashTraits.jl:365
 [11] hash_foreach
    @ ~/.julia/packages/StableHashTraits/cnBjT/src/StableHashTraits.jl:347 [inlined]
 [12] stable_hash_helper
    @ ~/.julia/packages/StableHashTraits/cnBjT/src/StableHashTraits.jl:602 [inlined]
 [13] #stable_hash#2
    @ ~/.julia/packages/StableHashTraits/cnBjT/src/StableHashTraits.jl:56 [inlined]
 [14] stable_hash(x::String; alg::Function, version::Int64)
    @ StableHashTraits ~/.julia/packages/StableHashTraits/cnBjT/src/StableHashTraits.jl:54
 [15] top-level scope
    @ REPL[4]:1

This is a practical problem because it is blocking JuliaHub's documentation builds, which may depend on GLMakie. The former uses --compiled-modules=no, and the latter calls into StableHashTraits here: https://github.com/MakieOrg/Makie.jl/blob/822d11cf1e9751084a276f79b616b03afdc43e2d/src/bezier.jl#L112.

ericphanson commented 10 months ago

I think this comes from misuse of @generated functions; this sounds exactly like

Generated functions are only permitted to call functions that were defined before the definition of the generated function. (Failure to follow this may result in getting MethodErrors referring to functions from a future world-age.)

from https://docs.julialang.org/en/v1/manual/metaprogramming/#Generated-functions.

In particular, stable_type_id on line 516 calls (eventually) cleanup_name defined on line 530.

Looking further in the docs, it says:

Calling any function that is defined after the body of the generated function. This condition is relaxed for incrementally-loaded precompiled modules to allow calling any function in the module.

So I guess that is why it works when --compiled-modules=no isn't present.

SimonDanisch commented 9 months ago

Could we just move around the definition?

SimonDanisch commented 9 months ago

Silly question, it does sound exactly like that issue. I made a pr and confirmed it locally: https://github.com/beacon-biosignals/StableHashTraits.jl/pull/39