Segfault when using promote_typejoin to control small union behaviour over parametric type

I have a parametric type AtLeast{T}(x::T), and I’d like my broadcasts over vectors of Union{Float64, AtLeast} to propagate its type, instead of becoming Any. Following the discussion in this post, I do this:

julia> struct AtLeast{T}
           x::T
       end

julia> a = [1.0, AtLeast(1.0)]
2-element Array{Any,1}:
 1.0                   
  AtLeast{Float64}(1.0)

julia> identity.(a)    # bad
2-element Array{Any,1}:
 1.0                   
  AtLeast{Float64}(1.0)

julia> Base._promote_typejoin(::Type{A}, ::Type{T}) where {T, A<:AtLeast} =
           isconcretetype(T) || T === Union{} ? Union{T, A} : Any

julia> Base._promote_typejoin(::Type{T}, ::Type{A}) where {T, A<:AtLeast} =
           isconcretetype(T) || T === Union{} ? Union{T, A} : Any

julia> identity.(a)    # good
2-element Array{Union{Float64, AtLeast{Float64}},1}:
 1.0                   
  AtLeast{Float64}(1.0)

All’s well, but when I put these two _promote_typejoin lines into my (large) module, precompilation segfaults on Julia 1.1, Linux. I’ve tried to bisect it to a MWE, but after one hour of toil, I just found out that it depends on another of our private modules, and Unitful (at least). Gah. Am I doing anything wrong?

signal (6): Aborted
in expression starting at no file:0
raise at /build/glibc-LK5gWL/glibc-2.23/signal/../sysdeps/unix/sysv/linux/raise.c:54
abort at /build/glibc-LK5gWL/glibc-2.23/stdlib/abort.c:89
jl_intref at /buildworker/worker/package_linux64/build/src/typemap.c:190 [inlined]
mtcache_hash_lookup at /buildworker/worker/package_linux64/build/src/typemap.c:251 [inlined]
jl_typemap_intersection_visitor at /buildworker/worker/package_linux64/build/src/typemap.c:526
jl_method_table_insert at /buildworker/worker/package_linux64/build/src/gf.c:1622
_jl_restore_incremental at /buildworker/worker/package_linux64/build/src/dump.c:2174
jl_restore_incremental at /buildworker/worker/package_linux64/build/src/dump.c:3159
_include_from_serialized at ./loading.jl:617
_require_from_serialized at ./loading.jl:684
_require at ./loading.jl:967
require at ./loading.jl:858
require at ./loading.jl:853
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2219
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1571 [inlined]
call_require at /buildworker/worker/package_linux64/build/src/toplevel.c:397 [inlined]
eval_import_path at /buildworker/worker/package_linux64/build/src/toplevel.c:432
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:630
jl_toplevel_eval_in at /buildworker/worker/package_linux64/build/src/toplevel.c:793
eval at ./boot.jl:328
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2219
eval_user_input at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.1/REPL/src/REPL.jl:85
macro expansion at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.1/REPL/src/REPL.jl:117 [inlined]
#26 at ./task.jl:259
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2219
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1571 [inlined]
start_task at /buildworker/worker/package_linux64/build/src/task.c:572
unknown function (ip: 0xffffffffffffffff)
Allocations: 21554287 (Pool: 21551691; Big: 2596); GC: 40
Aborted (core dumped)
1 Like