Different behaviors between SVector and SMatrix parametric types

Hi, I’m confused about the different parametric type behaviors between SVector and SMatrix, both are SArray types. When sufficient size info is supplied, SVector has all parameters evaluated, but SMatrix still has one parameter left free, which seems unnecessary, as shown in the screenshot below:
why can’t SMatrix figure out the total size of the array is 4 in this case?

It gets figured out on construction. Until then you can make all sorts of random types, which cannot ever be types of objects – in fact Tuple{2,2} is already such a thing.

julia> Matrix{-99}
Matrix{-99} (alias for Array{-99, 2})

julia> SMatrix{2,2,Int}(1,2,3,4)
2×2 SMatrix{2, 2, Int64, 4} with indices SOneTo(2)×SOneTo(2):
 1  3
 2  4

julia> Tuple{2}(2)
ERROR: MethodError: First argument to `convert` must be a Type, got 2

Thanks, but I think the main confusion is that why SVector can figure out that total size?

Because that’s how SVector is defined

const SVector{S,T} = SArray{Tuple{S}, T, 1, S}

Whereas SMatrix requires all 4 type parameters:

const SMatrix{S1, S2, T, L} = SArray{Tuple{S1, S2}, T, 2, L}

The crucial difference is that L == S1 * S2 is not something the compiler can infer/calculate in type parameter space.