]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: isParameterized must be able to handle tuples
authorRobert Griesemer <gri@golang.org>
Sat, 29 Apr 2023 00:46:00 +0000 (17:46 -0700)
committerGopher Robot <gobot@golang.org>
Mon, 1 May 2023 17:49:13 +0000 (17:49 +0000)
CL 484615 rewrote isParameterized by handling tuple types only where
they occur (function signatures). However, isParameterized is also
called from Checker.callExpr, with a result parameter list which
is a tuple. This CL handles tuples again.

Fixes #59890.

Change-Id: I35159ff65f23322432557e6abcab939933933d40
Reviewed-on: https://go-review.googlesource.com/c/go/+/490695
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>

src/cmd/compile/internal/types2/call.go
src/cmd/compile/internal/types2/infer.go
src/go/types/call.go
src/go/types/infer.go
src/internal/types/testdata/fixedbugs/issue59890.go [new file with mode: 0644]

index 7e8fce43506ff861a945047acc9f489738ed770c..20cde9f44ed3a2d5b5df4cc606ada37e065e0b59 100644 (file)
@@ -329,8 +329,8 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
        x.expr = call
        check.hasCallOrRecv = true
 
-       // if type inference failed, a parametrized result must be invalidated
-       // (operands cannot have a parametrized type)
+       // if type inference failed, a parameterized result must be invalidated
+       // (operands cannot have a parameterized type)
        if x.mode == value && sig.TypeParams().Len() > 0 && isParameterized(sig.TypeParams().list(), x.typ) {
                x.mode = invalid
        }
index 46f461ea0933521316bd044d24b19ea10ac3c482..dbe621cded56189c2cc2035c756f8118bcaad659 100644 (file)
@@ -498,9 +498,13 @@ func (w *tpWalker) isParameterized(typ Type) (res bool) {
        case *Pointer:
                return w.isParameterized(t.base)
 
-       // case *Tuple:
-       //      This case should not occur because tuples only appear
-       //      in signatures where they are handled explicitly.
+       case *Tuple:
+               // This case does not occur from within isParameterized
+               // because tuples only appear in signatures where they
+               // are handled explicitly. But isParameterized is also
+               // called by Checker.callExpr with a function result tuple
+               // if instantiation failed (go.dev/issue/59890).
+               return t != nil && w.varList(t.vars)
 
        case *Signature:
                // t.tparams may not be nil if we are looking at a signature
index 418de06e76887c68f873e2c6d52bde090844410e..979de2338f27293b30863dfeed9c13827e51d1e3 100644 (file)
@@ -334,8 +334,8 @@ func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
        x.expr = call
        check.hasCallOrRecv = true
 
-       // if type inference failed, a parametrized result must be invalidated
-       // (operands cannot have a parametrized type)
+       // if type inference failed, a parameterized result must be invalidated
+       // (operands cannot have a parameterized type)
        if x.mode == value && sig.TypeParams().Len() > 0 && isParameterized(sig.TypeParams().list(), x.typ) {
                x.mode = invalid
        }
index f24c729d7af79c870c74e3984c049f902a8dae10..3aa66105c409ec835d21953ed94ac6152ae7d5df 100644 (file)
@@ -500,9 +500,13 @@ func (w *tpWalker) isParameterized(typ Type) (res bool) {
        case *Pointer:
                return w.isParameterized(t.base)
 
-       // case *Tuple:
-       //      This case should not occur because tuples only appear
-       //      in signatures where they are handled explicitly.
+       case *Tuple:
+               // This case does not occur from within isParameterized
+               // because tuples only appear in signatures where they
+               // are handled explicitly. But isParameterized is also
+               // called by Checker.callExpr with a function result tuple
+               // if instantiation failed (go.dev/issue/59890).
+               return t != nil && w.varList(t.vars)
 
        case *Signature:
                // t.tparams may not be nil if we are looking at a signature
diff --git a/src/internal/types/testdata/fixedbugs/issue59890.go b/src/internal/types/testdata/fixedbugs/issue59890.go
new file mode 100644 (file)
index 0000000..ed7afd9
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _() { g /* ERROR "cannot infer T" */ () }
+
+func g[T any]() (_ /* ERROR "cannot use _ as value or type" */, int) { panic(0) }
+
+// test case from issue
+
+var _ = append(f /* ERROR "cannot infer T" */ ()())
+
+func f[T any]() (_ /* ERROR "cannot use _" */, _ /* ERROR "cannot use _" */, int) {
+       panic("not implemented")
+}