mirror of
https://github.com/golang/go
synced 2024-11-19 07:04:43 -07:00
4da31df1c8
We now use LookupFieldOrMethod for all SelectorExprs, and simplify the logic to discriminate the various cases. We inline static calls to promoted/indirected functions, dramatically reducing the number of functions created. More tests are needed, but I'd like to submit this as-is. In this CL, we: - rely less on Id strings. Internally we now use *types.Method (and its components) almost everywhere. - stop thinking of types.Methods as objects. They don't have stable identities. (Hopefully they will become plain-old structs soon.) - eliminate receiver indirection wrappers: indirection and promotion are handled together by makeWrapper. - Handle the interactions of promotion, indirection and abstract methods much more cleanly. - support receiver-bound interface method closures. - break up builder.selectField so we can re-use parts (emitFieldSelection). - add importer.PackageInfo.classifySelector utility. - delete interfaceMethodIndex() - delete namedTypeMethodIndex() - delete isSuperInterface() (replaced by types.IsAssignable) - call memberFromObject on each declared concrete method's *types.Func, not on every Method frem each method set, in the CREATE phase for packages loaded by gcimporter. go/types: - document Func, Signature.Recv() better. - use fmt in {Package,Label}.String - reimplement Func.String to be prettier and to include method receivers. API changes: - Function.method now holds the types.Method (soon to be not-an-object) for synthetic wrappers. - CallCommon.Method now contains an abstract (interface) method object; was an abstract method index. - CallCommon.MethodId() gone. - Program.LookupMethod now takes a *Method not an Id string. R=gri CC=golang-dev https://golang.org/cl/11674043
59 lines
855 B
Go
59 lines
855 B
Go
package main
|
|
|
|
// Test of promotion of methods of an interface embedded within a
|
|
// struct. In particular, this test excercises that the correct
|
|
// method is called.
|
|
|
|
type I interface {
|
|
one() int
|
|
two() string
|
|
}
|
|
|
|
type S struct {
|
|
I
|
|
}
|
|
|
|
type impl struct{}
|
|
|
|
func (impl) one() int {
|
|
return 1
|
|
}
|
|
|
|
func (impl) two() string {
|
|
return "two"
|
|
}
|
|
|
|
func main() {
|
|
var s S
|
|
s.I = impl{}
|
|
if one := s.I.one(); one != 1 {
|
|
panic(one)
|
|
}
|
|
if one := s.one(); one != 1 {
|
|
panic(one)
|
|
}
|
|
closOne := s.I.one
|
|
if one := closOne(); one != 1 {
|
|
panic(one)
|
|
}
|
|
closOne = s.one
|
|
if one := closOne(); one != 1 {
|
|
panic(one)
|
|
}
|
|
|
|
if two := s.I.two(); two != "two" {
|
|
panic(two)
|
|
}
|
|
if two := s.two(); two != "two" {
|
|
panic(two)
|
|
}
|
|
closTwo := s.I.two
|
|
if two := closTwo(); two != "two" {
|
|
panic(two)
|
|
}
|
|
closTwo = s.two
|
|
if two := closTwo(); two != "two" {
|
|
panic(two)
|
|
}
|
|
}
|