Skip to content

The behavior of type parameter constraint inheritance is not documented #53380

Open
@brainandforce

Description

@brainandforce

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    breakingThis change will break codedocsThis change adds or pertains to documentationminor changeMarginal behavior change acceptable for a minor releasetypes and dispatchTypes, subtyping and method dispatch

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions