diff options
| author | Mark Freeman <mark@golang.org> | 2026-03-30 16:03:29 -0400 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2026-03-31 16:41:49 -0700 |
| commit | 9cd372147e0bf75afdb700177b36ef984b533a54 (patch) | |
| tree | 10c9fd5d2527bb7d7f6ebe685f43945f65734461 /src/cmd/compile/internal/noder | |
| parent | fe0850174fadb479ec2e45597e7fb3d555524d04 (diff) | |
| download | go-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.go | 64 |
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()) } |
