Open
Description
If you have an abstract type with a constrained type parameter, subtypes whose parameters inherit from the type's parameters do not inherit the constraints.
abstract type AbstractFoo{T<:Real}
end
struct Foo{T} <: AbstractFoo{T} end
julia> supertype(Foo)
AbstractFoo{T} where T
julia> supertype(Foo{<:Real}}
AbstractFoo
julia> Foo <: AbstractFoo # This one is very much unexpected!
false
julia> Foo{<:Real} <: AbstractFoo
true
This is true even though you can't construct a type which violates the constraints on its parent's parameters:
julia> Foo{String}
ERROR: TypeError: in AbstractFoo, in T, expected T<:Real, got Type{String}
Stacktrace:
[1] top-level scope
@ REPL[5]:1
This is a subtle point that is not included in the documentation on abstract parametric types, but has caused me some headaches when some subtype relations broke unexpectedly.
The above examples were tested on Julia 1.10 (version info below) running on Arch Linux in WSL2, installed with the AUR provided julia-bin
package that provides the official release:
julia> versioninfo()
Julia Version 1.10.0
Commit 3120989f39b (2023-12-25 18:01 UTC)
Build Info:
Official https://julialang.org/ release
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: 20 × 13th Gen Intel(R) Core(TM) i5-13600K
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-15.0.7 (ORCJIT, goldmont)
Threads: 1 on 20 virtual cores