Casting struct into an apparently identical type

Is it possible (even if hacky and not advisable) to do something like the following? Forewarning: this is a contrived example that just happens to work as an MWE exercise for my use case.

Let Foo be some type whose definition I can’t control and with a fundamentally-incompatible inner constructor.

struct Foo{T}
    x::T
    Foo(x) = error()
end

Is it possible to declare a shadow implementation a la

struct _ShadowFoo{T}
    x::T
end

and then cast an instance of this type to the type being shadowed?

reinterpret(Foo{Float64}, _ShadowFoo(1.0))

This use of reinterpret doesn’t seem to work for me and I haven’t been able to find a different function that achieves this effect.

Reinterpret usually works on mutable arrays and may be implemented for some other mutable types.

We can accomplish what you want as follows.

julia> shadows = [_ShadowFoo(1.0)]
1-element Vector{_ShadowFoo{Float64}}:
 _ShadowFoo{Float64}(1.0)

julia> reinterpret(Foo{Float64}, shadows)[1]
Foo{Float64}(1.0)

Here we managed to construct Foo despite having no constructor.

1 Like

I think v1.10 added support for reinterpreting between isbitstype types. On v1.10, the original post’s code all works for me, concluding with

julia> reinterpret(Foo{Float64}, _ShadowFoo(1.0))
Foo{Float64}(1.0)

I think it mostly uses the procedure that mkitti suggests, but it’s builtin and maybe does it in a way that is slightly more sophisticated and possibly more performant. See @less Base._reinterpret(ComplexF32, 1.0) for the source.

2 Likes