Getproperty/getfield type instability?

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.

5 Likes