It errors at MyStruct{String} alone. When you provide M<N parameters for a struct with N parameters, it makes an iterated union that fills in the first M parameters and takes the bounds of the type for the rest:
I see what you’re trying to do, but it’s not possible to opt out of the type system’s behavior above and treat S as an extra input next to the name MyStruct. An iterated union with the type parameter in the right position would work:
but that’s wordier. Any dummy type parameter or bounds there would still instantiate properly, but <:Real is more consistent with the iterated unions that setting M parameters would make.
Thanks, didn’t know that MyStruct{Float64} is indeed of UnionAll type.
What if now I have a struct
struct MyStruct{T<:Real}
x::T
end
Now I got curious: what does MyStruct{<:Any} really generate? I feel like it should be a union of all types of the form MyStruct{T}, where T<:Any. But then the type MyStruct{String} should be in this union as well (however, it cannot be created in Julia REPL).
Right, you can make iterated unions that specify invalid types, even strict supertypes of the original type or a completely disjoint set of invalid types: