diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/noder/transform.go | 5 | ||||
| -rw-r--r-- | src/cmd/compile/internal/typecheck/subr.go | 12 |
2 files changed, 15 insertions, 2 deletions
diff --git a/src/cmd/compile/internal/noder/transform.go b/src/cmd/compile/internal/noder/transform.go index a084f0b7be..946d335f07 100644 --- a/src/cmd/compile/internal/noder/transform.go +++ b/src/cmd/compile/internal/noder/transform.go @@ -437,7 +437,10 @@ func assignconvfn(n ir.Node, t *types.Type) ir.Node { return n } - op, _ := typecheck.Assignop(n.Type(), t) + op, why := typecheck.Assignop(n.Type(), t) + if op == ir.OXXX { + base.Fatalf("found illegal assignment %+v -> %+v; %s", n.Type(), t, why) + } r := ir.NewConvExpr(base.Pos, op, t, n) r.SetTypecheck(1) diff --git a/src/cmd/compile/internal/typecheck/subr.go b/src/cmd/compile/internal/typecheck/subr.go index e9a9a57126..0e306eaea8 100644 --- a/src/cmd/compile/internal/typecheck/subr.go +++ b/src/cmd/compile/internal/typecheck/subr.go @@ -723,13 +723,23 @@ func ifacelookdot(s *types.Sym, t *types.Type, ignorecase bool) (m *types.Field, return m, followptr } +// implements reports whether t implements the interface iface. t can be +// an interface, a type parameter, or a concrete type. If implements returns +// false, it stores a method of iface that is not implemented in *m. If the +// method name matches but the type is wrong, it additionally stores the type +// of the method (on t) in *samename. func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool { t0 := t if t == nil { return false } - if t.IsInterface() { + if t.IsInterface() || t.IsTypeParam() { + if t.IsTypeParam() { + // A typeparam satisfies an interface if its type bound + // has all the methods of that interface. + t = t.Bound() + } i := 0 tms := t.AllMethods().Slice() for _, im := range iface.AllMethods().Slice() { |
