From e6798795ff523b9b5df2514bffd8d5ce743c312e Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Mon, 23 Aug 2021 21:04:56 -0700 Subject: cmd/compile/internal/types2: use TypeList in the Inferred struct This is a port of CL 343934 from go/types with the necessary adjustments to the compiler. Change-Id: I810144e6e2eb2bc8fa0d34dc206403c993cbbe7a Reviewed-on: https://go-review.googlesource.com/c/go/+/344616 Trust: Robert Griesemer Reviewed-by: Matthew Dempsky Reviewed-by: Dan Scales --- src/cmd/compile/internal/noder/expr.go | 16 ++++++++-------- src/cmd/compile/internal/noder/writer.go | 13 +++++++------ src/cmd/compile/internal/types2/api.go | 2 +- src/cmd/compile/internal/types2/api_test.go | 9 +++++---- src/cmd/compile/internal/types2/check.go | 2 +- 5 files changed, 22 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/cmd/compile/internal/noder/expr.go b/src/cmd/compile/internal/noder/expr.go index cb20d645aa..2f004ba1a2 100644 --- a/src/cmd/compile/internal/noder/expr.go +++ b/src/cmd/compile/internal/noder/expr.go @@ -116,12 +116,12 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node { // The key for the Inferred map is the CallExpr (if inferring // types required the function arguments) or the IndexExpr below // (if types could be inferred without the function arguments). - if inferred, ok := g.info.Inferred[expr]; ok && len(inferred.TArgs) > 0 { + if inferred, ok := g.info.Inferred[expr]; ok && inferred.TArgs.Len() > 0 { // This is the case where inferring types required the // types of the function arguments. - targs := make([]ir.Node, len(inferred.TArgs)) - for i, targ := range inferred.TArgs { - targs[i] = ir.TypeNode(g.typ(targ)) + targs := make([]ir.Node, inferred.TArgs.Len()) + for i := range targs { + targs[i] = ir.TypeNode(g.typ(inferred.TArgs.At(i))) } if fun.Op() == ir.OFUNCINST { // Replace explicit type args with the full list that @@ -149,13 +149,13 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node { case *syntax.IndexExpr: var targs []ir.Node - if inferred, ok := g.info.Inferred[expr]; ok && len(inferred.TArgs) > 0 { + if inferred, ok := g.info.Inferred[expr]; ok && inferred.TArgs.Len() > 0 { // This is the partial type inference case where the types // can be inferred from other type arguments without using // the types of the function arguments. - targs = make([]ir.Node, len(inferred.TArgs)) - for i, targ := range inferred.TArgs { - targs[i] = ir.TypeNode(g.typ(targ)) + targs = make([]ir.Node, inferred.TArgs.Len()) + for i := range targs { + targs[i] = ir.TypeNode(g.typ(inferred.TArgs.At(i))) } } else if _, ok := expr.Index.(*syntax.ListExpr); ok { targs = g.exprList(expr.Index) diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go index a6bd8b2426..1405c77161 100644 --- a/src/cmd/compile/internal/noder/writer.go +++ b/src/cmd/compile/internal/noder/writer.go @@ -1212,12 +1212,12 @@ func (w *writer) expr(expr syntax.Expr) { if obj != nil { if isGlobal(obj) { w.code(exprName) - w.obj(obj, types2.NewTypeList(targs)) + w.obj(obj, targs) return } obj := obj.(*types2.Var) - assert(len(targs) == 0) + assert(targs.Len() == 0) w.code(exprLocal) w.useLocal(expr.Pos(), obj) @@ -1321,7 +1321,7 @@ func (w *writer) expr(expr syntax.Expr) { // As if w.expr(expr.Fun), but using inf.TArgs instead. w.code(exprName) - w.obj(obj, types2.NewTypeList(inf.TArgs)) + w.obj(obj, inf.TArgs) } else { w.expr(expr.Fun) } @@ -1770,7 +1770,7 @@ func isGlobal(obj types2.Object) bool { // lookupObj returns the object that expr refers to, if any. If expr // is an explicit instantiation of a generic object, then the type // arguments are returned as well. -func lookupObj(info *types2.Info, expr syntax.Expr) (obj types2.Object, targs []types2.Type) { +func lookupObj(info *types2.Info, expr syntax.Expr) (obj types2.Object, targs *types2.TypeList) { if index, ok := expr.(*syntax.IndexExpr); ok { if inf, ok := info.Inferred[index]; ok { targs = inf.TArgs @@ -1785,13 +1785,14 @@ func lookupObj(info *types2.Info, expr syntax.Expr) (obj types2.Object, targs [] } } - targs = make([]types2.Type, len(args)) + list := make([]types2.Type, len(args)) for i, arg := range args { tv, ok := info.Types[arg] assert(ok) assert(tv.IsType()) - targs[i] = tv.Type + list[i] = tv.Type } + targs = types2.NewTypeList(list) } expr = index.X diff --git a/src/cmd/compile/internal/types2/api.go b/src/cmd/compile/internal/types2/api.go index f268508825..b2938b84da 100644 --- a/src/cmd/compile/internal/types2/api.go +++ b/src/cmd/compile/internal/types2/api.go @@ -373,7 +373,7 @@ func (tv TypeAndValue) HasOk() bool { // Inferred reports the inferred type arguments and signature // for a parameterized function call that uses type inference. type Inferred struct { - TArgs []Type + TArgs *TypeList Sig *Signature } diff --git a/src/cmd/compile/internal/types2/api_test.go b/src/cmd/compile/internal/types2/api_test.go index 269b06f08a..039a6c0e5e 100644 --- a/src/cmd/compile/internal/types2/api_test.go +++ b/src/cmd/compile/internal/types2/api_test.go @@ -500,7 +500,7 @@ func TestInferredInfo(t *testing.T) { } // look for inferred type arguments and signature - var targs []Type + var targs *TypeList var sig *Signature for call, inf := range info.Inferred { var fun syntax.Expr @@ -524,11 +524,12 @@ func TestInferredInfo(t *testing.T) { } // check that type arguments are correct - if len(targs) != len(test.targs) { - t.Errorf("package %s: got %d type arguments; want %d", name, len(targs), len(test.targs)) + if targs.Len() != len(test.targs) { + t.Errorf("package %s: got %d type arguments; want %d", name, targs.Len(), len(test.targs)) continue } - for i, targ := range targs { + for i := 0; i < targs.Len(); i++ { + targ := targs.At(i) if got := targ.String(); got != test.targs[i] { t.Errorf("package %s, %d. type argument: got %s; want %s", name, i, got, test.targs[i]) continue diff --git a/src/cmd/compile/internal/types2/check.go b/src/cmd/compile/internal/types2/check.go index 6bc965c497..4226b4de82 100644 --- a/src/cmd/compile/internal/types2/check.go +++ b/src/cmd/compile/internal/types2/check.go @@ -416,7 +416,7 @@ func (check *Checker) recordInferred(call syntax.Expr, targs []Type, sig *Signat assert(call != nil) assert(sig != nil) if m := check.Inferred; m != nil { - m[call] = Inferred{targs, sig} + m[call] = Inferred{NewTypeList(targs), sig} } } -- cgit v1.2.3-54-g00ecf