Skip to content

Commit 72a76ca

Browse files
committed
cmd/compile: restore test/nested.go test cases
When handling a type declaration like: ``` type B A ``` unified IR has been writing out that B's underlying type is A, rather than the underlying type of A. This is a bit awkward to implement and adds complexity to importers, who need to handle resolving the underlying type themselves. But it was necessary to handle when A was declared like: ``` //go:notinheap type A int ``` Because we expected A's not-in-heap'ness to be conferred to B, which required knowing that A was on the path from B to its actual underlying type int. However, since #46731 was accepted, we no longer need to support this case. Instead we can write out B's actual underlying type. One stumbling point though is the existing code for exporting interfaces doesn't work for the underlying type of `comparable`, which is now needed to implement `type C comparable`. As a bit of a hack, we we instead export its underlying type as `interface{ comparable }`. Fixes #54512. Change-Id: I0fb892068d656f1e87bb8ef97da27756051126d5 Reviewed-on: https://go-review.googlesource.com/c/go/+/424854 Run-TryBot: Matthew Dempsky <[email protected]> Reviewed-by: Cuong Manh Le <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: David Chase <[email protected]>
1 parent c94633d commit 72a76ca

File tree

2 files changed

+28
-38
lines changed

2 files changed

+28
-38
lines changed

src/cmd/compile/internal/noder/writer.go

+23-17
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,9 @@ func (pw *pkgWriter) pkgIdx(pkg *types2.Package) pkgbits.Index {
432432
// @@@ Types
433433

434434
var (
435-
anyTypeName = types2.Universe.Lookup("any").(*types2.TypeName)
436-
runeTypeName = types2.Universe.Lookup("rune").(*types2.TypeName)
435+
anyTypeName = types2.Universe.Lookup("any").(*types2.TypeName)
436+
comparableTypeName = types2.Universe.Lookup("comparable").(*types2.TypeName)
437+
runeTypeName = types2.Universe.Lookup("rune").(*types2.TypeName)
437438
)
438439

439440
// typ writes a use of the given type into the bitstream.
@@ -485,7 +486,7 @@ func (pw *pkgWriter) typIdx(typ types2.Type, dict *writerDict) typeInfo {
485486
w.Len(int(kind))
486487

487488
default:
488-
// Handle "byte" and "rune" as references to their TypeName.
489+
// Handle "byte" and "rune" as references to their TypeNames.
489490
obj := types2.Universe.Lookup(typ.Name())
490491
assert(obj.Type() == typ)
491492

@@ -543,6 +544,7 @@ func (pw *pkgWriter) typIdx(typ types2.Type, dict *writerDict) typeInfo {
543544
w.structType(typ)
544545

545546
case *types2.Interface:
547+
// Handle "any" as reference to its TypeName.
546548
if typ == anyTypeName.Type() {
547549
w.Code(pkgbits.TypeNamed)
548550
w.obj(anyTypeName, nil)
@@ -590,6 +592,23 @@ func (w *writer) unionType(typ *types2.Union) {
590592
}
591593

592594
func (w *writer) interfaceType(typ *types2.Interface) {
595+
// If typ has no embedded types but it's not a basic interface, then
596+
// the natural description we write out below will fail to
597+
// reconstruct it.
598+
if typ.NumEmbeddeds() == 0 && !typ.IsMethodSet() {
599+
// Currently, this can only happen for the underlying Interface of
600+
// "comparable", which is needed to handle type declarations like
601+
// "type C comparable".
602+
assert(typ == comparableTypeName.Type().(*types2.Named).Underlying())
603+
604+
// Export as "interface{ comparable }".
605+
w.Len(0) // NumExplicitMethods
606+
w.Len(1) // NumEmbeddeds
607+
w.Bool(false) // IsImplicit
608+
w.typ(comparableTypeName.Type()) // EmbeddedType(0)
609+
return
610+
}
611+
593612
w.Len(typ.NumExplicitMethods())
594613
w.Len(typ.NumEmbeddeds())
595614

@@ -775,9 +794,6 @@ func (w *writer) doObj(wext *writer, obj types2.Object) pkgbits.CodeObj {
775794
return pkgbits.ObjFunc
776795

777796
case *types2.TypeName:
778-
decl, ok := w.p.typDecls[obj]
779-
assert(ok)
780-
781797
if obj.IsAlias() {
782798
w.pos(obj)
783799
w.typ(obj.Type())
@@ -790,7 +806,7 @@ func (w *writer) doObj(wext *writer, obj types2.Object) pkgbits.CodeObj {
790806
w.pos(obj)
791807
w.typeParamNames(named.TypeParams())
792808
wext.typeExt(obj)
793-
w.typExpr(decl.Type)
809+
w.typ(named.Underlying())
794810

795811
w.Len(named.NumMethods())
796812
for i := 0; i < named.NumMethods(); i++ {
@@ -807,16 +823,6 @@ func (w *writer) doObj(wext *writer, obj types2.Object) pkgbits.CodeObj {
807823
}
808824
}
809825

810-
// typExpr writes the type represented by the given expression.
811-
//
812-
// TODO(mdempsky): Document how this differs from exprType.
813-
func (w *writer) typExpr(expr syntax.Expr) {
814-
tv, ok := w.p.info.Types[expr]
815-
assert(ok)
816-
assert(tv.IsType())
817-
w.typ(tv.Type)
818-
}
819-
820826
// objDict writes the dictionary needed for reading the given object.
821827
func (w *writer) objDict(obj types2.Object, dict *writerDict) {
822828
// TODO(mdempsky): Split objDict into multiple entries? reader.go

test/typeparam/nested.go

+5-21
Original file line numberDiff line numberDiff line change
@@ -104,27 +104,11 @@ func main() {
104104
F[V]()
105105
F[W]()
106106

107-
// TODO(go.dev/issue/54512): Restore these tests. They currently
108-
// cause problems for shaping with unified IR.
109-
//
110-
// For example, instantiating X[int] requires instantiating shape
111-
// type X[shapify(int)] == X[go.shape.int]. In turn, this requires
112-
// instantiating U[shapify(X[go.shape.int])]. But we're still in the
113-
// process of constructing X[go.shape.int], so we don't yet know its
114-
// underlying type.
115-
//
116-
// Notably, this is a consequence of unified IR writing out type
117-
// declarations with a reference to the full RHS expression (i.e.,
118-
// U[X[A]]) rather than its underlying type (i.e., int), which is
119-
// necessary to support //go:notinheap. Once go.dev/issue/46731 is
120-
// implemented and unified IR is updated, I expect this will just
121-
// work.
122-
//
123-
// type X[A any] U[X[A]]
124-
//
125-
// F[X[int]]()
126-
// F[X[Int]]()
127-
// F[X[GlobalInt]]()
107+
type X[A any] U[X[A]]
108+
109+
F[X[int]]()
110+
F[X[Int]]()
111+
F[X[GlobalInt]]()
128112

129113
for j, tj := range tests {
130114
for i, ti := range tests[:j+1] {

0 commit comments

Comments
 (0)