mirror of
https://github.com/golang/go
synced 2024-11-26 19:31:17 -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:
parent
a0d477cb6d
commit
f9c0423ec8
@ -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 ©
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user