aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder
diff options
context:
space:
mode:
authorMark Freeman <mark@golang.org>2026-03-30 16:03:29 -0400
committerGopher Robot <gobot@golang.org>2026-03-31 16:41:49 -0700
commit9cd372147e0bf75afdb700177b36ef984b533a54 (patch)
tree10c9fd5d2527bb7d7f6ebe685f43945f65734461 /src/cmd/compile/internal/noder
parentfe0850174fadb479ec2e45597e7fb3d555524d04 (diff)
downloadgo-9cd372147e0bf75afdb700177b36ef984b533a54.tar.xz
cmd/compile/internal/noder: mangle method names
Mangling produces shaped qualified identifiers using a dictionary. It's important for determining the stenciled type to use for a given instantiation. Since generic methods have qualified identifiers, they need mangling. Suppose a generic method like T[P].m[Q] and a shaped dictionary like: { implicits: 0 receivers: 1 targs: [go.shape.int, go.shape.int] } This would be shaped to T[go.shape.int].m[go.shape.int]. Change-Id: Idc4c825f77a4e9209da65b5b0acb74b9f845bde7 Reviewed-on: https://go-review.googlesource.com/c/go/+/761340 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Mark Freeman <markfreeman@google.com> Reviewed-by: Robert Griesemer <gri@google.com>
Diffstat (limited to 'src/cmd/compile/internal/noder')
-rw-r--r--src/cmd/compile/internal/noder/reader.go64
1 files changed, 52 insertions, 12 deletions
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go
index 7099806cba..00710775d6 100644
--- a/src/cmd/compile/internal/noder/reader.go
+++ b/src/cmd/compile/internal/noder/reader.go
@@ -198,6 +198,9 @@ type readerDict struct {
// implicits counts how many of types within targs are implicit type
// arguments; the rest are explicit.
implicits int
+ // receivers counts how many of types within targs are receiver type
+ // arguments; they are explicit.
+ receivers int
derived []derivedInfo // reloc index of the derived type's descriptor
derivedTypes []*types.Type // slice of previously computed derived types
@@ -864,31 +867,68 @@ func (pr *pkgReader) objIdxMayFail(idx index, implicits, explicits []*types.Type
}
}
+// mangle shapes the non-shaped symbol sym under the current dictionary.
func (dict *readerDict) mangle(sym *types.Sym) *types.Sym {
if !dict.hasTypeParams() {
return sym
}
+ var buf strings.Builder
// If sym is a locally defined generic type, we need the suffix to
// stay at the end after mangling so that types/fmt.go can strip it
// out again when writing the type's runtime descriptor (#54456).
- base, suffix := types.SplitVargenSuffix(sym.Name)
+ n0, vsuff := types.SplitVargenSuffix(sym.Name)
+ n1, msuff := types.SplitMethSuffix(sym.Name)
- var buf strings.Builder
- buf.WriteString(base)
- buf.WriteByte('[')
- for i, targ := range dict.targs {
- if i > 0 {
- if i == dict.implicits {
- buf.WriteByte(';')
- } else {
+ // Methods are never locally defined.
+ var n string
+ assert(vsuff == "" || msuff == "")
+ if vsuff != "" {
+ n = n0
+ } else {
+ n = n1
+ }
+
+ var j int
+ assert(dict.implicits == 0 || dict.receivers == 0)
+ if msuff != "" {
+ j = dict.receivers // consume receiver type arguments
+ } else {
+ j = len(dict.targs) // consume all type arguments
+ }
+
+ // type arguments, if any
+ buf.WriteString(n)
+ if j > 0 {
+ buf.WriteByte('[')
+ for i := 0; i < j; i++ {
+ if i > 0 {
+ if i == dict.implicits {
+ buf.WriteByte(';')
+ } else {
+ buf.WriteByte(',')
+ }
+ }
+ buf.WriteString(dict.targs[i].LinkString())
+ }
+ buf.WriteByte(']')
+ }
+
+ buf.WriteString(vsuff)
+ buf.WriteString(msuff)
+
+ // method arguments, if any
+ if msuff != "" {
+ buf.WriteByte('[')
+ for i := j; i < len(dict.targs); i++ {
+ if i > j {
buf.WriteByte(',')
}
+ buf.WriteString(dict.targs[i].LinkString())
}
- buf.WriteString(targ.LinkString())
+ buf.WriteByte(']')
}
- buf.WriteByte(']')
- buf.WriteString(suffix)
+
return sym.Pkg.Lookup(buf.String())
}