From 5337e53dfa3f5fde73b8f505ec3a91c628e8f648 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Fri, 12 Nov 2021 12:38:29 -0800 Subject: [PATCH] cmd/compile: ensure we replace package placeholder in type names We want package names exposed by reflect to be things like main.F[main.foo], not main.F["".foo]. Fixes #49547 Change-Id: I182411a75d56ce1f64fde847e5b9ee74ce44e00b Reviewed-on: https://go-review.googlesource.com/c/go/+/363656 Trust: Keith Randall Trust: Dan Scales Run-TryBot: Keith Randall TryBot-Result: Go Bot Reviewed-by: Dan Scales --- src/cmd/compile/internal/types/fmt.go | 8 +++++++- test/typeparam/issue49547.go | 22 ++++++++++++++++++++++ test/typeparam/nested.out | 6 +++--- 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 test/typeparam/issue49547.go diff --git a/src/cmd/compile/internal/types/fmt.go b/src/cmd/compile/internal/types/fmt.go index 23fc4221e1..b20d2e2908 100644 --- a/src/cmd/compile/internal/types/fmt.go +++ b/src/cmd/compile/internal/types/fmt.go @@ -140,11 +140,17 @@ func sconv2(b *bytes.Buffer, s *Sym, verb rune, mode fmtMode) { } func symfmt(b *bytes.Buffer, s *Sym, verb rune, mode fmtMode) { + name := s.Name if q := pkgqual(s.Pkg, verb, mode); q != "" { b.WriteString(q) b.WriteByte('.') + if mode == fmtTypeIDName { + // If name is a generic instantiation, it might have local package placeholders + // in it. Replace those placeholders with the package name. See issue 49547. + name = strings.Replace(name, LocalPkg.Prefix, q, -1) + } } - b.WriteString(s.Name) + b.WriteString(name) } // pkgqual returns the qualifier that should be used for printing diff --git a/test/typeparam/issue49547.go b/test/typeparam/issue49547.go new file mode 100644 index 0000000000..99c124d7ab --- /dev/null +++ b/test/typeparam/issue49547.go @@ -0,0 +1,22 @@ +// run -gcflags=-G=3 + +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "fmt" + +type foo int + +func main() { + want := "main.F[main.foo]" + got := fmt.Sprintf("%T", F[foo]{}) + if got != want { + fmt.Printf("want: %s, got: %s\n", want, got) + } +} + +type F[T any] struct { +} diff --git a/test/typeparam/nested.out b/test/typeparam/nested.out index 9110518248..37cb762e32 100644 --- a/test/typeparam/nested.out +++ b/test/typeparam/nested.out @@ -1,4 +1,4 @@ 0,3: main.T·2[int;int] -4,7: main.T·2[int;"".U·3[int;int]] -22,23: main.T·2["".Int;"".Int] -26,27: main.T·2["".Int;"".U·3["".Int;"".Int]] +4,7: main.T·2[int;main.U·3[int;int]] +22,23: main.T·2[main.Int;main.Int] +26,27: main.T·2[main.Int;main.U·3[main.Int;main.Int]]