From: Matthew Dempsky Date: Thu, 25 Jan 2024 23:51:22 +0000 (-0800) Subject: cmd/compile/internal/noder: preserve alias uses in export data X-Git-Tag: go1.23rc1~1346 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=f9c0423ec821e325d5a77e0f18dc1e44ee13503b;p=gostls13.git cmd/compile/internal/noder: preserve alias uses in export data 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 Auto-Submit: Matthew Dempsky LUCI-TryBot-Result: Go LUCI --- diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go index e5894c9505..641374e03c 100644 --- a/src/cmd/compile/internal/noder/writer.go +++ b/src/cmd/compile/internal/noder/writer.go @@ -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 © } @@ -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) }