Using parametric type inside outer parametric constructor

Removing the <: from the type definition makes it work:

This works:

julia> struct Foo{T<:Real, S<:AbstractMatrix{T}}
               data::S
               n::Int
       end

julia> Foo(A::AbstractMatrix{T}, n::Int) where {T<:Real} = Foo{T, typeof(A)}(A, n)
Foo

julia> Foo{T}(::UndefInitializer,n) where {T<:Real} = Foo(Matrix{T}(undef,n,n),n)

julia> Foo{Float64}(undef,2)
Foo{Float64,Array{Float64,2}}([0.0 0.0; 0.0 0.0], 2)

julia>

This does not:

julia> struct Foo{T<:Real, S<:AbstractMatrix{<:T}} # the difference is the <: here
               data::S
               n::Int
       end

julia> Foo(A::AbstractMatrix{T}, n::Int) where {T<:Real} = Foo{T, typeof(A)}(A, n)
Foo

julia> Foo{T}(::UndefInitializer,n) where {T<:Real} = Foo(Matrix{T}(undef,n,n),n)

julia> Foo{Float64}(undef,2)
ERROR: UndefVarError: T not defined

Minimal example:

julia> struct Foo{T,S <: Vector{<:T}}
         x :: S
       end

julia> Foo{T}(::UndefInitializer) where T = Foo(Vector{T}(undef,2))

julia> Foo{Float64}(undef)
ERROR: UndefVarError: T not defined

2 Likes