Capturing a parameter of a type!

abstract type MM{T} end

capture(::Type{MM{T}}) where T = T

capture(MM{Int})
Int64

julia> const CMM{C} = MM{T} where T<:C
MM{T} where T<:C where C

julia> capture(::Type{CMM{T}}) where T = T
capture (generic function with 2 methods)

julia> capture(CMM{Int})
ERROR: UndefVarError: T not defined
Stacktrace:
 [1] capture(::Type{MM{T} where T<:Int64}) at ./REPL[5]:1
 [2] top-level scope at REPL[6]:1

The second one doesn’t work? Is there a way to capture Int in the second example?

Thanks

To me the error makes sense. Note that the problem is not in “capturing” the type, but rather the definition of CMM: in

const CMM{C} = MM{T} where T<:C

what type is T supposed to be?

1 Like

I think an interesting aspect is that this still happens when C is Int which is a concrete type. Shouldn’t upper-bounding by a concrete type determine the type parameter? The reason that it’s not enough is Union{} <: Int. Because of this, we have:

julia> abstract type MM{T} end

julia> CMM{C} = MM{T} where T<:C
MM{T} where T<:C where C

julia> MM{Int} <: CMM{Int}
true

julia> MM{Union{}} <: CMM{Int}
true

So, julia can’t decide what T in MM{T} where T<:C should be.

This just caused an “interesting” bug in StaticArrays: https://github.com/JuliaArrays/StaticArrays.jl/pull/685. See also:

https://github.com/JuliaLang/julia/issues/33780

1 Like