Tuple constructor on 0.6 with convert


#1

The following works on 0.5 but not on 0.6

julia>  immutable Test1{T<:AbstractFloat} <: Number
                     x::T
                     y::T
        end

julia> import Base.convert; convert{T}(::Type{Tuple{T,T}}, x::Test1{T}) = (x.x,  x.y)

julia> Tuple{Float64,Float64}(Test1(.2,2.2))
ERROR: MethodError: Cannot `convert` an object of type Test1{Float64} to an object of type Float64
This may have arisen from a call to the constructor Float64(...),
since type constructors fall back to convert methods.
Stacktrace:
 [1] _totuple at .\tuple.jl:211 [inlined]
 [2] Tuple{Float64,Float64}(::Test1{Float64}) at .\tuple.jl:198

Is there a reason why this should fail on 0.6?


#2

Reference:


#3

Is that relevant here?


#4

In Julia 0.6

Tuple{Float64,Float64}(Test1(.2,2.2))

calls

(::Type{T}){T<:Tuple}(itr) = _totuple(T, itr, start(itr))

from tuple.jl, that was introduced with that pull request. Instead, in Julia 0.5 the generic

(::Type{T}){T}(arg) = convert(T, arg)::T

from sysimg.jl was used (still present in Julia 0.6).

Thus, the change was definitely introduced with that PR, I can’t comment whether it was intentional or not to prevent simple conversions like yours.


#5

You’re defining a conversion but calling the constructor. Calling convert directly works, or you can define a custom constructor. Or even better, define iteration for your Test1 object and the default constructor will just work.

julia> (::Type{Tuple{T,T}}){T}(x::Test1{T}) = (x.x,  x.y)

julia> Tuple{Float64,Float64}(Test1(.2,2.2))
(0.2, 2.2)