My application has a construct equivalent to the following MWE
using Interpolations
struct MyStruct{T<:Real, IT<:AbstractInterpolation{T,1}}
x::Array{T,1}
y::Array{T,1}
itp::IT
end
MyStruct(x::Array{T,1},y::Array{T,1}) where T = MyStruct{T,AbstractInterpolation{T,1}}(x,y,LinearInterpolation(x,y))
x = collect(1.0:50.0)
y = randn(50)
m = MyStruct(x,y)
f(m::MyStruct{T, AbstractInterpolation{T,1}}, x::T) where T<:Real = m.itp(x)
for which calling
@code_warntype f(m,1.0)
gives Any as the return type. Is there some way to rewrite this so that the return type can be correctly inferred as T (i.e. Float64 in this case)?
Proximally, the original struct has two parametric type parameters and I assumed you needed to specify both of them in the constructor. Ultimately, I still don’t have a good grasp of how to use Julia’s parametric type system (rather embarrassingly given the cake symbol I just noticed next to my name)
Ok, that is useful to know. In this case, the constructor is also doing the extra work of doing the interpolation. The thing that confuses me is that if I do @code_warntype m.itp(x), that is fine, but f(m,x) is not even when the type information is present in m; I think this is quite similar to the question from Type instability if function inside a struct is run inside another function , and my original solution was an attempt to emulate the accepted solution from that question
The problem in your example was that there was “bad” type information in m. What was put as IT was AbstractInterpolation which the compiler cannot reason about. What we wanted in there was the concrete type of the interpolation object that we created.