go/types: removed instantiate call, renamed instantiate2 => instantiate

Also: added a currently failing test case to testdata/tmp.go2

Change-Id: I605bffb457e3b3979b42a642010215630c0544c6
This commit is contained in:
Robert Griesemer 2019-11-27 16:46:57 -08:00
parent 45eb8a74f0
commit 1a0bc57392
4 changed files with 35 additions and 27 deletions

View File

@ -81,13 +81,32 @@ func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind {
args, _ := check.exprOrTypeList(e.Args)
// instantiate function if needed
if n := len(args); len(sig.tparams) > 0 && n > 0 && args[0].mode == typexpr {
if n := len(args); n > 0 && len(sig.tparams) > 0 && args[0].mode == typexpr {
// if the first argument is a type, assume we have explicit type arguments
x.mode = value
x.typ = check.instantiate(sig, sig.tparams, args)
if x.typ == nil {
// we must have the correct number of type parameters
if n != len(sig.tparams) {
check.errorf(args[n-1].pos(), "got %d type arguments but want %d", n, len(sig.tparams))
x.mode = invalid
x.expr = e
return expression
}
// collect types
targs := make([]Type, n)
for i, a := range args {
if a.mode != typexpr {
// error was reported earlier
x.mode = invalid
x.expr = e
return expression
}
targs[i] = a.typ
}
// instantiate function signature
x.typ = check.subst(x.pos(), sig, sig.tparams, targs)
x.mode = value
x.expr = e
return expression
}
@ -172,26 +191,6 @@ func (check *Checker) exprOrTypeList(elist []ast.Expr) (xlist []*operand, ok boo
return
}
func (check *Checker) instantiate(typ Type, tparams []*TypeName, args []*operand) Type {
assert(typ != nil)
n := len(args)
if n != len(tparams) {
check.errorf(args[n-1].pos(), "got %d type arguments but want %d", n, len(tparams))
return nil
}
// collect types
targs := make([]Type, n)
for i, a := range args {
if a.mode != typexpr {
// error was reported earlier
return nil
}
targs[i] = a.typ
}
// result is instantiated typ
return check.subst(token.NoPos, typ, tparams, targs)
}
func (check *Checker) exprList(elist []ast.Expr, allowCommaOk bool) (xlist []*operand, commaOk bool) {
switch len(elist) {
case 0:

View File

@ -14,7 +14,7 @@ import (
"strings"
)
func (check *Checker) instantiate2(pos token.Pos, named *Named, targs []Type) (res Type) {
func (check *Checker) instantiate(pos token.Pos, named *Named, targs []Type) (res Type) {
tname := named.obj
if check.conf.Trace {
check.trace(pos, "-- instantiating %s with %s", tname, typeListString(targs))

View File

@ -4,6 +4,16 @@
package p
type T(type P) struct {}
func (_ T(P)) m1() T(P)
func (m T(P)) m2() {
// TODO(gri) this should be valid
var _ T(P) = m /* ERROR cannot use */ .m1()
}
/*
type Pair(type K) struct {
key K
}
@ -16,7 +26,6 @@ type Iterator(type K) struct {
r Receiver(Pair(K))
}
/*
func (r Receiver(T)) Values() T {
return r.values
}

View File

@ -302,7 +302,7 @@ func (check *Checker) typInternal(e ast.Expr, def *Named) Type {
}
// instantiate parameterized type
typ = check.instantiate2(e.Pos(), named, targs)
typ = check.instantiate(e.Pos(), named, targs)
def.setUnderlying(typ)
return typ