1
0
mirror of https://github.com/golang/go synced 2024-11-26 16:46:58 -07:00

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 <gri@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Matthew Dempsky 2024-01-25 15:51:22 -08:00 committed by Gopher Robot
parent a0d477cb6d
commit f9c0423ec8

View 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.obj(obj, targs)
w.namedType(splitNamed(typ))
case *types2.Alias:
w.Code(pkgbits.TypeNamed)
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)
}