Skip to content

Commit cae1343

Browse files
committed
matchFuncType error test
1 parent 01d1d7d commit cae1343

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

ast.go

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -643,11 +643,7 @@ retry:
643643
src, pos := pkg.cb.loadExpr(fn.Src)
644644
pkg.cb.panicCodeErrorf(&pos, "cannot call non-function %s (type %v)", src, fn.Type)
645645
}
646-
at := func() string {
647-
src, _ := pkg.cb.loadExpr(fn.Src)
648-
return "argument to " + src
649-
}
650-
if err = matchFuncType(pkg, args, flags, sig, at); err != nil {
646+
if err = matchFuncType(pkg, args, flags, sig, fn); err != nil {
651647
return
652648
}
653649
tyRet := toRetType(sig.Results(), it)
@@ -751,7 +747,7 @@ func toRetType(t *types.Tuple, it *instantiated) types.Type {
751747
}
752748

753749
func matchFuncType(
754-
pkg *Package, args []*internal.Elem, flags InstrFlags, sig *types.Signature, at interface{}) error {
750+
pkg *Package, args []*internal.Elem, flags InstrFlags, sig *types.Signature, fn *internal.Elem) error {
755751
var t *types.Tuple
756752
n := len(args)
757753
if len(args) == 1 && checkTuple(&t, args[0].Type) {
@@ -768,6 +764,15 @@ func matchFuncType(
768764
}
769765
}
770766
}
767+
var at interface{}
768+
if fn == nil {
769+
at = "closure argument" // fn = nil means it is a closure
770+
} else {
771+
at = func() string {
772+
src, _ := pkg.cb.loadExpr(fn.Src)
773+
return "argument to " + src
774+
}
775+
}
771776
if sig.Variadic() {
772777
if (flags & InstrFlagEllipsis) == 0 {
773778
n1 := getParamLen(sig) - 1
@@ -784,10 +789,25 @@ func matchFuncType(
784789
return matchElemType(pkg, args[n1:], tyVariadic.Elem(), at)
785790
}
786791
} else if (flags & InstrFlagEllipsis) != 0 {
787-
return errors.New("TODO: call with ... to non variadic function")
792+
var caller string
793+
var pos token.Position
794+
if fn != nil {
795+
caller, pos = pkg.cb.loadExpr(fn.Src)
796+
}
797+
return pkg.cb.newCodeError(&pos, fmt.Sprintf("invalid use of ... in call to %v", caller))
788798
}
789799
if nreq := getParamLen(sig); nreq != n {
790-
return fmt.Errorf("TODO: unmatched function parameters count, requires %v but got %v", nreq, n)
800+
fewOrMany := "few"
801+
if n > nreq {
802+
fewOrMany = "many"
803+
}
804+
var caller string
805+
var pos token.Position
806+
if fn != nil {
807+
caller, pos = pkg.cb.loadExpr(fn.Src)
808+
}
809+
return pkg.cb.newCodeError(&pos, fmt.Sprintf(
810+
"too %s arguments in call to %s\n\thave (%v)\n\twant %v", fewOrMany, caller, getTypes(args), sig.Params()))
791811
}
792812
return matchFuncArgs(pkg, args, sig, at)
793813
}

codebuild.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ func (p *CodeBuilder) CallInlineClosureStart(sig *types.Signature, arity int, el
515515
if ellipsis {
516516
flags = InstrFlagEllipsis
517517
}
518-
if err := matchFuncType(pkg, args, flags, sig, "closure argument"); err != nil {
518+
if err := matchFuncType(pkg, args, flags, sig, nil); err != nil {
519519
panic(err)
520520
}
521521
n1 := getParamLen(sig) - 1

error_msg_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,13 @@ func TestErrFuncCall(t *testing.T) {
465465
Val(ctxRef(pkg, "a")).CallWith(0, false, source("a()", 2, 10)).
466466
End()
467467
})
468+
codeErrorTest(t, `./foo.gop:2:10: invalid use of ... in call to foo(a...)`,
469+
func(pkg *gox.Package) {
470+
pkg.NewFunc(nil, "foo", nil, nil, false).BodyStart(pkg).
471+
NewVar(types.Typ[types.Int], "a").
472+
Val(ctxRef(pkg, "foo"), source("foo", 2, 2)).Val(ctxRef(pkg, "a")).CallWith(1, true, source("foo(a...)", 2, 10)).
473+
End()
474+
})
468475
codeErrorTest(t, `./foo.gop:3:5: cannot use a (type bool) as type int in argument to foo(a)`,
469476
func(pkg *gox.Package) {
470477
retInt := pkg.NewParam(position(1, 10), "", types.Typ[types.Int])

0 commit comments

Comments
 (0)