To elaborate, @code_warntype only sees the types of the arguments to the function call you give it.
The syntax p1.first is just a shorthand for getproperty(p1, :first), so when you do: @code_warntype p1.first, you’re seeing the result of:
which isn’t enough information to indicate whether you’re accessing the first or second element.
Putting the access into a function lets Julia’s usual constant propagation machinery do its work, and @code_warntype can correctly show you that result when you use it on the new function.