Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
brainandforce opened this issue Feb 18, 2024 · 4 comments
Open
Labels
domain:docs This change adds or pertains to documentation domain:types and dispatch Types, subtyping and method dispatch kind:breaking This change will break code kind:minor change Marginal behavior change acceptable for a minor release

Comments

@brainandforce
Copy link

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
@mikmoore
Copy link
Contributor

It seems that maybe the simplest and most robust solution to "simply" change type behavior to clone parameter constraints from supertypes? The actual parameter of a subtype would be restricted by the typeintersect of the subtype's and parent type's constraints in the relevant parameters.

Since types can only be declared once and never modified or moved within the hierarchy, this seems possible? It also seems nonbreaking, except for the useless(?) case where previously one could define a type even though one could never instantiate it.

@nsajko nsajko added the domain:types and dispatch Types, subtyping and method dispatch label Mar 1, 2024
@nsajko nsajko added needs decision A decision on this change is needed design Design of APIs or of the language itself kind:correctness bug ⚠ Bugs that are likely to lead to incorrect results in user code without throwing kind:minor change Marginal behavior change acceptable for a minor release labels Apr 25, 2024
@vtjnash vtjnash added kind:breaking This change will break code and removed needs decision A decision on this change is needed design Design of APIs or of the language itself kind:correctness bug ⚠ Bugs that are likely to lead to incorrect results in user code without throwing labels May 3, 2024
@brainandforce
Copy link
Author

@vtjnash I know that changing the behavior described here would be a breaking change, but I opened this issue solely for documentation purposes, since this behavior is not detailed in the manual.

@nsajko
Copy link
Contributor

nsajko commented Jun 18, 2024

Documenting the buggy behavior may prevent future fixes.

@vtjnash vtjnash added the domain:docs This change adds or pertains to documentation label Jun 19, 2024
@vtjnash
Copy link
Sponsor Member

vtjnash commented Jun 19, 2024

Okay, I added the doc tag as well, to reflect that we may want to document the current situation better, and indicate that while changes could be considered, they are not necessary for this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:docs This change adds or pertains to documentation domain:types and dispatch Types, subtyping and method dispatch kind:breaking This change will break code kind:minor change Marginal behavior change acceptable for a minor release
Projects
None yet
Development

No branches or pull requests

4 participants