I noticed a strange behavior when using constructors of parametric types.
If a constructor does not have constraints on type parameters, then both type inference and providing explicit type argument work:
struct Foo{T}
val :: T
Foo(x :: T) where T = new{T}(x)
end
julia> Foo(3)
Foo{Int64}(3)
julia> Foo{Number}(3)
Foo{Number}(3)
But if I add a constraint on a type parameter, then depending on the syntax of a constructor only one of the constructor’s calls works:
struct Bar{T}
val :: T
Bar(x :: T) where T <: Number = new{T}(x)
end
struct Baz{T}
val :: T
Baz{T}(x :: T) where T <: Number = new{T}(x)
end
julia> Bar(2)
Bar{Int64}(2)
julia> Bar{Number}(2)
ERROR: MethodError: Cannot `convert` an object of type Int64 to an object of type Bar{Number}
This may have arisen from a call to the constructor Bar{Number}(...),
since type constructors fall back to convert methods.
Stacktrace:
[1] Bar{Number}(::Int64) at ./sysimg.jl:102
julia> Baz{Number}(2)
Baz{Number}(2)
julia> Baz(2)
ERROR: MethodError: Cannot `convert` an object of type Int64 to an object of type Baz
This may have arisen from a call to the constructor Baz(...),
since type constructors fall back to convert methods.
Stacktrace:
[1] Baz(::Int64) at ./sysimg.jl:102
Is this a bug?