}
func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
+ var inst *ast.IndexExpr
if iexpr, _ := call.Fun.(*ast.IndexExpr); iexpr != nil {
if check.indexExpr(x, iexpr) {
- check.funcInst(x, iexpr)
+ // Delay function instantiation to argument checking,
+ // where we combine type and value arguments for type
+ // inference.
+ assert(x.mode == value)
+ inst = iexpr
}
x.expr = iexpr
check.record(x)
return statement
}
+ // evaluate type arguments, if any
+ var targs []Type
+ if inst != nil {
+ xlist := typeparams.UnpackExpr(inst.Index)
+ targs = check.typeList(xlist)
+ if targs == nil {
+ check.use(call.Args...)
+ x.mode = invalid
+ x.expr = call
+ return statement
+ }
+ assert(len(targs) == len(xlist))
+
+ // check number of type arguments (got) vs number of type parameters (want)
+ got, want := len(targs), len(sig.tparams)
+ if got > want {
+ check.errorf(xlist[want], _Todo, "got %d type arguments but want %d", got, want)
+ check.use(call.Args...)
+ x.mode = invalid
+ x.expr = call
+ return statement
+ }
+ }
+
// evaluate arguments
args, _ := check.exprList(call.Args, false)
- sig = check.arguments(call, sig, args)
+ sig = check.arguments(call, sig, targs, args)
// determine result
switch sig.results.Len() {
return
}
-func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, args []*operand) (rsig *Signature) {
+func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type, args []*operand) (rsig *Signature) {
rsig = sig
// TODO(gri) try to eliminate this extra verification loop
if len(sig.tparams) > 0 {
// TODO(gri) provide position information for targs so we can feed
// it to the instantiate call for better error reporting
- targs := check.infer(call, sig.tparams, nil, sigParams, args, true)
+ targs := check.infer(call, sig.tparams, targs, sigParams, args, true)
if targs == nil {
return // error already reported
}
\r
func _() {\r
f[int, Optional[int], Optional[int]]()\r
- // f[int, Optional[int], Optional /* ERROR does not satisfy Box */ [string]]()\r
+ _ = f[int, Optional[int], Optional /* ERROR does not satisfy Box */ [string]]\r
+ // TODO(gri) Provide better position information here.\r
+ // See TODO in call.go, Checker.arguments.\r
+ // TODO(rFindley) Reconcile this error position with types2.\r
+ f /* ERROR does not satisfy Box */ [int, Optional[int], Optional[string]]()\r
}\r
--- /dev/null
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func Map[F, T any](s []F, f func(F) T) []T { return nil }
+
+func Reduce[Elem1, Elem2 any](s []Elem1, initializer Elem2, f func(Elem2, Elem1) Elem2) Elem2 { var x Elem2; return x }
+
+func main() {
+ var s []int
+ var f1 func(int) float64
+ var f2 func(float64, int) float64
+ _ = Map[int](s, f1)
+ _ = Map(s, f1)
+ _ = Reduce[int](s, 0, f2)
+ _ = Reduce(s, 0, f2)
+}
+
// If we have a receiver of pointer type (below: *T) we must ignore
// the pointer in the implementation of the method lookup because
-// the type bound of T is an interface an pointer to interface types
+// the type bound of T is an interface and pointer to interface types
// have no methods and then the lookup would fail.
type C[T any] interface {
m()
func (*T) m2()
func _() {
- f2[T /* ERROR wrong method signature */]()
+ // TODO(rFindley) this error should be positioned on the 'T'.
+ f2 /* ERROR wrong method signature */ [T]()
f2[*T]()
}