How does Julia invoke constructors with overlapping constraints

Hello, I am playing with constructors, but seems, that Julia allows to have constructor with overlapping constrains N.

using StaticArrays: SizedVector

mutable struct Context{TYPE_VAR_STACK <: Union{UInt8, UInt16}, N <:Union{UInt8, UInt16}}
    stack::SizedVector
    index::N 

    # Constructor constraint for N <:UInt8
    function Context(stack_type::Type{T}, stack_length::N, def_stack_val=eltype(stack_type)(0),) where {T <: Union{UInt8, UInt16}, N <: Union{UInt8}}
        
        println("ctor UInt8")
        # StaticArrays pkg doesn't allow to have its Size in different types than Int
        size = Int(stack_length)
        new{T, N}(SizedVector{size}(fill(def_stack_val, size)), size)
        
    end

    # More general constructor for N <:Union{UInt8 and UInt16}
    function Context(stack_type::Type{T}, stack_length::N, def_stack_val=eltype(stack_type)(0),) where {T <: Union{UInt8, UInt16}, N <: Union{UInt8, UInt16}}
        # StaticArrays pkg doesn't allow to have its Size in different types than Int
        size = Int(stack_length)
        new{T, N}(SizedVector{size}(fill(def_stack_val, size)), size)
        
    end


end


# More specific
julia> Context(UInt16, UInt8(100))
ctor UInt8
Context{UInt16, UInt8}(UInt16[0, 0, 0, 0, 0, 0, 0, 0, 0, 0  …  0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 100)
# More specific
julia> Context(UInt8, UInt8(100))
ctor UInt8
Context{UInt8, UInt8}(UInt8[0, 0, 0, 0, 0, 0, 0, 0, 0, 0  …  0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 100)

# More generic
julia> Context(UInt8, UInt16(100))
Context{UInt8, UInt16}(UInt8[0, 0, 0, 0, 0, 0, 0, 0, 0, 0  …  0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 100)

and methods

julia> methods(Context)
# 4 methods for type constructor:
 [1] Context(stack_type::Type{T}, stack_length::N) where {T<:Union{UInt16, UInt8}, N<:UInt8}
     @ ~/devel/julia/bf/bf.jl:8
 [2] Context(stack_type::Type{T}, stack_length::N, def_stack_val) where {T<:Union{UInt16, UInt8}, N<:UInt8}
     @ ~/devel/julia/bf/bf.jl:8
 [3] Context(stack_type::Type{T}, stack_length::N, def_stack_val) where {T<:Union{UInt16, UInt8}, N<:Union{UInt16, UInt8}}
     @ ~/devel/julia/bf/bf.jl:18
 [4] Context(stack_type::Type{T}, stack_length::N) where {T<:Union{UInt16, UInt8}, N<:Union{UInt16, UInt8}}
     @ ~/devel/julia/bf/bf.jl:18

I have several question:

  1. Is there some kind of internal mechanism, that uses more specific constructor?
  2. Is there possibility to call more general constructor?
  1. The same way as for any other function multiple dispatch/method specificity Methods · The Julia Language
  2. invoke