My gut tells me that this constructor doesn’t exist because it’s only straightforward in this case, where `T`

is only used once. Consider:

```
struct E{T <: Real}
a::T
b::Vector{T}
end
```

Now think about calling `E(1, [1.0])`

- which argument (if any) should be converted? Both `E(1.0, [1.0])`

and `E(1, [1])`

are valid and you also immediately run into problems when you have e.g. `E(Int8(-1), [0xff])`

because both conversions and a type promotion throw:

```
julia> convert(Int8, 0xff)
ERROR: InexactError: check_top_bit(Int8, 255)
julia> convert(UInt8, Int8(-1))
ERROR: InexactError: check_top_bit(UInt8, -1)
julia> promote(Int8(-1), 0xff)
ERROR: InexactError: check_top_bit(UInt8, -1)
```

The non-parametric version with explicit `Int`

and `Vector{Int}`

fields is perfectly fine with any conversion, because such an ambiguity can never occur! All fields can be promoted/converted in isolation. So IMO it’s perfectly ok to say “no, be specific with what you want to enforce” when talking about parametric types.

There is a default constructor - that is exactly what `C`

(no parameters) *is*. That is just a distinct method & method table from `C{T}`

:

What’s really going on here is that `Point`

, `Point{Float64}`

and `Point{Int64}`

are all different constructor functions. In fact, `Point{T}`

is a distinct constructor function for each type `T`

.

[…]

When the type is implied by the arguments to the constructor call, as in `Point(1,2)`

, then the types of the arguments must agree – otherwise the `T`

cannot be determined – but any pair of real arguments with matching type may be given to the generic `Point`

constructor.

and to prove that:

```
julia> struct C{T}
n::T
v::Vector{Real}
end
julia> methods(C)
# 1 method for type constructor:
[1] C(n::T, v::Vector{Real}) where T in Main at REPL[1]:2
julia> methods(C{Int})
# 1 method for type constructor:
[1] C{T}(n, v) where T in Main at REPL[1]:2
julia> methods(C)[1] === methods(C{Int})[1]
false
### with differently typed fields:
julia> struct C{T <: Real}
n::T
v::Vector{T}
end
julia> methods(C)
# 1 method for type constructor:
[1] C(n::T, v::Vector{T}) where T<:Real in Main at REPL[1]:2
julia> methods(C{Int})
# 1 method for type constructor:
[1] C{T}(n, v) where T<:Real in Main at REPL[1]:2
julia> methods(C)[1] === methods(C{Int})[1]
false
```

So no, the behavior is not a bug or broken, it is an expected consequence of an ambiguity that comes up when this (inevitably) has to be generalized to more than one argument constraining the `T`

.