cmd/compile/internal/types: don't change outer formatting mode when recursing

Change-Id: I2a27c32284c996128a27f61d1587ab4c67f0bd0c
GitHub-Last-Rev: 2f5e1a9b51
GitHub-Pull-Request: golang/go#78951
Reviewed-on: https://go-review.googlesource.com/c/go/+/770641
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
This commit is contained in:
Weixie Cui 2026-04-26 01:30:10 +00:00 committed by Gopher Robot
parent c4a8f71e28
commit 914b632202
2 changed files with 56 additions and 2 deletions

View file

@ -431,10 +431,11 @@ func tconv2(b *bytes.Buffer, t *Type, verb rune, mode fmtMode, visited map[*Type
case IsExported(f.Sym.Name):
sconv2(b, f.Sym, 'S', mode)
default:
smode := mode
if mode != fmtTypeIDName {
mode = fmtTypeID
smode = fmtTypeID
}
sconv2(b, f.Sym, 'v', mode)
sconv2(b, f.Sym, 'v', smode)
}
tconv2(b, f.Type, 'S', mode, visited)
}

View file

@ -5,9 +5,62 @@
package types
import (
"bytes"
"fmt"
"strings"
"testing"
"cmd/internal/src"
)
// testTypeName is a minimal types.Object for NewNamed in tests.
type testTypeName struct {
sym *Sym
}
func (o *testTypeName) Sym() *Sym { return o.sym }
func (o *testTypeName) Pos() src.XPos { return src.NoXPos }
func (o *testTypeName) Type() *Type { return nil }
// If the printer mistakenly switches to fmtTypeID while formatting an
// unexported interface method name, the method's signature is then
// printed in fmtTypeID as well, so package-local names use Pkg.Prefix
// (import path) instead of Pkg.Name. Regression test for that mistake.
func TestFormatInterfaceUnexportedMethodUsesGoModeForSignature(t *testing.T) {
oldLocal := LocalPkg
oldPtr, oldReg, oldMax := PtrSize, RegSize, MaxWidth
t.Cleanup(func() {
LocalPkg = oldLocal
PtrSize, RegSize, MaxWidth = oldPtr, oldReg, oldMax
})
LocalPkg = NewPkg("main", "main")
PtrSize = 8
RegSize = 8
MaxWidth = 1 << 50
lib := NewPkg("example.com/lib", "lib")
namedT := NewNamed(&testTypeName{sym: lib.Lookup("T")})
// Underlying must not rely on Types[…]; InitTypes is not run in this package's tests.
namedT.SetUnderlying(NewStruct(nil))
sig := NewSignature(nil, nil, []*Field{NewField(src.NoXPos, nil, namedT)})
iface := NewInterface([]*Field{NewField(src.NoXPos, LocalPkg.Lookup("unexported"), sig)})
CalcSize(iface) // populate interface method set for printing (expandiface)
var buf bytes.Buffer
fmt.Fprintf(&buf, "%v", iface)
got := buf.String()
// Go syntax should qualify T with the package name, not the linker prefix / path.
const want = "lib.T"
if !strings.Contains(got, want) {
t.Fatalf("formatted type missing %q:\n%s", want, got)
}
// Stale fmtTypeID mode used Prefix ("example.com/lib") instead of Name ("lib").
if strings.Contains(got, "example.com/lib.T") {
t.Fatalf("formatted type should not use import path to qualify T (found example.com/lib.T):\n%s", got)
}
}
func TestSSACompare(t *testing.T) {
a := []*Type{
TypeInvalid,