diff --git a/importer/pkginfo.go b/importer/pkginfo.go index 30d12f575e..7c87b4c8ce 100644 --- a/importer/pkginfo.go +++ b/importer/pkginfo.go @@ -20,7 +20,7 @@ type PackageInfo struct { // Type-checker deductions. types map[ast.Expr]types.Type // inferred types of expressions constants map[ast.Expr]exact.Value // values of constant expressions - idents map[*ast.Ident]types.Object // resoved objects for named entities + idents map[*ast.Ident]types.Object // resolved objects for named entities typecases map[*ast.CaseClause]*types.Var // implicit vars for single-type typecases } @@ -47,6 +47,7 @@ func (info *PackageInfo) TypeOf(e ast.Expr) types.Type { // ValueOf returns the value of expression e if it is a constant, nil // otherwise. +// Precondition: e belongs to the package's ASTs. // func (info *PackageInfo) ValueOf(e ast.Expr) exact.Value { return info.constants[e] diff --git a/ssa/interp/interp_test.go b/ssa/interp/interp_test.go index 909da9254f..5849d41039 100644 --- a/ssa/interp/interp_test.go +++ b/ssa/interp/interp_test.go @@ -132,6 +132,7 @@ var testdataTests = []string{ "coverage.go", "mrvchain.go", "boundmeth.go", + "ifaceprom.go", } func run(t *testing.T, dir, input string) bool { diff --git a/ssa/interp/testdata/ifaceprom.go b/ssa/interp/testdata/ifaceprom.go new file mode 100644 index 0000000000..87298830ec --- /dev/null +++ b/ssa/interp/testdata/ifaceprom.go @@ -0,0 +1,35 @@ +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.one(); one != 1 { + panic(one) + } + if two := s.two(); two != "two" { + panic(two) + } +} diff --git a/ssa/promote.go b/ssa/promote.go index 929e97574e..09f457b91d 100644 --- a/ssa/promote.go +++ b/ssa/promote.go @@ -314,11 +314,15 @@ func makeBridgeMethod(prog *Program, typ types.Type, cand *candidate) *Function c.Call.Func = cand.concrete c.Call.Args = append(c.Call.Args, v) } else { + c.Call.Method = -1 + iface := v.Type().Underlying().(*types.Interface) + for i, n := 0, iface.NumMethods(); i < n; i++ { + if iface.Method(i) == cand.method { + c.Call.Method = i + break + } + } c.Call.Recv = v - // TODO(adonovan): fix: this looks wrong! Need to - // find method index within - // v.Type().Underlying().(*types.Interface).Methods() - c.Call.Method = 0 } for _, arg := range fn.Params[1:] { c.Call.Args = append(c.Call.Args, arg)