aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2023-08-14 15:56:08 -0700
committerGopher Robot <gobot@golang.org>2023-08-17 21:05:04 +0000
commitd91843ff67f7acc433bd169d2b189656627ebbb8 (patch)
tree4349fc7f75291bcfaf2e807f7a4f3a66957445ef
parent7437db10858fa147da00a2b67444ed42200bf161 (diff)
downloadgo-d91843ff67f7acc433bd169d2b189656627ebbb8.tar.gz
go-d91843ff67f7acc433bd169d2b189656627ebbb8.zip
[release-branch.go1.21] 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 #61932. 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> Reviewed-on: https://go-review.googlesource.com/c/go/+/519417 Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
-rw-r--r--src/cmd/compile/internal/types2/call.go21
-rw-r--r--src/cmd/compile/internal/types2/issues_test.go20
-rw-r--r--src/go/types/call.go21
-rw-r--r--src/go/types/issues_test.go22
4 files changed, 60 insertions, 24 deletions
diff --git a/src/cmd/compile/internal/types2/call.go b/src/cmd/compile/internal/types2/call.go
index af27339967..f7a8a8dfcd 100644
--- a/src/cmd/compile/internal/types2/call.go
+++ b/src/cmd/compile/internal/types2/call.go
@@ -610,20 +610,17 @@ func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []T
return // error already reported
}
- // compute result signature: instantiate if needed
- rsig = sig
+ // update result signature: instantiate if needed
if n > 0 {
rsig = check.instantiateSignature(call.Pos(), call.Fun, sig, targs[:n], xlist)
- }
-
- // Optimization: Only if the callee's parameter list was adjusted do we need to
- // compute it from the adjusted list; otherwise we can simply use the result
- // signature's parameter list. We only need the n type parameters and arguments
- // of the callee.
- if n > 0 && adjusted {
- sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(tparams[:n], targs[:n]), nil, check.context()).(*Tuple)
- } else {
- sigParams = rsig.params
+ // If the callee's parameter list was adjusted we need to update (instantiate)
+ // it separately. Otherwise we can simply use the result signature's parameter
+ // list.
+ if adjusted {
+ sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(tparams[:n], targs[:n]), nil, check.context()).(*Tuple)
+ } else {
+ sigParams = rsig.params
+ }
}
// compute argument signatures: instantiate if needed
diff --git a/src/cmd/compile/internal/types2/issues_test.go b/src/cmd/compile/internal/types2/issues_test.go
index 5e0ae213dc..9f67ad0902 100644
--- a/src/cmd/compile/internal/types2/issues_test.go
+++ b/src/cmd/compile/internal/types2/issues_test.go
@@ -900,3 +900,23 @@ func _cgoCheckResult(interface{})
*boolFieldAddr(cfg, "go115UsesCgo") = true
})
}
+
+func TestIssue61931(t *testing.T) {
+ const src = `
+package p
+
+func A(func(any), ...any) {}
+func B[T any](T) {}
+
+func _() {
+ A(B, nil // syntax error: missing ',' before newline in argument list
+}
+`
+ f, err := syntax.Parse(syntax.NewFileBase(pkgName(src)), strings.NewReader(src), func(error) {}, nil, 0)
+ if err == nil {
+ t.Fatal("expected syntax error")
+ }
+
+ var conf Config
+ conf.Check(f.PkgName.Value, []*syntax.File{f}, nil) // must not panic
+}
diff --git a/src/go/types/call.go b/src/go/types/call.go
index 7258ab1237..8a3cec7309 100644
--- a/src/go/types/call.go
+++ b/src/go/types/call.go
@@ -612,20 +612,17 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type
return // error already reported
}
- // compute result signature: instantiate if needed
- rsig = sig
+ // update result signature: instantiate if needed
if n > 0 {
rsig = check.instantiateSignature(call.Pos(), call.Fun, sig, targs[:n], xlist)
- }
-
- // Optimization: Only if the callee's parameter list was adjusted do we need to
- // compute it from the adjusted list; otherwise we can simply use the result
- // signature's parameter list. We only need the n type parameters and arguments
- // of the callee.
- if n > 0 && adjusted {
- sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(tparams[:n], targs[:n]), nil, check.context()).(*Tuple)
- } else {
- sigParams = rsig.params
+ // If the callee's parameter list was adjusted we need to update (instantiate)
+ // it separately. Otherwise we can simply use the result signature's parameter
+ // list.
+ if adjusted {
+ sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(tparams[:n], targs[:n]), nil, check.context()).(*Tuple)
+ } else {
+ sigParams = rsig.params
+ }
}
// compute argument signatures: instantiate if needed
diff --git a/src/go/types/issues_test.go b/src/go/types/issues_test.go
index 1a784aae21..64e1c20d7e 100644
--- a/src/go/types/issues_test.go
+++ b/src/go/types/issues_test.go
@@ -10,6 +10,7 @@ import (
"fmt"
"go/ast"
"go/importer"
+ "go/parser"
"go/token"
"internal/testenv"
"regexp"
@@ -908,3 +909,24 @@ func _cgoCheckResult(interface{})
*boolFieldAddr(cfg, "go115UsesCgo") = true
})
}
+
+func TestIssue61931(t *testing.T) {
+ const src = `
+package p
+
+func A(func(any), ...any) {}
+func B[T any](T) {}
+
+func _() {
+ A(B, nil // syntax error: missing ',' before newline in argument list
+}
+`
+ fset := token.NewFileSet()
+ f, err := parser.ParseFile(fset, pkgName(src), src, 0)
+ if err == nil {
+ t.Fatal("expected syntax error")
+ }
+
+ var conf Config
+ conf.Check(f.Name.Name, fset, []*ast.File{f}, nil) // must not panic
+}