1
0
mirror of https://github.com/golang/go synced 2024-11-23 00:20:12 -07:00

go/types, types2: isParameterized must be able to handle tuples

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>
This commit is contained in:
Robert Griesemer 2023-04-28 17:46:00 -07:00 committed by Gopher Robot
parent 63edd418b6
commit 73a4684caa
5 changed files with 35 additions and 10 deletions

View 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
}

View 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

View 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
}

View 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

View File

@ -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")
}