Is this function type unstable?

Hi,

could you please try to help understand why this minimal working example does not return an object of concrete type?

using DifferentialEquations

function f(du,u,p,t)  
  du[1] = p.a
  du[2] = p.b
end

function solve_ode(f::F, p::P) where {F,P}

  tspan = (0., 1.0)
  Δt = tspan[2] - tspan[1]
  dt = 1/252
  nodes = Int(ceil(Δt / dt) + 1)
  t = T = [tspan[1] + (i - 1) * dt for i = 1:nodes]

  # if I do not set {true}, prob type is Any...
  prob = ODEProblem{true}(f, [0., 0.], tspan, p)
  # prob = ODEProblem(f, [0., 0.], tspan, p)

  prob_func = (prob, i, repeat) -> begin
    remake(prob, tspan = (T[i + 1], t[1]))
  end

  # ensemble problem
  odes = EnsembleProblem(prob, prob_func = prob_func)

  sol = DifferentialEquations.solve(
    odes, Tsit5(), EnsembleThreads(), trajectories = nodes - 1, saveat = -dt
  )

  return sol
end

When running the following:

@code_warntype solve_ode(f, (a = 1, b = 1))
Variables
  #self#::Core.Compiler.Const(solve_ode, false)
  f::Core.Compiler.Const(f, false)
  p::NamedTuple{(:a, :b),Tuple{Int64,Int64}}
  #25::var"#25#27"{Tuple{Float64,Float64},Float64}
  #26::var"#26#28"{Array{Float64,1},Array{Float64,1}}
  tspan::Tuple{Float64,Float64}
  Δt::Float64
  dt::Float64
  nodes::Int64
  T::Array{Float64,1}
  t::Array{Float64,1}
  prob::ODEProblem{Array{Float64,1},Tuple{Float64,Float64},true,NamedTuple{(:a, :b),Tuple{Int64,Int64}},ODEFunction{true,typeof(f),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem}
  prob_func::var"#26#28"{Array{Float64,1},Array{Float64,1}}
  odes::EnsembleProblem{ODEProblem{Array{Float64,1},Tuple{Float64,Float64},true,NamedTuple{(:a, :b),Tuple{Int64,Int64}},ODEFunction{true,typeof(f),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem},var"#26#28"{Array{Float64,1},Array{Float64,1}},DiffEqBase.var"#342#348",DiffEqBase.var"#344#350",Array{Any,1}}
  sol::EnsembleSolution{_A,_B,_C} where _C where _B where _A

Body::EnsembleSolution{_A,_B,_C} where _C where _B where _A
1 ─       (tspan = Core.tuple(0.0, 1.0))
│   %2  = Base.getindex(tspan::Core.Compiler.Const((0.0, 1.0), false), 2)::Core.Compiler.Const(1.0, false)
│   %3  = Base.getindex(tspan::Core.Compiler.Const((0.0, 1.0), false), 1)::Core.Compiler.Const(0.0, false)
│         (Δt = %2 - %3)
│         (dt = 1 / 252)
│   %6  = (Δt::Core.Compiler.Const(1.0, false) / dt::Core.Compiler.Const(0.003968253968253968, false))::Core.Compiler.Const(252.0, false)
│   %7  = Main.ceil(%6)::Core.Compiler.Const(252.0, false)
│   %8  = (%7 + 1)::Core.Compiler.Const(253.0, false)
│         (nodes = Main.Int(%8))
│   %10 = Main.:(var"#25#27")::Core.Compiler.Const(var"#25#27", false)
│   %11 = Core.typeof(tspan::Core.Compiler.Const((0.0, 1.0), false))::Core.Compiler.Const(Tuple{Float64,Float64}, false)
│   %12 = Core.typeof(dt::Core.Compiler.Const(0.003968253968253968, false))::Core.Compiler.Const(Float64, false)
│   %13 = Core.apply_type(%10, %11, %12)::Core.Compiler.Const(var"#25#27"{Tuple{Float64,Float64},Float64}, false)
│   %14 = tspan::Core.Compiler.Const((0.0, 1.0), false)::Core.Compiler.Const((0.0, 1.0), false)
│         (#25 = %new(%13, %14, dt::Core.Compiler.Const(0.003968253968253968, false)))
│   %16 = #25::Core.Compiler.Const(var"#25#27"{Tuple{Float64,Float64},Float64}((0.0, 1.0), 0.003968253968253968), false)::Core.Compiler.Const(var"#25#27"{Tuple{Float64,Float64},Float64}((0.0, 1.0), 0.003968253968253968), false)
│   %17 = (1:nodes::Core.Compiler.Const(253, false))::Core.Compiler.Const(1:253, false)
│   %18 = Base.Generator(%16, %17)::Core.Compiler.Const(Base.Generator{UnitRange{Int64},var"#25#27"{Tuple{Float64,Float64},Float64}}(var"#25#27"{Tuple{Float64,Float64},Float64}((0.0, 1.0), 0.003968253968253968), 1:253), false)
│   %19 = Base.collect(%18)::Array{Float64,1}
│         (T = %19)
│         (t = %19)
│   %22 = Core.apply_type(Main.ODEProblem, true)::Core.Compiler.Const(ODEProblem{true,tType,isinplace,P,F,K,PT} where PT where K where F where P where isinplace where tType, false)
│   %23 = Base.vect(0.0, 0.0)::Array{Float64,1}
│   %24 = tspan::Core.Compiler.Const((0.0, 1.0), false)::Core.Compiler.Const((0.0, 1.0), false)
│         (prob = (%22)(f, %23, %24, p))
│   %26 = Main.:(var"#26#28")::Core.Compiler.Const(var"#26#28", false)
│   %27 = Core.typeof(T)::Core.Compiler.Const(Array{Float64,1}, false)
│   %28 = Core.typeof(t)::Core.Compiler.Const(Array{Float64,1}, false)
│   %29 = Core.apply_type(%26, %27, %28)::Core.Compiler.Const(var"#26#28"{Array{Float64,1},Array{Float64,1}}, false)
│   %30 = T::Array{Float64,1}
│         (#26 = %new(%29, %30, t))
│         (prob_func = #26)
│   %33 = (:prob_func,)::Core.Compiler.Const((:prob_func,), false)
│   %34 = Core.apply_type(Core.NamedTuple, %33)::Core.Compiler.Const(NamedTuple{(:prob_func,),T} where T<:Tuple, false)
│   %35 = Core.tuple(prob_func)::Tuple{var"#26#28"{Array{Float64,1},Array{Float64,1}}}
│   %36 = (%34)(%35)::NamedTuple{(:prob_func,),Tuple{var"#26#28"{Array{Float64,1},Array{Float64,1}}}}
│   %37 = Core.kwfunc(Main.EnsembleProblem)::Core.Compiler.Const(Core.var"#Type##kw"(), false)
│         (odes = (%37)(%36, Main.EnsembleProblem, prob::Core.Compiler.PartialStruct(ODEProblem{Array{Float64,1},Tuple{Float64,Float64},true,NamedTuple{(:a, :b),Tuple{Int64,Int64}},ODEFunction{true,typeof(f),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem}, Any[Core.Compiler.Const(ODEFunction{true,typeof(f),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing}(f, LinearAlgebra.UniformScaling{Bool}(true), nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing), false), Array{Float64,1}, Core.Compiler.Const((0.0, 1.0), false), NamedTuple{(:a, :b),Tuple{Int64,Int64}}, Core.Compiler.Const(Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}(), false), Core.Compiler.Const(DiffEqBase.StandardODEProblem(), false)])))
│   %39 = Main.Tsit5()::Core.Compiler.Const(Tsit5(), false)
│   %40 = Main.EnsembleThreads()::Core.Compiler.Const(EnsembleThreads(), false)
│   %41 = (nodes::Core.Compiler.Const(253, false) - 1)::Core.Compiler.Const(252, false)
│   %42 = -dt::Core.Compiler.Const(0.003968253968253968, false)::Core.Compiler.Const(-0.003968253968253968, false)
│   %43 = (:trajectories, :saveat)::Core.Compiler.Const((:trajectories, :saveat), false)
│   %44 = Core.apply_type(Core.NamedTuple, %43)::Core.Compiler.Const(NamedTuple{(:trajectories, :saveat),T} where T<:Tuple, false)
│   %45 = Core.tuple(%41, %42)::Core.Compiler.Const((252, -0.003968253968253968), false)
│   %46 = (%44)(%45)::NamedTuple{(:trajectories, :saveat),Tuple{Int64,Float64}}
│   %47 = DifferentialEquations.solve::Core.Compiler.Const(DiffEqBase.solve, false)
│   %48 = Core.kwfunc(%47)::Core.Compiler.Const(DiffEqBase.var"#solve##kw"(), false)
│   %49 = DifferentialEquations.solve::Core.Compiler.Const(DiffEqBase.solve, false)
│   %50 = odes::Core.Compiler.PartialStruct(EnsembleProblem{ODEProblem{Array{Float64,1},Tuple{Float64,Float64},true,NamedTuple{(:a, :b),Tuple{Int64,Int64}},ODEFunction{true,typeof(f),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem},var"#26#28"{Array{Float64,1},Array{Float64,1}},DiffEqBase.var"#342#348",DiffEqBase.var"#344#350",Array{Any,1}}, Any[Core.Compiler.PartialStruct(ODEProblem{Array{Float64,1},Tuple{Float64,Float64},true,NamedTuple{(:a, :b),Tuple{Int64,Int64}},ODEFunction{true,typeof(f),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem}, Any[Core.Compiler.Const(ODEFunction{true,typeof(f),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing}(f, LinearAlgebra.UniformScaling{Bool}(true), nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing), false), Array{Float64,1}, Core.Compiler.Const((0.0, 1.0), false), NamedTuple{(:a, :b),Tuple{Int64,Int64}}, Core.Compiler.Const(Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}(), false), Core.Compiler.Const(DiffEqBase.StandardODEProblem(), false)]), var"#26#28"{Array{Float64,1},Array{Float64,1}}, Core.Compiler.Const(DiffEqBase.var"#342#348"(), false), Core.Compiler.Const(DiffEqBase.var"#344#350"(), false), Array{Any,1}])::Core.Compiler.PartialStruct(EnsembleProblem{ODEProblem{Array{Float64,1},Tuple{Float64,Float64},true,NamedTuple{(:a, :b),Tuple{Int64,Int64}},ODEFunction{true,typeof(f),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem},var"#26#28"{Array{Float64,1},Array{Float64,1}},DiffEqBase.var"#342#348",DiffEqBase.var"#344#350",Array{Any,1}}, Any[Core.Compiler.PartialStruct(ODEProblem{Array{Float64,1},Tuple{Float64,Float64},true,NamedTuple{(:a, :b),Tuple{Int64,Int64}},ODEFunction{true,typeof(f),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},DiffEqBase.StandardODEProblem}, Any[Core.Compiler.Const(ODEFunction{true,typeof(f),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing}(f, LinearAlgebra.UniformScaling{Bool}(true), nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing), false), Array{Float64,1}, Core.Compiler.Const((0.0, 1.0), false), NamedTuple{(:a, :b),Tuple{Int64,Int64}}, Core.Compiler.Const(Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}(), false), Core.Compiler.Const(DiffEqBase.StandardODEProblem(), false)]), var"#26#28"{Array{Float64,1},Array{Float64,1}}, Core.Compiler.Const(DiffEqBase.var"#342#348"(), false), Core.Compiler.Const(DiffEqBase.var"#344#350"(), false), Array{Any,1}])
│         (sol = (%48)(%46, %49, %50, %39, %40))
└──       return sol

the returned value type is not concrete. Or there is something I am not understanding?

Thanks!