Surprising type inference failure for `map` on mid-size tuples

This surprised me:

using Test  # for Test.@inferred
g(::Val{n}) where {n} = ntuple(i -> one(Rational{BigInt}), Val{n}())  # constructs an example tuple of specified length
map(+, g(Val{30}()), g(Val{30}()));  # warm up
@inferred map(+, g(Val{30}()), g(Val{30}()))  # works fine
map(+, g(Val{40}()), g(Val{40}()));  # warm up
@inferred map(+, g(Val{40}()), g(Val{40}()))  # ERROR: return type NTuple{40, Rational{BigInt}} does not match inferred return type Tuple

I guess that using ntuple instead of map could be a workaround for this type inference issue.

But I’m curious, are there any similar gotchas that I should keep in mind?

Eventually I wrote these functions to fix my type inference issues (they’re an unary and a binary version):

# Like map, but with better type inference.
map_tuple(f::Fun, a::NTuple{len}) where {Fun <: Function, len} =
  ntuple(
    let a = a
      i -> f(a[i])
    end,
    Val{len}())

# Like map, but with better type inference.
map_tuple(f::Fun, a::T, b::T) where {Fun <: Function, len, T <: NTuple{len}} =
  ntuple(
    let a = a, b = b
      i -> f(a[i], b[i])
    end,
    Val{len}())

They work fine, but I wonder if a somewhat generalized version should really be in Julia Base? Pretty sure this is an issue that comes up often, and implementing a solution is out-of-reach for most newcomers.