From: Robert Griesemer Date: Fri, 19 Feb 2021 02:06:01 +0000 (-0800) Subject: [dev.typeparams] go/types, types2: revert fancy struct printing (fixes x/tools tests) X-Git-Tag: go1.17beta1~1473^2~2 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=dfe0ef961b02916ae8403ced9a9a7c9a9ec19a7e;p=gostls13.git [dev.typeparams] go/types, types2: revert fancy struct printing (fixes x/tools tests) An embedded struct field is embedded by mentioning its type. The fact that the field name may be different and derived from the type doesn't matter for the struct type. Do print the embedded type rather than the derived field name, as we have always done in the past. Remove the fancy new code which was just plain wrong. The struct output printing is only relevant for debugging and test cases. Reverting to the original code (pre-generics) fixes a couple of x/tools tests. Unfortunately, the original code is (also) not correct for embedded type aliases. Adjusted a gccgoimporter test accordingly and filed issue #44410. This is a follow-up on https://golang.org/cl/293961 which addressed the issue only partially and left the incorrect code in place. Change-Id: Icb7a89c12ef7929c221fb1a5792f144f7fcd5855 Reviewed-on: https://go-review.googlesource.com/c/go/+/293962 Trust: Robert Griesemer Run-TryBot: Robert Griesemer TryBot-Result: Go Bot Reviewed-by: Robert Findley --- diff --git a/src/cmd/compile/internal/types2/typestring.go b/src/cmd/compile/internal/types2/typestring.go index 47b2c259e5..af44624d2c 100644 --- a/src/cmd/compile/internal/types2/typestring.go +++ b/src/cmd/compile/internal/types2/typestring.go @@ -126,19 +126,14 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) { if i > 0 { buf.WriteString("; ") } - buf.WriteString(f.name) - if f.embedded { - // emphasize that the embedded field's name - // doesn't match the field's type name - if f.name != embeddedFieldName(f.typ) { - buf.WriteString(" /* = ") - writeType(buf, f.typ, qf, visited) - buf.WriteString(" */") - } - } else { + // This doesn't do the right thing for embedded type + // aliases where we should print the alias name, not + // the aliased type (see issue #44410). + if !f.embedded { + buf.WriteString(f.name) buf.WriteByte(' ') - writeType(buf, f.typ, qf, visited) } + writeType(buf, f.typ, qf, visited) if tag := t.Tag(i); tag != "" { fmt.Fprintf(buf, " %q", tag) } @@ -423,25 +418,6 @@ func writeSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier, visited []T writeTuple(buf, sig.results, false, qf, visited) } -// embeddedFieldName returns an embedded field's name given its type. -// The result is "" if the type doesn't have an embedded field name. -func embeddedFieldName(typ Type) string { - switch t := typ.(type) { - case *Basic: - return t.name - case *Named: - return t.obj.name - case *Pointer: - // *T is ok, but **T is not - if _, ok := t.base.(*Pointer); !ok { - return embeddedFieldName(t.base) - } - case *instance: - return t.base.obj.name - } - return "" // not a (pointer to) a defined type -} - // subscript returns the decimal (utf8) representation of x using subscript digits. func subscript(x uint64) string { const w = len("₀") // all digits 0...9 have the same utf8 width diff --git a/src/go/internal/gccgoimporter/importer_test.go b/src/go/internal/gccgoimporter/importer_test.go index c5b520feb4..b3f39312be 100644 --- a/src/go/internal/gccgoimporter/importer_test.go +++ b/src/go/internal/gccgoimporter/importer_test.go @@ -94,7 +94,7 @@ var importerTests = [...]importerTest{ {pkgpath: "nointerface", name: "I", want: "type I int"}, {pkgpath: "issue29198", name: "FooServer", gccgoVersion: 7, want: "type FooServer struct{FooServer *FooServer; user string; ctx context.Context}"}, {pkgpath: "issue30628", name: "Apple", want: "type Apple struct{hey sync.RWMutex; x int; RQ [517]struct{Count uintptr; NumBytes uintptr; Last uintptr}}"}, - {pkgpath: "issue31540", name: "S", gccgoVersion: 7, want: "type S struct{b int; A2 /* = map[Y]Z */}"}, + {pkgpath: "issue31540", name: "S", gccgoVersion: 7, want: "type S struct{b int; map[Y]Z}"}, // should want "type S struct{b int; A2}" (issue #44410) {pkgpath: "issue34182", name: "T1", want: "type T1 struct{f *T2}"}, {pkgpath: "notinheap", name: "S", want: "type S struct{}"}, } diff --git a/src/go/types/typestring.go b/src/go/types/typestring.go index 6ddba08bdc..4697bd31e6 100644 --- a/src/go/types/typestring.go +++ b/src/go/types/typestring.go @@ -126,26 +126,14 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) { if i > 0 { buf.WriteString("; ") } - // For compatibility with versions < go1.16, qualify the field name - // of embedded fields with the package name. Various tests (such as - // in x/tools/cmd/guru) depend on this output; and x/tools packages - // are run against earlier versions of Go. - if n, _ := f.typ.(*Named); f.embedded && n != nil && n.obj != nil && n.obj.pkg != nil { - writePackage(buf, n.obj.pkg, qf) - } - buf.WriteString(f.name) - if f.embedded { - // emphasize that the embedded field's name - // doesn't match the field's type name - if f.name != embeddedFieldName(f.typ) { - buf.WriteString(" /* = ") - writeType(buf, f.typ, qf, visited) - buf.WriteString(" */") - } - } else { + // This doesn't do the right thing for embedded type + // aliases where we should print the alias name, not + // the aliased type (see issue #44410). + if !f.embedded { + buf.WriteString(f.name) buf.WriteByte(' ') - writeType(buf, f.typ, qf, visited) } + writeType(buf, f.typ, qf, visited) if tag := t.Tag(i); tag != "" { fmt.Fprintf(buf, " %q", tag) } @@ -431,25 +419,6 @@ func writeSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier, visited []T writeTuple(buf, sig.results, false, qf, visited) } -// embeddedFieldName returns an embedded field's name given its type. -// The result is "" if the type doesn't have an embedded field name. -func embeddedFieldName(typ Type) string { - switch t := typ.(type) { - case *Basic: - return t.name - case *Named: - return t.obj.name - case *Pointer: - // *T is ok, but **T is not - if _, ok := t.base.(*Pointer); !ok { - return embeddedFieldName(t.base) - } - case *instance: - return t.base.obj.name - } - return "" // not a (pointer to) a defined type -} - // subscript returns the decimal (utf8) representation of x using subscript digits. func subscript(x uint64) string { const w = len("₀") // all digits 0...9 have the same utf8 width