diff options
| -rw-r--r-- | src/cmd/compile/internal/noder/reader.go | 35 | ||||
| -rw-r--r-- | src/cmd/compile/internal/noder/writer.go | 13 |
2 files changed, 35 insertions, 13 deletions
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index e0545a86db..e923d81bcd 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -2916,14 +2916,18 @@ func (r *reader) optExpr() ir.Node { // otherwise, they need to create their own wrapper. func (r *reader) methodExpr() (wrapperFn, baseFn, dictPtr ir.Node) { recv := r.typ() - sig0 := r.typ() + + var sig *types.Type + generic := r.Version().Has(pkgbits.GenericMethods) && r.Bool() + if !generic { + // Signature type to return (i.e., recv prepended to the method's + // normal parameters list). + sig = typecheck.NewMethodType(r.typ(), recv) + } + pos := r.pos() sym := r.selector() - // Signature type to return (i.e., recv prepended to the method's - // normal parameters list). - sig := typecheck.NewMethodType(sig0, recv) - if r.Bool() { // type parameter method expression idx := r.Len() word := r.dictWord(pos, r.dict.typeParamMethodExprsOffset()+idx) @@ -2972,13 +2976,20 @@ func (r *reader) methodExpr() (wrapperFn, baseFn, dictPtr ir.Node) { base.FatalfAt(pos, "dict %L, but shaped method %L", dict, shapedFn) } - // For statically known instantiations, we can take advantage of - // the stenciled wrapper. - base.AssertfAt(!recv.HasShape(), pos, "shaped receiver %v", recv) - wrapperFn := typecheck.NewMethodExpr(pos, recv, sym) - base.AssertfAt(types.Identical(sig, wrapperFn.Type()), pos, "wrapper %L does not have type %v", wrapperFn, sig) - - return wrapperFn, shapedFn, dictPtr + if !generic { + // For statically known instantiations, we can take advantage of + // the stenciled wrapper. + base.AssertfAt(!recv.HasShape(), pos, "shaped receiver %v", recv) + wrapperFn := typecheck.NewMethodExpr(pos, recv, sym) + base.AssertfAt(types.Identical(sig, wrapperFn.Type()), pos, "wrapper %L does not have type %v", wrapperFn, sig) + return wrapperFn, shapedFn, dictPtr + } else { + // Also statically known, but there is a good amount of existing + // machinery downstream which makes assumptions about method + // wrapper functions. It's safest not to emit them for now. + // TODO(mark): Emit wrapper functions for generic methods. + return nil, shapedFn, dictPtr + } } // Simple method expression; no dictionary needed. diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go index 5a549ea198..c4c7458a27 100644 --- a/src/cmd/compile/internal/noder/writer.go +++ b/src/cmd/compile/internal/noder/writer.go @@ -2276,7 +2276,18 @@ func (w *writer) methodExpr(expr *syntax.SelectorExpr, recv types2.Type, sel *ty sig := fun.Type().(*types2.Signature) w.typ(recv) - w.typ(sig) + + // only pass the signature if it's not a generic method + if isGenericMethod(sig) { + assert(w.Version().Has(pkgbits.GenericMethods)) + w.Bool(true) + } else { + if w.Version().Has(pkgbits.GenericMethods) { + w.Bool(false) + } + w.typ(sig) + } + w.pos(expr) w.selector(fun) |
