Skip to content

Libtask v0.9.9 breaks Union types #207

@penelopeysm

Description

@penelopeysm

This is causing Turing PG/SMC to fail on all models.

using Libtask

g(i::Int) = begin; produce(1); i; end
g(s::String) = begin; produce(2); s; end
Libtask.@might_produce g

h(i::Int)::Int = i
h(s::String)::Int = length(s)

function f(x)
    i_or_s = if x > 0
        3
    else
        "libtask"
    end
    # These lines are just to make sure that `f` itself is type stable.
    # You can trigger the same error by just returning `g(i_or_s)`
    gres = g(i_or_s)
    return h(gres)
end

t = TapedTask(nothing, f, 1)
consume(t) # returns 1
consume(t) # should return `nothing`, but errors on 0.9.9 with:

#=
ERROR: TypeError: in typeassert, expected Base.RefValue{Union{Int64, String}}, got a value of type Base.RefValue{Int64}
Stacktrace:
 [1] deref_phi
   @ ~/ppl/Libtask.jl/src/copyable_task.jl:1229 [inlined]
 [2] f
   @ ./REPL[26]:2 [inlined]
 [3] (::Tuple{…})(_2::typeof(f), _3::Int64)
   @ Base.Experimental ./<missing>:0
 [4] consume(t::TapedTask{Nothing, Tuple{typeof(f), Int64}, MistyClosures.MistyClosure{Core.OpaqueClosure{…}}})
   @ Libtask ~/ppl/Libtask.jl/src/copyable_task.jl:378
 [5] top-level scope
   @ REPL[29]:1
=#

It works fine on 0.9.8 so this is caused by #205. You can fix it by moving the call to gres inside the if/else, so this works:

function f(x)
    gres = if x > 0
        g(3)
    else
        g("libtask")
    end
    return h(gres)
end

The immediate Turing breakage is here. You can work around it by moving the tilde_assume!! call inside the if/else just like with g, but doing that just shifts the error to something else in DynamicPPL, I think from_maybe_linked_vec_transform.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions