In go/types/selection.go, the intended significance of the Indirect flag (for MethodVal)
is hard to tell from the example. I was assuming that is means whether there are any
pointer indirections between the type of the receiver and the declared type of the
method, but that doesn't seem to explain it:
I instrumented recordSelection:
% cat sel.go
package main
type T struct {}
func (T)f() {}
func (*T)g() {}
func main() {
var x T
x.f()
x.g()
var p *T
p.f()
p.g()
}
% ./ssadump sel.go
sel.go:11:2: SEL method (main.T) f() indirect=false
sel.go:12:2: SEL method (main.T) g() indirect=false
sel.go:15:2: SEL method (*main.T) f() indirect=true
sel.go:16:2: SEL method (*main.T) g() indirect=true
In the last selection, there is no actual indirection between the receiver type *T and
the method type *T, yet the indirect flag is reported as true. (The indirect flag seems
to record only the pointerness of the receiver, which is redundant information.)
I think, by analogy with field selections, the indirect bit should be set iff there was
an implicit pointer indirection between the actual receiver type and the formal receiver
type, e.g a (T) method was called with an expression of type (*T), or in this example:
type A struct {}
func (*A) f() {}
type B struct {*A}
... B{}.f() // indirect, since method (*A).f
An (A) method is called with an expression of type B.
In go/types/selection.go, the intended significance of the Indirect flag (for MethodVal) is hard to tell from the example. I was assuming that is means whether there are any pointer indirections between the type of the receiver and the declared type of the method, but that doesn't seem to explain it: I instrumented recordSelection: % cat sel.go package main type T struct {} func (T)f() {} func (*T)g() {} func main() { var x T x.f() x.g() var p *T p.f() p.g() } % ./ssadump sel.go sel.go:11:2: SEL method (main.T) f() indirect=false sel.go:12:2: SEL method (main.T) g() indirect=false sel.go:15:2: SEL method (*main.T) f() indirect=true sel.go:16:2: SEL method (*main.T) g() indirect=true In the last selection, there is no actual indirection between the receiver type *T and the method type *T, yet the indirect flag is reported as true. (The indirect flag seems to record only the pointerness of the receiver, which is redundant information.) I think, by analogy with field selections, the indirect bit should be set iff there was an implicit pointer indirection between the actual receiver type and the formal receiver type, e.g a (T) method was called with an expression of type (*T), or in this example: type A struct {} func (*A) f() {} type B struct {*A} ... B{}.f() // indirect, since method (*A).f An (A) method is called with an expression of type B.