Calling type-unstable functions within a type-stable function (and usage of Val)

I have a function f that is potentially type-unstable. I also have a function g that in the end is type-stable, but inside it calls f.

Here is an (artificial) example, implemented in different ways:

f1(t::Tuple, i::Int) = t[i]
g1(thetupl::Tuple, ::Val{n}) where {n} = ntuple(i -> f1(thetupl, i), Val(n))

f2(t::Tuple, ::Val{i}) where {i} = t[i]
g2(thetupl::Tuple, ::Val{n}) where {n} = ntuple(i -> f2(thetupl, Val(i)), Val(n))

f3(t::Tuple, ::Val{i}) where {i} = t[i]
f3(t::Tuple, i::Int) = t[i]
g3(thetupl::Tuple, ::Val{n}) where {n} = ntuple(i -> f3(thetupl, i), Val(n))
g4(thetupl::Tuple, ::Val{n}) where {n} = ntuple(i -> f3(thetupl, Val(i)), Val(n))

f5(t::Tuple, i::Int) = f2(t::Tuple, Val(i))
g5(thetupl::Tuple, ::Val{n}) where {n} = ntuple(i -> f5(thetupl, i), Val(n))

All the versions of g are type-stable (in theory). However f1, f3, f5 are potentially type-unstable because their output types can depend on the value of i, when the tuple t has items of heterogeneous types.

To experiment, I created an heterogeneous tuple:

julia> thetupl = ntuple(i -> rand((rand(1:10), rand("da;glaergerf"), "afdsa", rand(Bool), randn())), 20)
("afdsa", false, false, "afdsa", "afdsa", true, 9, false, 4, false, 'l', 'l', 'e', false, 0.21198045684894534, -0.9550998919808197, 'f', false, "afdsa", "afdsa")

Then I inspected the type-stability of the different versions of g as inferred by Julia, using @inferred g1(thetupl, Val(5)), and so on for the other variations of g. Turns out that g1, g3 are seen as type-stable by Julia, while g2, g4, g5 are not! I was surprised by this, and would like to understand why.

I actually have some slightly more complicated code with a related issue, so I am trying to understand what is the best way to deal with these “spurious” type instabilities inside type-stable functions.

In case this depends on compiler internals that might change with version, I am using Julia 1.3.1 here.