Hi there,
I have a piece of code that is sometimes type-stable, sometimes not, and can’t understand why… I’ve been scratching my head on this for a while, a fresh look would be very much appreciated…
I’ve boiled it down to the following MWE: given
- 
args: a tuple that containsInts or<:AbstractVector{Int};
- 
inds: a tuple that also contains onlyInts or<:AbstractVector{Int}, whose length that matches the number of<:AbstractVector{Int}elements ofargs.
The following code should apply getindex to each non-Int element of args with the corresponding inds.
using Base: tail, OneTo
getindices(res, ::Tuple{}, ::Tuple{}) = res
getindices(res, args::Tuple{Int,Vararg}, inds) =
    getindices((res..., first(args)), tail(args), inds)
getindices(res, args::Tuple{AbstractVector{Int},Vararg}, inds) =
    getindices((res..., getindex(first(args), first(inds))), tail(args), tail(inds))
Sometimes it’s type stable
julia> args = (1, 2, OneTo(3), 4:5);
julia> inds = (2:3, 1);
julia> @code_warntype getindices((), args, inds)
MethodInstance for getindices(::Tuple{}, ::Tuple{Int64, Int64, OneTo{Int64}, UnitRange{Int64}}, ::Tuple{UnitRange{Int64}, Int64})
  from getindices(res, args::Tuple{Int64, Vararg}, inds) @ Main ~/.julia/dev/minimal.jl:5
Arguments
  #self#::Core.Const(getindices)
  res::Core.Const(())
  args::Tuple{Int64, Int64, OneTo{Int64}, UnitRange{Int64}}
  inds::Tuple{UnitRange{Int64}, Int64}
Body::Tuple{Int64, Int64, UnitRange{Int64}, Int64}
1 ─ %1 = Main.first(args)::Int64
│   %2 = Core.tuple(%1)::Tuple{Int64}
│   %3 = Core._apply_iterate(Base.iterate, Core.tuple, res, %2)::Tuple{Int64}
│   %4 = Main.tail(args)::Tuple{Int64, OneTo{Int64}, UnitRange{Int64}}
│   %5 = Main.getindices(%3, %4, inds)::Tuple{Int64, Int64, UnitRange{Int64}, Int64}
└──      return %5
args = (1, 2, 3, OneTo(5), -1, OneTo(6))
inds = (1, 2)
But other times it’s not
julia> args = (1, 2, 3, OneTo(5), -1, OneTo(6));
julia> inds = (1, 2:3);
julia> @code_warntype getindices((), args, inds)
MethodInstance for getindices(::Tuple{}, ::Tuple{Int64, Int64, Int64, OneTo{Int64}, Int64, OneTo{Int64}}, ::Tuple{Int64, UnitRange{Int64}})
  from getindices(res, args::Tuple{Int64, Vararg}, inds) @ Main ~/.julia/dev/ProductSandbox/minimal.jl:5
Arguments
  #self#::Core.Const(getindices)
  res::Core.Const(())
  args::Tuple{Int64, Int64, Int64, OneTo{Int64}, Int64, OneTo{Int64}}
  inds::Tuple{Int64, UnitRange{Int64}}
Body::Tuple
1 ─ %1 = Main.first(args)::Int64
│   %2 = Core.tuple(%1)::Tuple{Int64}
│   %3 = Core._apply_iterate(Base.iterate, Core.tuple, res, %2)::Tuple{Int64}
│   %4 = Main.tail(args)::Tuple{Int64, Int64, OneTo{Int64}, Int64, OneTo{Int64}}
│   %5 = Main.getindices(%3, %4, inds)::Tuple
└──      return %5
I’ve tried different versions of Julia (include 1.9.0-beta2), the results are the same… Thanks in advance for any tip to help me solve this!
 )
 )