Question here is on line 21 f.bar() why does it work. If I were to go with the spec
The method set of any other type T consists of all [methods] declared with receiver type T
The method set of the corresponding [pointer type] *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T ).
Then since f is of type T and bar is a receiver method of type *T I would have imagined I would have gotten a compile error. But I didn’t. Seems like the compiler stuck in & behind the scenes and it all worked ! Why will it do that? If it does that there then why doesn’t it do it in line 38, w.bar() and hence not give a compile error? Also seems when the compiler is figuring out the types interface implementation it is going by the spec definition. But when we are calling the method via a value it is doing an extra step. Seems not consistent between the two…I am sure good reason but cant fully understand the reason…
The differences in behavior that you’re seeing are the differences/interactions between concrete and interface types (concrete types being everything other than interfaces).
The compiler can implicitly take the address of a concrete type T to get a *T, so you’re right about line 21 being automatically compiled as (&f).foo()
The compiler does not, however, implicitly take the address of a value when “boxing” the value into an interface value. There you have to be explicit.
I don’t know the reason for this, but I suspect the language designers didn’t see any ambiguity calling pointer method receiver functions on values but didn’t want implicit conversions to interface types. You could write info(&f) and I think that should work.