Skip to content

Commit f2f5979

Browse files
griesemergopherbot
authored andcommitted
go/types, types2: use correct parameter list when checking argument passing
The existing code was simply wrong: we cannot ever use the result signature parameter list (rsig.params) if sigParams was adjusted for variadic functions. If it was adjusted, we always must either use sigParams or its separately instantiated version. In the condition "n > 0 && adjusted", the "n > 0" should have been in either of the respective "if statement" branches. Simplified the code by merging with the result signature parameter update. Fixes #61931. Change-Id: I5d39bc8bbc4dd85c7c985055d29532b4b176955e Reviewed-on: https://go-review.googlesource.com/c/go/+/519456 Auto-Submit: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Robert Griesemer <gri@google.com> Reviewed-by: Robert Griesemer <gri@google.com> Reviewed-by: Robert Findley <rfindley@google.com>
1 parent 3be2176 commit f2f5979

File tree

4 files changed

+60
-24
lines changed

4 files changed

+60
-24
lines changed

src/cmd/compile/internal/types2/call.go

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -610,20 +610,17 @@ func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []T
610610
return // error already reported
611611
}
612612

613-
// compute result signature: instantiate if needed
614-
rsig = sig
613+
// update result signature: instantiate if needed
615614
if n > 0 {
616615
rsig = check.instantiateSignature(call.Pos(), call.Fun, sig, targs[:n], xlist)
617-
}
618-
619-
// Optimization: Only if the callee's parameter list was adjusted do we need to
620-
// compute it from the adjusted list; otherwise we can simply use the result
621-
// signature's parameter list. We only need the n type parameters and arguments
622-
// of the callee.
623-
if n > 0 && adjusted {
624-
sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(tparams[:n], targs[:n]), nil, check.context()).(*Tuple)
625-
} else {
626-
sigParams = rsig.params
616+
// If the callee's parameter list was adjusted we need to update (instantiate)
617+
// it separately. Otherwise we can simply use the result signature's parameter
618+
// list.
619+
if adjusted {
620+
sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(tparams[:n], targs[:n]), nil, check.context()).(*Tuple)
621+
} else {
622+
sigParams = rsig.params
623+
}
627624
}
628625

629626
// compute argument signatures: instantiate if needed

src/cmd/compile/internal/types2/issues_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,3 +900,23 @@ func _cgoCheckResult(interface{})
900900
*boolFieldAddr(cfg, "go115UsesCgo") = true
901901
})
902902
}
903+
904+
func TestIssue61931(t *testing.T) {
905+
const src = `
906+
package p
907+
908+
func A(func(any), ...any) {}
909+
func B[T any](T) {}
910+
911+
func _() {
912+
A(B, nil // syntax error: missing ',' before newline in argument list
913+
}
914+
`
915+
f, err := syntax.Parse(syntax.NewFileBase(pkgName(src)), strings.NewReader(src), func(error) {}, nil, 0)
916+
if err == nil {
917+
t.Fatal("expected syntax error")
918+
}
919+
920+
var conf Config
921+
conf.Check(f.PkgName.Value, []*syntax.File{f}, nil) // must not panic
922+
}

src/go/types/call.go

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -612,20 +612,17 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type
612612
return // error already reported
613613
}
614614

615-
// compute result signature: instantiate if needed
616-
rsig = sig
615+
// update result signature: instantiate if needed
617616
if n > 0 {
618617
rsig = check.instantiateSignature(call.Pos(), call.Fun, sig, targs[:n], xlist)
619-
}
620-
621-
// Optimization: Only if the callee's parameter list was adjusted do we need to
622-
// compute it from the adjusted list; otherwise we can simply use the result
623-
// signature's parameter list. We only need the n type parameters and arguments
624-
// of the callee.
625-
if n > 0 && adjusted {
626-
sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(tparams[:n], targs[:n]), nil, check.context()).(*Tuple)
627-
} else {
628-
sigParams = rsig.params
618+
// If the callee's parameter list was adjusted we need to update (instantiate)
619+
// it separately. Otherwise we can simply use the result signature's parameter
620+
// list.
621+
if adjusted {
622+
sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(tparams[:n], targs[:n]), nil, check.context()).(*Tuple)
623+
} else {
624+
sigParams = rsig.params
625+
}
629626
}
630627

631628
// compute argument signatures: instantiate if needed

src/go/types/issues_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"fmt"
1111
"go/ast"
1212
"go/importer"
13+
"go/parser"
1314
"go/token"
1415
"internal/testenv"
1516
"regexp"
@@ -908,3 +909,24 @@ func _cgoCheckResult(interface{})
908909
*boolFieldAddr(cfg, "go115UsesCgo") = true
909910
})
910911
}
912+
913+
func TestIssue61931(t *testing.T) {
914+
const src = `
915+
package p
916+
917+
func A(func(any), ...any) {}
918+
func B[T any](T) {}
919+
920+
func _() {
921+
A(B, nil // syntax error: missing ',' before newline in argument list
922+
}
923+
`
924+
fset := token.NewFileSet()
925+
f, err := parser.ParseFile(fset, pkgName(src), src, 0)
926+
if err == nil {
927+
t.Fatal("expected syntax error")
928+
}
929+
930+
var conf Config
931+
conf.Check(f.Name.Name, fset, []*ast.File{f}, nil) // must not panic
932+
}

0 commit comments

Comments
 (0)