mirror of
https://github.com/golang/go
synced 2024-11-26 22:01:27 -07:00
cmd/compile: changed representation of typeparam bound in types1
Especially with typesets, we should be able to fully represent a typeparam bound as just another type (actually an interface type). Change the representation of a typeparam in types1 to include a bound, which is just a type. Changed the signature for NewTypeParam() to take a sym, and not a package, since we always set the sym (name) of the typeparam when creating it. No need for an extra pkg field in Typeparam. Also added index field in the types1 representation of typeparam. This is especially needed to correctly export the typeparam, and re-import it as a types2 type (which requires the index to be set correctly). Change-Id: I50200e2489a97898c37d292b2bd025df790b0277 Reviewed-on: https://go-review.googlesource.com/c/go/+/319929 Reviewed-by: Robert Griesemer <gri@golang.org> Trust: Robert Griesemer <gri@golang.org> Trust: Dan Scales <danscales@google.com> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
parent
9daf3cca82
commit
c3fa51c9a2
@ -204,18 +204,15 @@ func (g *irgen) typ0(typ types2.Type) *types.Type {
|
|||||||
return types.NewInterface(g.tpkg(typ), append(embeddeds, methods...))
|
return types.NewInterface(g.tpkg(typ), append(embeddeds, methods...))
|
||||||
|
|
||||||
case *types2.TypeParam:
|
case *types2.TypeParam:
|
||||||
tp := types.NewTypeParam(g.tpkg(typ))
|
|
||||||
// Save the name of the type parameter in the sym of the type.
|
// Save the name of the type parameter in the sym of the type.
|
||||||
// Include the types2 subscript in the sym name
|
// Include the types2 subscript in the sym name
|
||||||
sym := g.pkg(typ.Obj().Pkg()).Lookup(types2.TypeString(typ, func(*types2.Package) string { return "" }))
|
sym := g.pkg(typ.Obj().Pkg()).Lookup(types2.TypeString(typ, func(*types2.Package) string { return "" }))
|
||||||
tp.SetSym(sym)
|
tp := types.NewTypeParam(sym, typ.Index())
|
||||||
// Set g.typs[typ] in case the bound methods reference typ.
|
// Set g.typs[typ] in case the bound methods reference typ.
|
||||||
g.typs[typ] = tp
|
g.typs[typ] = tp
|
||||||
|
|
||||||
// TODO(danscales): we don't currently need to use the bounds
|
|
||||||
// anywhere, so eventually we can probably remove.
|
|
||||||
bound := g.typ1(typ.Bound())
|
bound := g.typ1(typ.Bound())
|
||||||
*tp.Methods() = *bound.Methods()
|
tp.SetBound(bound)
|
||||||
return tp
|
return tp
|
||||||
|
|
||||||
case *types2.Tuple:
|
case *types2.Tuple:
|
||||||
|
@ -151,7 +151,7 @@ type Type struct {
|
|||||||
// TARRAY: *Array
|
// TARRAY: *Array
|
||||||
// TSLICE: Slice
|
// TSLICE: Slice
|
||||||
// TSSA: string
|
// TSSA: string
|
||||||
// TTYPEPARAM: *Interface (though we may not need to store/use the Interface info)
|
// TTYPEPARAM: *Typeparam
|
||||||
Extra interface{}
|
Extra interface{}
|
||||||
|
|
||||||
// Width is the width of this Type in bytes.
|
// Width is the width of this Type in bytes.
|
||||||
@ -377,6 +377,12 @@ type Interface struct {
|
|||||||
pkg *Pkg
|
pkg *Pkg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Typeparam contains Type fields specific to typeparam types.
|
||||||
|
type Typeparam struct {
|
||||||
|
index int // type parameter index in source order, starting at 0
|
||||||
|
bound *Type
|
||||||
|
}
|
||||||
|
|
||||||
// Ptr contains Type fields specific to pointer types.
|
// Ptr contains Type fields specific to pointer types.
|
||||||
type Ptr struct {
|
type Ptr struct {
|
||||||
Elem *Type // element type
|
Elem *Type // element type
|
||||||
@ -558,7 +564,7 @@ func New(et Kind) *Type {
|
|||||||
case TRESULTS:
|
case TRESULTS:
|
||||||
t.Extra = new(Results)
|
t.Extra = new(Results)
|
||||||
case TTYPEPARAM:
|
case TTYPEPARAM:
|
||||||
t.Extra = new(Interface)
|
t.Extra = new(Typeparam)
|
||||||
}
|
}
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
@ -825,6 +831,8 @@ func (t *Type) copy() *Type {
|
|||||||
case TARRAY:
|
case TARRAY:
|
||||||
x := *t.Extra.(*Array)
|
x := *t.Extra.(*Array)
|
||||||
nt.Extra = &x
|
nt.Extra = &x
|
||||||
|
case TTYPEPARAM:
|
||||||
|
base.Fatalf("typeparam types cannot be copied")
|
||||||
case TTUPLE, TSSA, TRESULTS:
|
case TTUPLE, TSSA, TRESULTS:
|
||||||
base.Fatalf("ssa types cannot be copied")
|
base.Fatalf("ssa types cannot be copied")
|
||||||
}
|
}
|
||||||
@ -1766,14 +1774,34 @@ func NewInterface(pkg *Pkg, methods []*Field) *Type {
|
|||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTypeParam returns a new type param.
|
// NewTypeParam returns a new type param with the specified sym (package and name)
|
||||||
func NewTypeParam(pkg *Pkg) *Type {
|
// and specified index within the typeparam list.
|
||||||
|
func NewTypeParam(sym *Sym, index int) *Type {
|
||||||
t := New(TTYPEPARAM)
|
t := New(TTYPEPARAM)
|
||||||
t.Extra.(*Interface).pkg = pkg
|
t.sym = sym
|
||||||
|
t.Extra.(*Typeparam).index = index
|
||||||
t.SetHasTParam(true)
|
t.SetHasTParam(true)
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Index returns the index of the type param within its param list.
|
||||||
|
func (t *Type) Index() int {
|
||||||
|
t.wantEtype(TTYPEPARAM)
|
||||||
|
return t.Extra.(*Typeparam).index
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBound sets the bound of a typeparam.
|
||||||
|
func (t *Type) SetBound(bound *Type) {
|
||||||
|
t.wantEtype(TTYPEPARAM)
|
||||||
|
t.Extra.(*Typeparam).bound = bound
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bound returns the bound of a typeparam.
|
||||||
|
func (t *Type) Bound() *Type {
|
||||||
|
t.wantEtype(TTYPEPARAM)
|
||||||
|
return t.Extra.(*Typeparam).bound
|
||||||
|
}
|
||||||
|
|
||||||
const BOGUS_FUNARG_OFFSET = -1000000000
|
const BOGUS_FUNARG_OFFSET = -1000000000
|
||||||
|
|
||||||
func unzeroFieldOffsets(f []*Field) {
|
func unzeroFieldOffsets(f []*Field) {
|
||||||
|
@ -760,6 +760,11 @@ func (check *Checker) NewTypeParam(obj *TypeName, index int, bound Type) *TypePa
|
|||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Index returns the index of the type param within its param list.
|
||||||
|
func (t *TypeParam) Index() int {
|
||||||
|
return t.index
|
||||||
|
}
|
||||||
|
|
||||||
func (t *TypeParam) Bound() *Interface {
|
func (t *TypeParam) Bound() *Interface {
|
||||||
iface := asInterface(t.bound)
|
iface := asInterface(t.bound)
|
||||||
// use the type bound position if we have one
|
// use the type bound position if we have one
|
||||||
|
Loading…
Reference in New Issue
Block a user