Skip to content

Commit dddc1ba

Browse files
committed
cmd/compile: restore test/nested.go test cases
[Re-land of CL 424854, which was reverted as CL 425214.] 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: I9aa087e0a277527003195ebc7f4fbba6922e788c Reviewed-on: https://go-review.googlesource.com/c/go/+/455279 Run-TryBot: Matthew Dempsky <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
1 parent 8cd931f commit dddc1ba

File tree

1 file changed

+23
-16
lines changed

1 file changed

+23
-16
lines changed

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

+23-16
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,9 @@ func (pw *pkgWriter) pkgIdx(pkg *types2.Package) pkgbits.Index {
442442
// @@@ Types
443443

444444
var (
445-
anyTypeName = types2.Universe.Lookup("any").(*types2.TypeName)
446-
runeTypeName = types2.Universe.Lookup("rune").(*types2.TypeName)
445+
anyTypeName = types2.Universe.Lookup("any").(*types2.TypeName)
446+
comparableTypeName = types2.Universe.Lookup("comparable").(*types2.TypeName)
447+
runeTypeName = types2.Universe.Lookup("rune").(*types2.TypeName)
447448
)
448449

449450
// typ writes a use of the given type into the bitstream.
@@ -495,7 +496,7 @@ func (pw *pkgWriter) typIdx(typ types2.Type, dict *writerDict) typeInfo {
495496
w.Len(int(kind))
496497

497498
default:
498-
// Handle "byte" and "rune" as references to their TypeName.
499+
// Handle "byte" and "rune" as references to their TypeNames.
499500
obj := types2.Universe.Lookup(typ.Name())
500501
assert(obj.Type() == typ)
501502

@@ -553,6 +554,7 @@ func (pw *pkgWriter) typIdx(typ types2.Type, dict *writerDict) typeInfo {
553554
w.structType(typ)
554555

555556
case *types2.Interface:
557+
// Handle "any" as reference to its TypeName.
556558
if typ == anyTypeName.Type() {
557559
w.Code(pkgbits.TypeNamed)
558560
w.obj(anyTypeName, nil)
@@ -600,6 +602,23 @@ func (w *writer) unionType(typ *types2.Union) {
600602
}
601603

602604
func (w *writer) interfaceType(typ *types2.Interface) {
605+
// If typ has no embedded types but it's not a basic interface, then
606+
// the natural description we write out below will fail to
607+
// reconstruct it.
608+
if typ.NumEmbeddeds() == 0 && !typ.IsMethodSet() {
609+
// Currently, this can only happen for the underlying Interface of
610+
// "comparable", which is needed to handle type declarations like
611+
// "type C comparable".
612+
assert(typ == comparableTypeName.Type().(*types2.Named).Underlying())
613+
614+
// Export as "interface{ comparable }".
615+
w.Len(0) // NumExplicitMethods
616+
w.Len(1) // NumEmbeddeds
617+
w.Bool(false) // IsImplicit
618+
w.typ(comparableTypeName.Type()) // EmbeddedType(0)
619+
return
620+
}
621+
603622
w.Len(typ.NumExplicitMethods())
604623
w.Len(typ.NumEmbeddeds())
605624

@@ -785,9 +804,6 @@ func (w *writer) doObj(wext *writer, obj types2.Object) pkgbits.CodeObj {
785804
return pkgbits.ObjFunc
786805

787806
case *types2.TypeName:
788-
decl, ok := w.p.typDecls[obj]
789-
assert(ok)
790-
791807
if obj.IsAlias() {
792808
w.pos(obj)
793809
w.typ(obj.Type())
@@ -800,7 +816,7 @@ func (w *writer) doObj(wext *writer, obj types2.Object) pkgbits.CodeObj {
800816
w.pos(obj)
801817
w.typeParamNames(named.TypeParams())
802818
wext.typeExt(obj)
803-
w.typExpr(decl.Type)
819+
w.typ(named.Underlying())
804820

805821
w.Len(named.NumMethods())
806822
for i := 0; i < named.NumMethods(); i++ {
@@ -817,15 +833,6 @@ func (w *writer) doObj(wext *writer, obj types2.Object) pkgbits.CodeObj {
817833
}
818834
}
819835

820-
// typExpr writes the type represented by the given expression.
821-
//
822-
// TODO(mdempsky): Document how this differs from exprType.
823-
func (w *writer) typExpr(expr syntax.Expr) {
824-
tv := w.p.typeAndValue(expr)
825-
assert(tv.IsType())
826-
w.typ(tv.Type)
827-
}
828-
829836
// objDict writes the dictionary needed for reading the given object.
830837
func (w *writer) objDict(obj types2.Object, dict *writerDict) {
831838
// TODO(mdempsky): Split objDict into multiple entries? reader.go

0 commit comments

Comments
 (0)