]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/noder: preserve alias uses in export data
authorMatthew Dempsky <mdempsky@google.com>
Thu, 25 Jan 2024 23:51:22 +0000 (15:51 -0800)
committerGopher Robot <gobot@golang.org>
Tue, 30 Jan 2024 18:42:01 +0000 (18:42 +0000)
This CL changes the export data format to preserve alias uses.
Previously they were stripped away with types2.Unalias. For backwards
compatibility, we use pkgbits.TypeNamed, which is already used for the
predeclared aliases byte, rune, and any.

While here, remove unnecessary uses of types2.Unalias, and add a
missing one in recvBase to handle:

    type T int
    type A = T
    func (*A) m() {}

Change-Id: I62ddb0426080a44436054964a90ab250bcd8df12
Reviewed-on: https://go-review.googlesource.com/c/go/+/558577
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

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

index e5894c950543ae091e6b934196ffe562a6c43b7a..641374e03c441df8c62a1c1a661f797d46eaec9a 100644 (file)
@@ -189,7 +189,9 @@ type writer struct {
 
 // A writerDict tracks types and objects that are used by a declaration.
 type writerDict struct {
-       implicits []*types2.TypeName
+       // implicits is a slice of type parameters from the enclosing
+       // declarations.
+       implicits []*types2.TypeParam
 
        // derived is a slice of type indices for computing derived types
        // (i.e., types that depend on the declaration's type parameters).
@@ -217,7 +219,7 @@ type itabInfo struct {
 // generic function or method.
 func (dict *writerDict) typeParamIndex(typ *types2.TypeParam) int {
        for idx, implicit := range dict.implicits {
-               if types2.Unalias(implicit.Type()).(*types2.TypeParam) == typ {
+               if implicit == typ {
                        return idx
                }
        }
@@ -498,7 +500,7 @@ func (pw *pkgWriter) typIdx(typ types2.Type, dict *writerDict) typeInfo {
        w := pw.newWriter(pkgbits.RelocType, pkgbits.SyncTypeIdx)
        w.dict = dict
 
-       switch typ := types2.Unalias(typ).(type) {
+       switch typ := typ.(type) {
        default:
                base.Fatalf("unexpected type: %v (%T)", typ, typ)
 
@@ -513,24 +515,20 @@ func (pw *pkgWriter) typIdx(typ types2.Type, dict *writerDict) typeInfo {
 
                default:
                        // Handle "byte" and "rune" as references to their TypeNames.
-                       obj := types2.Universe.Lookup(typ.Name())
+                       obj := types2.Universe.Lookup(typ.Name()).(*types2.TypeName)
                        assert(obj.Type() == typ)
 
                        w.Code(pkgbits.TypeNamed)
-                       w.obj(obj, nil)
+                       w.namedType(obj, nil)
                }
 
        case *types2.Named:
-               obj, targs := splitNamed(typ)
-
-               // Defined types that are declared within a generic function (and
-               // thus have implicit type parameters) are always derived types.
-               if w.p.hasImplicitTypeParams(obj) {
-                       w.derived = true
-               }
+               w.Code(pkgbits.TypeNamed)
+               w.namedType(splitNamed(typ))
 
+       case *types2.Alias:
                w.Code(pkgbits.TypeNamed)
-               w.obj(obj, targs)
+               w.namedType(typ.Obj(), nil)
 
        case *types2.TypeParam:
                w.derived = true
@@ -596,6 +594,17 @@ func (pw *pkgWriter) typIdx(typ types2.Type, dict *writerDict) typeInfo {
        return typeInfo{idx: w.Flush(), derived: false}
 }
 
+// namedType writes a use of the given named type into the bitstream.
+func (w *writer) namedType(obj *types2.TypeName, targs *types2.TypeList) {
+       // Named types that are declared within a generic function (and
+       // thus have implicit type parameters) are always derived types.
+       if w.p.hasImplicitTypeParams(obj) {
+               w.derived = true
+       }
+
+       w.obj(obj, targs)
+}
+
 func (w *writer) structType(typ *types2.Struct) {
        w.Len(typ.NumFields())
        for i := 0; i < typ.NumFields(); i++ {
@@ -889,8 +898,7 @@ func (w *writer) objDict(obj types2.Object, dict *writerDict) {
        // parameter is constrained to `int | uint` but then never used in
        // arithmetic/conversions/etc, we could shape those together.
        for _, implicit := range dict.implicits {
-               tparam := types2.Unalias(implicit.Type()).(*types2.TypeParam)
-               w.Bool(tparam.Underlying().(*types2.Interface).IsMethodSet())
+               w.Bool(implicit.Underlying().(*types2.Interface).IsMethodSet())
        }
        for i := 0; i < ntparams; i++ {
                tparam := tparams.At(i)
@@ -2362,12 +2370,16 @@ func (w *writer) varDictIndex(obj *types2.Var) {
        }
 }
 
+// isUntyped reports whether typ is an untyped type.
 func isUntyped(typ types2.Type) bool {
-       basic, ok := types2.Unalias(typ).(*types2.Basic)
+       // Note: types2.Unalias is unnecessary here, since untyped types can't be aliased.
+       basic, ok := typ.(*types2.Basic)
        return ok && basic.Info()&types2.IsUntyped != 0
 }
 
+// isTuple reports whether typ is a tuple type.
 func isTuple(typ types2.Type) bool {
+       // Note: types2.Unalias is unnecessary here, since tuple types can't be aliased.
        _, ok := typ.(*types2.Tuple)
        return ok
 }
@@ -2447,7 +2459,7 @@ type typeDeclGen struct {
        gen int
 
        // Implicit type parameters in scope at this type declaration.
-       implicits []*types2.TypeName
+       implicits []*types2.TypeParam
 }
 
 type fileImports struct {
@@ -2465,7 +2477,7 @@ type declCollector struct {
        typegen    *int
        file       *fileImports
        withinFunc bool
-       implicits  []*types2.TypeName
+       implicits  []*types2.TypeParam
 }
 
 func (c *declCollector) withTParams(obj types2.Object) *declCollector {
@@ -2478,7 +2490,7 @@ func (c *declCollector) withTParams(obj types2.Object) *declCollector {
        copy := *c
        copy.implicits = copy.implicits[:len(copy.implicits):len(copy.implicits)]
        for i := 0; i < n; i++ {
-               copy.implicits = append(copy.implicits, tparams.At(i).Obj())
+               copy.implicits = append(copy.implicits, tparams.At(i))
        }
        return &copy
 }
@@ -2869,7 +2881,7 @@ func (pw *pkgWriter) isBuiltin(expr syntax.Expr, builtin string) bool {
 func recvBase(recv *types2.Var) *types2.Named {
        typ := types2.Unalias(recv.Type())
        if ptr, ok := typ.(*types2.Pointer); ok {
-               typ = ptr.Elem()
+               typ = types2.Unalias(ptr.Elem())
        }
        return typ.(*types2.Named)
 }