cmd/compile/internal/noder: put type args inside parenthesis

For generic methods on generic types that have a pointer receiver,
we have to be careful with the name mangling logic. OMETHEXPR
expects type arguments for the receiver to appear inside the
parenthesis, like (*T[int]).M[int]. We currently close the
parenthesis a bit early, producing (*T)[int].M[int].

This change checks for a closing parenthesis on the symbol name
and avoids writing it until after the type arguments have been
written.

Thank you to nealpatel@google.com for locating this and proposing
a fix in CL 775000.

Fixes #79237
For #77273

Change-Id: If89b6992bc98fbc93ad3a846c714a03ad289ee7b
Reviewed-on: https://go-review.googlesource.com/c/go/+/775220
Auto-Submit: Mark Freeman <markfreeman@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Griesemer <gri@google.com>
This commit is contained in:
Mark Freeman 2026-05-07 10:47:22 -04:00 committed by Gopher Robot
parent 16449179ec
commit 714a94dd31
2 changed files with 18 additions and 0 deletions

View file

@ -905,6 +905,9 @@ func (dict *readerDict) mangle(sym *types.Sym) *types.Sym {
j = len(dict.targs) // consume all type arguments
}
// put type arguments inside parenthesis; (*T)[int] -> (*T[int])
n, ok := strings.CutSuffix(n, ")")
// type arguments, if any
buf.WriteString(n)
if j > 0 {
@ -922,6 +925,10 @@ func (dict *readerDict) mangle(sym *types.Sym) *types.Sym {
buf.WriteByte(']')
}
if ok {
buf.WriteString(")")
}
buf.WriteString(vsuff)
buf.WriteString(msuff)

View file

@ -19,6 +19,17 @@ func (t *T) m[P any]() {
}
}
type G[P any] struct {}
func (g *G[P]) m[Q any]() {
var p P
var q Q
if got := fmt.Sprintf("%T %T", p, q); got != "int bool" {
panic(fmt.Sprintf("got %s, want int bool", got))
}
}
func main() {
(&T{}).m[int]()
(&G[int]{}).m[bool]()
}