It’s not showing the result of constant propagation because that’s not how @code_warntype
works - it can’t propagate constants from the top level. This:
is equivalent to
@code_warntype getproperty(obj, :a)
which is the same as
InteractiveUtils.code_warntype(getproperty, (Base.typesof)(obj, :a))
which ultimately is
InteractiveUtils.code_warntype(getproperty, Tuple{MyStruct, Symbol})
So there’s no Symbol
object to propagate because code_warntype
only cares about the input types, not their values. Not even obj
survives. For inspecting what syntax transforms macros perform, @macroexpand
is very useful.
If you use obj.a
in a function, the :a
is of course again a constant inside a call, which is propagated. Just as can be observed in the g(x)
example.
Both getproperty
and getfield
rely on constant propagation of the input symbol to be type stable. Using them in a function, where the accessed fields are hardcoded, allows them to be propagated as constants and thus resolve the field access in a type stable manner.
Further, only getproperty
is configurable. By default it just forwards to getfield
, which is the builtin version that’s typically used when overloading getproperty
for a custom type.
As to why @code_warntype
works this way - it’s intended for figuring out whether or not the function that’s called is type stable, not whether the Expr
that it’s used on is.