julia
julia copied to clipboard
Foo{T >: Int} gives ERROR: UndefVarError: `T` not defined
struct Foo{T >: Int}
x::T
end
I'm not sure if there is an actual use case for the following type specification, but at least this shouldn't give an UndefVarError when one calls Foo(1.0) and Foo(1) works.
I get this is putting the type bound as T instead of Int, but would be nice to have a hint somewhere. I'm not sure how to add it if someone knows.
~Which version is this on? I can't reproduce this:~
Missed the bit about Foo(1.0) erroring, now I can reproduce it
julia> struct Foo{T >: Int}
x::T
end
julia> Foo(1.0)
ERROR: UndefVarError: `T` not defined in static parameter matching
Suggestion: run Test.detect_unbound_args to detect method arguments that do not fully constrain a type parameter.
Stacktrace:
[1] Foo(x::Float64)
@ Main ./REPL[1]:2
[2] top-level scope
@ REPL[2]:1
julia> versioninfo()
Julia Version 1.12.0-DEV.512
Commit d01d2561e6* (2024-05-11 04:45 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: 24 × AMD Ryzen 9 7900X 12-Core Processor
WORD_SIZE: 64
LLVM: libLLVM-17.0.6 (ORCJIT, znver4)
Threads: 23 default, 1 interactive, 23 GC (on 24 virtual cores)
Environment:
JULIA_PKG_USE_CLI_GIT = true
This should presumably be a MethodError instead of an UndefVarError, but the type lower bounds gets ignored. Xref #54904.
According to the suggestion there, this is a Test.detect_unbound_args bug, since it doesn't know to model the covariance implications of this definition
Well there are two separate bugs here:
- On all Julia versions (v1.6 to v1.12-dev), an
UndefVarErroris thrown when aMethodErrorwould be better - On v1.11-dev and v1.12-dev the misleading
detect_unbound_argsmessage is additionally produced.
The UndefVarError is correct, as is the message about detect_unbound_args being supposed to be able to detect this, but just the Test.detect_unbound_args is failing to correctly detect it
If we are throwing an UndefVarError, should we throw it at the struct definition time instead of calling the constructor?
Assume we are going the ignoring lower bound route, then T will be an undefined variable in both cases, and the struct definition itself shouldn't work.
The struct definition must work, anything else would be breaking.