diff options
author | Dan Scales <danscales@google.com> | 2021-01-28 17:43:18 -0800 |
---|---|---|
committer | Dan Scales <danscales@google.com> | 2021-01-30 00:42:35 +0000 |
commit | 0aafd6912422570625414da6e5ed5ba2c371fcec (patch) | |
tree | 27788ad91dbfa27bbfbbe2239bd1c31aad2b8714 /src/cmd | |
parent | a59cb5109d49ac0dc09337449b9c7760ecc66c0e (diff) | |
download | go-0aafd6912422570625414da6e5ed5ba2c371fcec.tar.gz go-0aafd6912422570625414da6e5ed5ba2c371fcec.zip |
[dev.typeparams] cmd/compile: start translating type params in noder2
Also, make some fmt changes so that the type parameters and the
typeparam type are displayed in -W=2.
You can now parse a simple generic function (but not generic calls or generic
types) and print out the noder IR via 'go tool compile -G=2 -W=2 func.go'
Change-Id: I1f070fc4a96174a447763ad37999e61c25905901
Reviewed-on: https://go-review.googlesource.com/c/go/+/287833
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'src/cmd')
-rw-r--r-- | src/cmd/compile/internal/noder/types.go | 16 | ||||
-rw-r--r-- | src/cmd/compile/internal/types/fmt.go | 22 | ||||
-rw-r--r-- | src/cmd/compile/internal/types/size.go | 5 | ||||
-rw-r--r-- | src/cmd/compile/internal/types/type.go | 20 | ||||
-rw-r--r-- | src/cmd/compile/internal/types2/type.go | 4 |
5 files changed, 59 insertions, 8 deletions
diff --git a/src/cmd/compile/internal/noder/types.go b/src/cmd/compile/internal/noder/types.go index de191acc90..b4ad9cfc5b 100644 --- a/src/cmd/compile/internal/noder/types.go +++ b/src/cmd/compile/internal/noder/types.go @@ -100,6 +100,12 @@ func (g *irgen) typ0(typ types2.Type) *types.Type { return types.NewInterface(g.tpkg(typ), append(embeddeds, methods...)) + case *types2.TypeParam: + tp := types.NewTypeParam(g.tpkg(typ), g.typ(typ.Bound())) + // Save the name of the type parameter in the sym of the type. + tp.SetSym(g.sym(typ.Obj())) + return tp + default: base.FatalfAt(src.NoXPos, "unhandled type: %v (%T)", typ, typ) panic("unreachable") @@ -107,6 +113,13 @@ func (g *irgen) typ0(typ types2.Type) *types.Type { } func (g *irgen) signature(recv *types.Field, sig *types2.Signature) *types.Type { + tparams2 := sig.TParams() + tparams := make([]*types.Field, len(tparams2)) + for i := range tparams { + tp := tparams2[i] + tparams[i] = types.NewField(g.pos(tp), g.sym(tp), g.typ(tp.Type())) + } + do := func(typ *types2.Tuple) []*types.Field { fields := make([]*types.Field, typ.Len()) for i := range fields { @@ -114,14 +127,13 @@ func (g *irgen) signature(recv *types.Field, sig *types2.Signature) *types.Type } return fields } - params := do(sig.Params()) results := do(sig.Results()) if sig.Variadic() { params[len(params)-1].SetIsDDD(true) } - return types.NewSignature(g.tpkg(sig), recv, nil, params, results) + return types.NewSignature(g.tpkg(sig), recv, tparams, params, results) } func (g *irgen) param(v *types2.Var) *types.Field { diff --git a/src/cmd/compile/internal/types/fmt.go b/src/cmd/compile/internal/types/fmt.go index da224d4019..c59f62e302 100644 --- a/src/cmd/compile/internal/types/fmt.go +++ b/src/cmd/compile/internal/types/fmt.go @@ -318,7 +318,7 @@ func tconv2(b *bytes.Buffer, t *Type, verb rune, mode fmtMode, visited map[*Type } // Unless the 'L' flag was specified, if the type has a name, just print that name. - if verb != 'L' && t.Sym() != nil && t != Types[t.Kind()] { + if verb != 'L' && t.Sym() != nil && t != Types[t.Kind()] && t.Kind() != TTYPEPARAM { switch mode { case fmtTypeID, fmtTypeIDName: if verb == 'S' { @@ -478,6 +478,9 @@ func tconv2(b *bytes.Buffer, t *Type, verb rune, mode fmtMode, visited map[*Type } b.WriteString("func") } + if t.NumTParams() > 0 { + tconv2(b, t.TParams(), 0, mode, visited) + } tconv2(b, t.Params(), 0, mode, visited) switch t.NumResults() { @@ -515,7 +518,11 @@ func tconv2(b *bytes.Buffer, t *Type, verb rune, mode fmtMode, visited map[*Type } if funarg := t.StructType().Funarg; funarg != FunargNone { - b.WriteByte('(') + open, close := '(', ')' + if funarg == FunargTparams { + open, close = '[', ']' + } + b.WriteByte(byte(open)) fieldVerb := 'v' switch mode { case fmtTypeID, fmtTypeIDName, fmtGo: @@ -528,7 +535,7 @@ func tconv2(b *bytes.Buffer, t *Type, verb rune, mode fmtMode, visited map[*Type } fldconv(b, f, fieldVerb, mode, visited, funarg) } - b.WriteByte(')') + b.WriteByte(byte(close)) } else { b.WriteString("struct {") for i, f := range t.Fields().Slice() { @@ -554,6 +561,15 @@ func tconv2(b *bytes.Buffer, t *Type, verb rune, mode fmtMode, visited map[*Type case TUNSAFEPTR: b.WriteString("unsafe.Pointer") + case TTYPEPARAM: + if t.Sym() != nil { + sconv2(b, t.Sym(), 'v', mode) + } else { + b.WriteString("tp") + // Print out the pointer value for now to disambiguate type params + b.WriteString(fmt.Sprintf("%p", t)) + } + case Txxx: b.WriteString("Txxx") diff --git a/src/cmd/compile/internal/types/size.go b/src/cmd/compile/internal/types/size.go index 98540eefb6..d1203e4a21 100644 --- a/src/cmd/compile/internal/types/size.go +++ b/src/cmd/compile/internal/types/size.go @@ -499,6 +499,11 @@ func CalcSize(t *Type) { base.Warn("bad type %v %d\n", t1, w) } t.Align = 1 + + case TTYPEPARAM: + // TODO(danscales) - remove when we eliminate the need + // to do CalcSize in noder2 (which shouldn't be needed in the noder) + w = int64(PtrSize) } if PtrSize == 4 && w != int64(int32(w)) { diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go index 1d6edcda47..8d07b88ecd 100644 --- a/src/cmd/compile/internal/types/type.go +++ b/src/cmd/compile/internal/types/type.go @@ -204,7 +204,8 @@ func (t *Type) SetRecur(b bool) { t.flags.set(typeRecur, b) } func (t *Type) Kind() Kind { return t.kind } // Sym returns the name of type t. -func (t *Type) Sym() *Sym { return t.sym } +func (t *Type) Sym() *Sym { return t.sym } +func (t *Type) SetSym(sym *Sym) { t.sym = sym } // Underlying returns the underlying type of type t. func (t *Type) Underlying() *Type { return t.underlying } @@ -285,7 +286,7 @@ type Func struct { Receiver *Type // function receiver Results *Type // function results Params *Type // function params - Tparams *Type // type params of receiver (if method) or function + TParams *Type // type params of receiver (if method) or function pkg *Pkg @@ -512,6 +513,8 @@ func New(et Kind) *Type { t.Extra = new(Tuple) case TRESULTS: t.Extra = new(Results) + case TTYPEPARAM: + t.Extra = new(Interface) } return t } @@ -769,10 +772,12 @@ func (t *Type) wantEtype(et Kind) { } func (t *Type) Recvs() *Type { return t.FuncType().Receiver } +func (t *Type) TParams() *Type { return t.FuncType().TParams } func (t *Type) Params() *Type { return t.FuncType().Params } func (t *Type) Results() *Type { return t.FuncType().Results } func (t *Type) NumRecvs() int { return t.FuncType().Receiver.NumFields() } +func (t *Type) NumTParams() int { return t.FuncType().TParams.NumFields() } func (t *Type) NumParams() int { return t.FuncType().Params.NumFields() } func (t *Type) NumResults() int { return t.FuncType().Results.NumFields() } @@ -1648,6 +1653,15 @@ func NewInterface(pkg *Pkg, methods []*Field) *Type { return t } +// NewTypeParam returns a new type param with the given constraint (which may +// not really be needed except for the type checker). +func NewTypeParam(pkg *Pkg, constraint *Type) *Type { + t := New(TTYPEPARAM) + t.methods = constraint.methods + t.Extra.(*Interface).pkg = pkg + return t +} + // NewSignature returns a new function type for the given receiver, // parametes, results, and type parameters, any of which may be nil. func NewSignature(pkg *Pkg, recv *Field, tparams, params, results []*Field) *Type { @@ -1669,7 +1683,7 @@ func NewSignature(pkg *Pkg, recv *Field, tparams, params, results []*Field) *Typ } ft.Receiver = funargs(recvs, FunargRcvr) - ft.Tparams = funargs(tparams, FunargTparams) + ft.TParams = funargs(tparams, FunargTparams) ft.Params = funargs(params, FunargParams) ft.Results = funargs(results, FunargResults) ft.pkg = pkg diff --git a/src/cmd/compile/internal/types2/type.go b/src/cmd/compile/internal/types2/type.go index 22901b2ba9..7e51a138b5 100644 --- a/src/cmd/compile/internal/types2/type.go +++ b/src/cmd/compile/internal/types2/type.go @@ -837,6 +837,10 @@ type TypeParam struct { aType } +func (t *TypeParam) Obj() *TypeName { + return t.obj +} + // NewTypeParam returns a new TypeParam. func (check *Checker) NewTypeParam(obj *TypeName, index int, bound Type) *TypeParam { assert(bound != nil) |