I’m trying to understand type stability when accessing composite types.
Consider the custom datatype:
struct MyStruct
a::Int
b::Number
c::AbstractDict
end
I create an instance,
obj = MyStruct(1, 2.0, Dict())
Running @code_warntype on obj.a shows that getproperty is not type stable:
julia> @code_warntype obj.a
MethodInstance for getproperty(::MyStruct, ::Symbol)
from getproperty(x, f::Symbol) in Base at Base.jl:38
Arguments
#self#::Core.Const(getproperty)
x::MyStruct
f::Symbol
Body::Any
1 ─ nothing
│ %2 = Base.getfield(x, f)::Any
└── return %2
of course, ::Any is highlighted in red in the REPL.
Next, if I try @code_warntype on getfield, I get this:
julia> @code_warntype getfield(obj, :a)
getfield(...) in Core
failed to infer
When passing such objects as arguments to functions which access their properties, obviously the type instability is resolved somehow when the function attempts to access obj.a. For example,
julia> function g(x) x.a+1 end
julia> @code_warntype g(obj)
MethodInstance for g(::MyStruct)
from g(x) in Main at REPL[9]:1
Arguments
#self#::Core.Const(g)
x::MyStruct
Body::Int64
1 ─ %1 = Base.getproperty(x, :a)::Int64
│ %2 = (%1 + 1)::Int64
└── return %2
What’s happening here? I’ve tried to look for applicable definitions of getproperty and getfield to see how the type instability is resolved, but so far I couldn’t seem to find them.
Thanks~