mirror of https://github.com/golang/go.git
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 <gri@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Dan Scales <danscales@google.com>
This commit is contained in:
parent
b1cdf860dd
commit
e6798795ff
|
|
@ -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
|
// The key for the Inferred map is the CallExpr (if inferring
|
||||||
// types required the function arguments) or the IndexExpr below
|
// types required the function arguments) or the IndexExpr below
|
||||||
// (if types could be inferred without the function arguments).
|
// (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
|
// This is the case where inferring types required the
|
||||||
// types of the function arguments.
|
// types of the function arguments.
|
||||||
targs := make([]ir.Node, len(inferred.TArgs))
|
targs := make([]ir.Node, inferred.TArgs.Len())
|
||||||
for i, targ := range inferred.TArgs {
|
for i := range targs {
|
||||||
targs[i] = ir.TypeNode(g.typ(targ))
|
targs[i] = ir.TypeNode(g.typ(inferred.TArgs.At(i)))
|
||||||
}
|
}
|
||||||
if fun.Op() == ir.OFUNCINST {
|
if fun.Op() == ir.OFUNCINST {
|
||||||
// Replace explicit type args with the full list that
|
// 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:
|
case *syntax.IndexExpr:
|
||||||
var targs []ir.Node
|
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
|
// This is the partial type inference case where the types
|
||||||
// can be inferred from other type arguments without using
|
// can be inferred from other type arguments without using
|
||||||
// the types of the function arguments.
|
// the types of the function arguments.
|
||||||
targs = make([]ir.Node, len(inferred.TArgs))
|
targs = make([]ir.Node, inferred.TArgs.Len())
|
||||||
for i, targ := range inferred.TArgs {
|
for i := range targs {
|
||||||
targs[i] = ir.TypeNode(g.typ(targ))
|
targs[i] = ir.TypeNode(g.typ(inferred.TArgs.At(i)))
|
||||||
}
|
}
|
||||||
} else if _, ok := expr.Index.(*syntax.ListExpr); ok {
|
} else if _, ok := expr.Index.(*syntax.ListExpr); ok {
|
||||||
targs = g.exprList(expr.Index)
|
targs = g.exprList(expr.Index)
|
||||||
|
|
|
||||||
|
|
@ -1212,12 +1212,12 @@ func (w *writer) expr(expr syntax.Expr) {
|
||||||
if obj != nil {
|
if obj != nil {
|
||||||
if isGlobal(obj) {
|
if isGlobal(obj) {
|
||||||
w.code(exprName)
|
w.code(exprName)
|
||||||
w.obj(obj, types2.NewTypeList(targs))
|
w.obj(obj, targs)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
obj := obj.(*types2.Var)
|
obj := obj.(*types2.Var)
|
||||||
assert(len(targs) == 0)
|
assert(targs.Len() == 0)
|
||||||
|
|
||||||
w.code(exprLocal)
|
w.code(exprLocal)
|
||||||
w.useLocal(expr.Pos(), obj)
|
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.
|
// As if w.expr(expr.Fun), but using inf.TArgs instead.
|
||||||
w.code(exprName)
|
w.code(exprName)
|
||||||
w.obj(obj, types2.NewTypeList(inf.TArgs))
|
w.obj(obj, inf.TArgs)
|
||||||
} else {
|
} else {
|
||||||
w.expr(expr.Fun)
|
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
|
// lookupObj returns the object that expr refers to, if any. If expr
|
||||||
// is an explicit instantiation of a generic object, then the type
|
// is an explicit instantiation of a generic object, then the type
|
||||||
// arguments are returned as well.
|
// 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 index, ok := expr.(*syntax.IndexExpr); ok {
|
||||||
if inf, ok := info.Inferred[index]; ok {
|
if inf, ok := info.Inferred[index]; ok {
|
||||||
targs = inf.TArgs
|
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 {
|
for i, arg := range args {
|
||||||
tv, ok := info.Types[arg]
|
tv, ok := info.Types[arg]
|
||||||
assert(ok)
|
assert(ok)
|
||||||
assert(tv.IsType())
|
assert(tv.IsType())
|
||||||
targs[i] = tv.Type
|
list[i] = tv.Type
|
||||||
}
|
}
|
||||||
|
targs = types2.NewTypeList(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
expr = index.X
|
expr = index.X
|
||||||
|
|
|
||||||
|
|
@ -373,7 +373,7 @@ func (tv TypeAndValue) HasOk() bool {
|
||||||
// Inferred reports the inferred type arguments and signature
|
// Inferred reports the inferred type arguments and signature
|
||||||
// for a parameterized function call that uses type inference.
|
// for a parameterized function call that uses type inference.
|
||||||
type Inferred struct {
|
type Inferred struct {
|
||||||
TArgs []Type
|
TArgs *TypeList
|
||||||
Sig *Signature
|
Sig *Signature
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -500,7 +500,7 @@ func TestInferredInfo(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// look for inferred type arguments and signature
|
// look for inferred type arguments and signature
|
||||||
var targs []Type
|
var targs *TypeList
|
||||||
var sig *Signature
|
var sig *Signature
|
||||||
for call, inf := range info.Inferred {
|
for call, inf := range info.Inferred {
|
||||||
var fun syntax.Expr
|
var fun syntax.Expr
|
||||||
|
|
@ -524,11 +524,12 @@ func TestInferredInfo(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that type arguments are correct
|
// check that type arguments are correct
|
||||||
if len(targs) != len(test.targs) {
|
if targs.Len() != len(test.targs) {
|
||||||
t.Errorf("package %s: got %d type arguments; want %d", name, len(targs), len(test.targs))
|
t.Errorf("package %s: got %d type arguments; want %d", name, targs.Len(), len(test.targs))
|
||||||
continue
|
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] {
|
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])
|
t.Errorf("package %s, %d. type argument: got %s; want %s", name, i, got, test.targs[i])
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
|
|
@ -416,7 +416,7 @@ func (check *Checker) recordInferred(call syntax.Expr, targs []Type, sig *Signat
|
||||||
assert(call != nil)
|
assert(call != nil)
|
||||||
assert(sig != nil)
|
assert(sig != nil)
|
||||||
if m := check.Inferred; m != nil {
|
if m := check.Inferred; m != nil {
|
||||||
m[call] = Inferred{targs, sig}
|
m[call] = Inferred{NewTypeList(targs), sig}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue