aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2022-08-18 15:16:23 -0700
committerMatthew Dempsky <mdempsky@google.com>2022-08-23 18:13:48 +0000
commitaa6a7fa775d8f38225ad74a622187bbe891eaf1c (patch)
tree9e161c751f4e112e3d15b6d4cb3acf2776b1686d /src/cmd/compile/internal/noder
parent72a76ca1f9c195ed39e929cf768d5df5421eada1 (diff)
downloadgo-aa6a7fa775d8f38225ad74a622187bbe891eaf1c.tar.xz
cmd/compile: fix reflect naming of local generic types
To disambiguate local types, we append a "·N" suffix to their name and then trim it off again when producing their runtime type descriptors. However, if a local type is generic, then we were further appending the type arguments after this suffix, and the code in types/fmt.go responsible for trimming didn't know to handle this. We could extend the types/fmt.go code to look for the "·N" suffix elsewhere in the type name, but this is risky because it could legitimately (albeit unlikely) appear in struct field tags. Instead, the most robust solution is to just change the mangling logic to keep the "·N" suffix at the end, where types/fmt.go can easily and reliably trim it. Note: the "·N" suffix is still visible within the type arguments list (e.g., the "·3" suffixes in nested.out), because we currently use the link strings in the type arguments list. Fixes #54456. Change-Id: Ie9beaf7e5330982f539bff57b8d48868a3674a37 Reviewed-on: https://go-review.googlesource.com/c/go/+/424901 TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Than McIntosh <thanm@google.com>
Diffstat (limited to 'src/cmd/compile/internal/noder')
-rw-r--r--src/cmd/compile/internal/noder/reader.go8
-rw-r--r--src/cmd/compile/internal/noder/writer.go7
2 files changed, 12 insertions, 3 deletions
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go
index 1acc8c7fb6..5f770166db 100644
--- a/src/cmd/compile/internal/noder/reader.go
+++ b/src/cmd/compile/internal/noder/reader.go
@@ -777,8 +777,13 @@ func (dict *readerDict) mangle(sym *types.Sym) *types.Sym {
return sym
}
+ // 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)
+
var buf strings.Builder
- buf.WriteString(sym.Name)
+ buf.WriteString(base)
buf.WriteByte('[')
for i, targ := range dict.targs {
if i > 0 {
@@ -791,6 +796,7 @@ func (dict *readerDict) mangle(sym *types.Sym) *types.Sym {
buf.WriteString(targ.LinkString())
}
buf.WriteByte(']')
+ buf.WriteString(suffix)
return sym.Pkg.Lookup(buf.String())
}
diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go
index d9cd1cbd32..c2c3567220 100644
--- a/src/cmd/compile/internal/noder/writer.go
+++ b/src/cmd/compile/internal/noder/writer.go
@@ -933,8 +933,11 @@ func (w *writer) qualifiedIdent(obj types2.Object) {
decl, ok := w.p.typDecls[obj.(*types2.TypeName)]
assert(ok)
if decl.gen != 0 {
- // TODO(mdempsky): Find a better solution than embedding middle
- // dot in the symbol name; this is terrible.
+ // For local defined types, we embed a scope-disambiguation
+ // number directly into their name. types.SplitVargenSuffix then
+ // knows to look for this.
+ //
+ // TODO(mdempsky): Find a better solution; this is terrible.
name = fmt.Sprintf("%s·%v", name, decl.gen)
}
}