Skip to content

Commit 629453d

Browse files
committed
Fix: use CallTyped for methods as well
1 parent 9009d4d commit 629453d

File tree

3 files changed

+33
-21
lines changed

3 files changed

+33
-21
lines changed

checker/checker.go

+15-18
Original file line numberDiff line numberDiff line change
@@ -511,44 +511,41 @@ func (v *visitor) checkFunc(fn reflect.Type, method bool, node *ast.CallNode, na
511511
return v.error(node, "func %v returns more then two values", name)
512512
}
513513

514-
numIn := fn.NumIn()
515-
516514
// If func is method on an env, first argument should be a receiver,
517-
// and actual arguments less than numIn by one.
515+
// and actual arguments less than fnNumIn by one.
516+
fnNumIn := fn.NumIn()
518517
if method {
519-
numIn--
518+
fnNumIn--
519+
}
520+
// Skip first argument in case of the receiver.
521+
fnInOffset := 0
522+
if method {
523+
fnInOffset = 1
520524
}
521525

522526
if fn.IsVariadic() {
523-
if len(arguments) < numIn-1 {
527+
if len(arguments) < fnNumIn-1 {
524528
return v.error(node, "not enough arguments to call %v", name)
525529
}
526530
} else {
527-
if len(arguments) > numIn {
531+
if len(arguments) > fnNumIn {
528532
return v.error(node, "too many arguments to call %v", name)
529533
}
530-
if len(arguments) < numIn {
534+
if len(arguments) < fnNumIn {
531535
return v.error(node, "not enough arguments to call %v", name)
532536
}
533537
}
534538

535-
offset := 0
536-
537-
// Skip first argument in case of the receiver.
538-
if method {
539-
offset = 1
540-
}
541-
542539
for i, arg := range arguments {
543540
t, _ := v.visit(arg)
544541

545542
var in reflect.Type
546-
if fn.IsVariadic() && i >= numIn-1 {
543+
if fn.IsVariadic() && i >= fnNumIn-1 {
547544
// For variadic arguments fn(xs ...int), go replaces type of xs (int) with ([]int).
548545
// As we compare arguments one by one, we need underling type.
549546
in = fn.In(fn.NumIn() - 1).Elem()
550547
} else {
551-
in = fn.In(i + offset)
548+
in = fn.In(i + fnInOffset)
552549
}
553550

554551
if isIntegerOrArithmeticOperation(arg) {
@@ -583,11 +580,11 @@ func (v *visitor) checkFunc(fn reflect.Type, method bool, node *ast.CallNode, na
583580
continue funcTypes
584581
}
585582
}
586-
if typed.NumIn() != fn.NumIn() {
583+
if typed.NumIn() != fnNumIn {
587584
continue
588585
}
589586
for j := 0; j < typed.NumIn(); j++ {
590-
if typed.In(j) != fn.In(j) {
587+
if typed.In(j) != fn.In(j+fnInOffset) {
591588
continue funcTypes
592589
}
593590
}

checker/checker_test.go

+14-3
Original file line numberDiff line numberDiff line change
@@ -714,11 +714,22 @@ func TestCheck_CallFastTyped(t *testing.T) {
714714
tree, err := parser.Parse("fn([1, 2], 'bar')")
715715
require.NoError(t, err)
716716

717-
config := conf.New(env)
718-
719-
_, err = checker.Check(tree, config)
717+
_, err = checker.Check(tree, conf.New(env))
720718
require.NoError(t, err)
721719

722720
require.False(t, tree.Node.(*ast.CallNode).Fast)
723721
require.Equal(t, 22, tree.Node.(*ast.CallNode).Typed)
724722
}
723+
724+
func TestCheck_CallFastTyped_Method(t *testing.T) {
725+
env := mock.Env{}
726+
727+
tree, err := parser.Parse("FuncTyped('bar')")
728+
require.NoError(t, err)
729+
730+
_, err = checker.Check(tree, conf.New(env))
731+
require.NoError(t, err)
732+
733+
require.False(t, tree.Node.(*ast.CallNode).Fast)
734+
require.Equal(t, 42, tree.Node.(*ast.CallNode).Typed)
735+
}

test/mock/mock.go

+4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ func (p Env) Func() int {
4343
return 0
4444
}
4545

46+
func (p Env) FuncTyped(_ string) int {
47+
return 2023
48+
}
49+
4650
type Embed struct {
4751
EmbedEmbed
4852
EmbedString string

0 commit comments

Comments
 (0)