Fixes #60346.
Change-Id: I14834858d53fd80f8261ec0c8d0eccdd75a1bc2b
Reviewed-on: https://go-review.googlesource.com/c/go/+/496917
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
}
// genericExprList is like exprList but result operands may be uninstantiated or partially
-// instantiated generic functions.
+// instantiated generic functions (where constraint information is insufficient to infer
+// the missing type arguments) for Go 1.21 and later.
// For each non-generic or uninstantiated generic operand, the corresponding targsList and
// xlistList elements do not exist (targsList and xlistList are nil) or the elements are nil.
// For each partially instantiated generic function operand, the corresponding targsList and
}()
}
- if n := len(elist); n == 1 {
+ // Before Go 1.21, uninstantiated or partially instantiated argument functions are
+ // nor permitted. Checker.funcInst must infer missing type arguments in that case.
+ infer := true // for -lang < go1.21
+ n := len(elist)
+ if n > 0 && check.allowVersion(check.pkg, elist[0], go1_21) {
+ infer = false
+ }
+
+ if n == 1 {
// single value (possibly a partially instantiated function), or a multi-valued expression
e := elist[0]
var x operand
if inst, _ := e.(*syntax.IndexExpr); inst != nil && check.indexExpr(&x, inst) {
// x is a generic function.
- targs, xlist := check.funcInst(nil, x.Pos(), &x, inst, false)
+ targs, xlist := check.funcInst(nil, x.Pos(), &x, inst, infer)
if targs != nil {
// x was not instantiated: collect the (partial) type arguments.
targsList = [][]Type{targs}
var x operand
if inst, _ := e.(*syntax.IndexExpr); inst != nil && check.indexExpr(&x, inst) {
// x is a generic function.
- targs, xlist := check.funcInst(nil, x.Pos(), &x, inst, false)
+ targs, xlist := check.funcInst(nil, x.Pos(), &x, inst, infer)
if targs != nil {
// x was not instantiated: collect the (partial) type arguments.
targsList[i] = targs
}
// genericExprList is like exprList but result operands may be uninstantiated or partially
-// instantiated generic functions.
+// instantiated generic functions (where constraint information is insufficient to infer
+// the missing type arguments) for Go 1.21 and later.
// For each non-generic or uninstantiated generic operand, the corresponding targsList and
// xlistList elements do not exist (targsList and xlistList are nil) or the elements are nil.
// For each partially instantiated generic function operand, the corresponding targsList and
}()
}
- if n := len(elist); n == 1 {
+ // Before Go 1.21, uninstantiated or partially instantiated argument functions are
+ // nor permitted. Checker.funcInst must infer missing type arguments in that case.
+ infer := true // for -lang < go1.21
+ n := len(elist)
+ if n > 0 && check.allowVersion(check.pkg, elist[0], go1_21) {
+ infer = false
+ }
+
+ if n == 1 {
// single value (possibly a partially instantiated function), or a multi-valued expression
e := elist[0]
var x operand
if ix := typeparams.UnpackIndexExpr(e); ix != nil && check.indexExpr(&x, ix) {
// x is a generic function.
- targs, xlist := check.funcInst(nil, x.Pos(), &x, ix, false)
+ targs, xlist := check.funcInst(nil, x.Pos(), &x, ix, infer)
if targs != nil {
// x was not instantiated: collect the (partial) type arguments.
targsList = [][]Type{targs}
var x operand
if ix := typeparams.UnpackIndexExpr(e); ix != nil && check.indexExpr(&x, ix) {
// x is a generic function.
- targs, xlist := check.funcInst(nil, x.Pos(), &x, ix, false)
+ targs, xlist := check.funcInst(nil, x.Pos(), &x, ix, infer)
if targs != nil {
// x was not instantiated: collect the (partial) type arguments.
targsList[i] = targs
--- /dev/null
+// -lang=go1.20
+
+// 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 F[P any, Q *P](p P) {}
+
+var _ = F[int]
+
+func G[R any](func(R)) {}
+
+func _() {
+ G(F[int])
+}