aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/compile/internal/noder/reader.go35
-rw-r--r--src/cmd/compile/internal/noder/writer.go13
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)