]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types, types2: use correct parameter list when checking argument passing
authorRobert Griesemer <gri@golang.org>
Mon, 14 Aug 2023 22:56:08 +0000 (15:56 -0700)
committerGopher Robot <gobot@golang.org>
Tue, 15 Aug 2023 21:01:03 +0000 (21:01 +0000)
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>
src/cmd/compile/internal/types2/call.go
src/cmd/compile/internal/types2/issues_test.go
src/go/types/call.go
src/go/types/issues_test.go

index af273399672a8e905a33adf79361e748b25c2cb7..f7a8a8dfcd3c040a912b231940983e839ad901c0 100644 (file)
@@ -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
index 5e0ae213dcb2efa2d2888118f0307ccaa44071ea..9f67ad09025116deef80945bd08d12c88b66f352 100644 (file)
@@ -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
+}
index 7258ab1237cb7bbbed673cd3739fb2e04caef888..8a3cec7309eae53573185f5926c0fc7356fe64e9 100644 (file)
@@ -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
index 1a784aae213d232d13fed910f4337c741dcf66a0..64e1c20d7eb1c31198dd13f8c857e6f05272923e 100644 (file)
@@ -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
+}