1
0
mirror of https://github.com/golang/go synced 2024-11-26 11:48:03 -07:00

cmd/compile/internal/types2: simplify Checker.funcInst

Now that we use square brackets for instantiations, we
can tell type arguments from ordinary arguments without
"guessing" which permits a simpler implementation.

While at it, also fix a minor position error for type
instantiations (now matching the code for function
instantiations).

Change-Id: I20eca51c5b06259703767b5906e89197d6cd595a
Reviewed-on: https://go-review.googlesource.com/c/go/+/306169
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Griesemer 2021-03-30 22:07:26 -07:00
parent 93466cc1b6
commit 3a30381b21
2 changed files with 10 additions and 28 deletions

View File

@ -15,39 +15,29 @@ import (
// funcInst type-checks a function instantiaton inst and returns the result in x. // funcInst type-checks a function instantiaton inst and returns the result in x.
// The operand x must be the evaluation of inst.X and its type must be a signature. // The operand x must be the evaluation of inst.X and its type must be a signature.
func (check *Checker) funcInst(x *operand, inst *syntax.IndexExpr) { func (check *Checker) funcInst(x *operand, inst *syntax.IndexExpr) {
args, ok := check.exprOrTypeList(unpackExpr(inst.Index)) xlist := unpackExpr(inst.Index)
if !ok { targs := check.typeList(xlist)
if targs == nil {
x.mode = invalid x.mode = invalid
x.expr = inst x.expr = inst
return return
} }
if len(args) > 0 && args[0].mode != typexpr { assert(len(targs) == len(xlist))
check.errorf(args[0], "%s is not a type", args[0])
ok = false
}
// check number of type arguments // check number of type arguments
n := len(args) n := len(targs)
sig := x.typ.(*Signature) sig := x.typ.(*Signature)
if !check.conf.InferFromConstraints && n != len(sig.tparams) || n > len(sig.tparams) { if !check.conf.InferFromConstraints && n != len(sig.tparams) || n > len(sig.tparams) {
check.errorf(args[n-1], "got %d type arguments but want %d", n, len(sig.tparams)) check.errorf(xlist[n-1], "got %d type arguments but want %d", n, len(sig.tparams))
x.mode = invalid x.mode = invalid
x.expr = inst x.expr = inst
return return
} }
// collect types // determine argument positions (for error reporting)
targs := make([]Type, n)
poslist := make([]syntax.Pos, n) poslist := make([]syntax.Pos, n)
for i, a := range args { for i, x := range xlist {
if a.mode != typexpr { poslist[i] = syntax.StartPos(x)
// error was reported earlier
x.mode = invalid
x.expr = inst
return
}
targs[i] = a.typ
poslist[i] = a.Pos()
} }
// if we don't have enough type arguments, use constraint type inference // if we don't have enough type arguments, use constraint type inference
@ -82,14 +72,6 @@ func (check *Checker) funcInst(x *operand, inst *syntax.IndexExpr) {
assert(n == len(sig.tparams)) assert(n == len(sig.tparams))
// instantiate function signature // instantiate function signature
for i, typ := range targs {
// some positions may be missing if types are inferred
var pos syntax.Pos
if i < len(poslist) {
pos = poslist[i]
}
check.ordinaryType(pos, typ)
}
res := check.instantiate(x.Pos(), sig, targs, poslist).(*Signature) res := check.instantiate(x.Pos(), sig, targs, poslist).(*Signature)
assert(res.tparams == nil) // signature is not generic anymore assert(res.tparams == nil) // signature is not generic anymore
if inferred { if inferred {

View File

@ -671,7 +671,7 @@ func (check *Checker) instantiatedType(x syntax.Expr, targs []syntax.Expr, def *
// determine argument positions (for error reporting) // determine argument positions (for error reporting)
typ.poslist = make([]syntax.Pos, len(targs)) typ.poslist = make([]syntax.Pos, len(targs))
for i, arg := range targs { for i, arg := range targs {
typ.poslist[i] = arg.Pos() typ.poslist[i] = syntax.StartPos(arg)
} }
// make sure we check instantiation works at least once // make sure we check instantiation works at least once