diff options
| author | Robert Griesemer <gri@golang.org> | 2021-09-22 09:55:10 -0700 |
|---|---|---|
| committer | Robert Griesemer <gri@golang.org> | 2021-09-28 16:36:22 +0000 |
| commit | 73418bca347c94560a6cb605d8eb393b56941446 (patch) | |
| tree | 0da0a14c7f7d5fa15dd3972d928ca987d47e9958 /src/cmd/compile/internal/noder/expr.go | |
| parent | 583eeaae509a01cc50955c4174044b9dac539ff6 (diff) | |
| download | go-73418bca347c94560a6cb605d8eb393b56941446.tar.xz | |
cmd/compile/internal/types2: record all instances, not just inferred instances
This is a port of CL 349629 from go/types to types2, adjusted to
make it work for types2. It also includes the necessary compiler
changes, provided by mdempsky.
Change-Id: If8de174cee9c69df0d0642fcec1ee7622b7c3852
Reviewed-on: https://go-review.googlesource.com/c/go/+/351455
Trust: Robert Griesemer <gri@golang.org>
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Dan Scales <danscales@google.com>
Diffstat (limited to 'src/cmd/compile/internal/noder/expr.go')
| -rw-r--r-- | src/cmd/compile/internal/noder/expr.go | 79 |
1 files changed, 10 insertions, 69 deletions
diff --git a/src/cmd/compile/internal/noder/expr.go b/src/cmd/compile/internal/noder/expr.go index 9852ad964c..3dd7737c9f 100644 --- a/src/cmd/compile/internal/noder/expr.go +++ b/src/cmd/compile/internal/noder/expr.go @@ -114,86 +114,27 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node { case *syntax.CallExpr: fun := g.expr(expr.Fun) - - // 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 && inferred.TArgs.Len() > 0 { - // This is the case where inferring types required the - // types of the function arguments. - 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 { - if len(fun.(*ir.InstExpr).Targs) < len(targs) { - // Replace explicit type args with the full list that - // includes the additional inferred type args. - // Substitute the type args for the type params in - // the generic function's type. - fun.(*ir.InstExpr).Targs = targs - newt := g.substType(fun.(*ir.InstExpr).X.Type(), fun.(*ir.InstExpr).X.Type().TParams(), targs) - typed(newt, fun) - } - } else { - // Create a function instantiation here, given there - // are only inferred type args (e.g. min(5,6), where - // min is a generic function). Substitute the type - // args for the type params in the generic function's - // type. - inst := ir.NewInstExpr(pos, ir.OFUNCINST, fun, targs) - newt := g.substType(fun.Type(), fun.Type().TParams(), targs) - typed(newt, inst) - fun = inst - } - - } return Call(pos, g.typ(typ), fun, g.exprs(expr.ArgList), expr.HasDots) case *syntax.IndexExpr: - var targs []ir.Node - - 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, 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) - } else { - index := g.expr(expr.Index) - if index.Op() != ir.OTYPE { + args := unpackListExpr(expr.Index) + if len(args) == 1 { + tv, ok := g.info.Types[args[0]] + assert(ok) + if tv.IsValue() { // This is just a normal index expression - n := Index(pos, g.typ(typ), g.expr(expr.X), index) + n := Index(pos, g.typ(typ), g.expr(expr.X), g.expr(args[0])) if !g.delayTransform() { // transformIndex will modify n.Type() for OINDEXMAP. transformIndex(n) } return n } - // This is generic function instantiation with a single type - targs = []ir.Node{index} - } - // This is a generic function instantiation (e.g. min[int]). - // Generic type instantiation is handled in the type - // section of expr() above (using g.typ). - x := g.expr(expr.X) - if x.Op() != ir.ONAME || x.Type().Kind() != types.TFUNC { - panic("Incorrect argument for generic func instantiation") } - n := ir.NewInstExpr(pos, ir.OFUNCINST, x, targs) - newt := g.typ(typ) - // Substitute the type args for the type params in the uninstantiated - // function's type. If there aren't enough type args, then the rest - // will be inferred at the call node, so don't try the substitution yet. - if x.Type().TParams().NumFields() == len(targs) { - newt = g.substType(g.typ(typ), x.Type().TParams(), targs) - } - typed(newt, n) - return n + + // expr.Index is a list of type args, so we ignore it, since types2 has + // already provided this info with the Info.Instances map. + return g.expr(expr.X) case *syntax.SelectorExpr: // Qualified identifier. |
