Any way to make this one-liner type stable?

I’ve got this function which widens each of the arguments of a Tuple type

widen_tupleargs(::Type{T}) where {T<:Tuple} = Tuple{map(widen,T.parameters)...}

e.g.

julia> widen_tupleargs(Tuple{Int16,Float16})
Tuple{Int32,Float32}

However, its not type-stable,

julia> @code_warntype widen_tupleargs(Tuple{Int16,Float16})
Variables:
  #self# <optimized out>
  #unused# <optimized out>

Body:
  begin 
      return (Core._apply)(Core.apply_type, (Core.tuple)(Main.Tuple)::Tuple{DataType}, $(Expr(:invoke, MethodInstance for map(::Base.#widen, ::SimpleVector), :(Main.map), :(Main.widen), :((Core.getfield)($(Expr(:static_parameter, 1)), :parameters)::SimpleVector))))::Any
  end::Any

Is there any way to write this so that it is type stable? I’d be curious on either 0.6 or 0.7 (above output was 0.6). Thanks for any help!

You could try something like this, with head and tail (the versions for tuple type):

widen_tupleargs(::Type{Tuple{}}) = Tuple{}
widen_tupleargs(::Type{T}) where {T<:Tuple} =  Base.tuple_type_cons(widen(Base.tuple_type_head(T)), widen_tupleargs(Base.tuple_type_tail(T)))

This is for Julia 0.6, I didn’t check if it changed in 0.7

Awesome, Base.tuple_type_head/tail is exactly what I was looking for, thanks! I just checked on 0.7 and it works exactly the same.