diff options
Diffstat (limited to 'src/cmd/compile/internal/noder/reader.go')
| -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()) } |
