aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2023-05-09 14:02:07 -0700
committerGopher Robot <gobot@golang.org>2023-05-10 13:59:32 +0000
commitd9dce0cd26a1e5df0aa2dbbecde4515807be929e (patch)
treecba9742676717ba0136ed3709c97b7f52ed4f5a0
parent607a04588886b3d605500942f20de9dbab02ed9d (diff)
downloadgo-d9dce0cd26a1e5df0aa2dbbecde4515807be929e.tar.xz
go/types, types2: explicitly look for nil type arguments in infer
Don't assume we have all type arguments if the number of type arguments matches the number of type parameters. Instead, look explicitly for nil type arguments in the provided targs. Preparation for type inference with type arguments provided for type parameters of generic function arguments passed to other functions. For #59338. Change-Id: I00918cd5ed06ae3277b4e41a3641063e0f53fef0 Reviewed-on: https://go-review.googlesource.com/c/go/+/494115 Reviewed-by: Robert Griesemer <gri@google.com> Run-TryBot: Robert Griesemer <gri@google.com> Reviewed-by: Robert Findley <rfindley@google.com> Auto-Submit: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
-rw-r--r--src/cmd/compile/internal/types2/infer.go20
-rw-r--r--src/go/types/infer.go20
2 files changed, 26 insertions, 14 deletions
diff --git a/src/cmd/compile/internal/types2/infer.go b/src/cmd/compile/internal/types2/infer.go
index 94a59f94bb..d8c81820f8 100644
--- a/src/cmd/compile/internal/types2/infer.go
+++ b/src/cmd/compile/internal/types2/infer.go
@@ -29,10 +29,7 @@ const enableReverseTypeInference = true // disable for debugging
func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type, params *Tuple, args []*operand) (inferred []Type) {
if debug {
defer func() {
- assert(inferred == nil || len(inferred) == len(tparams))
- for _, targ := range inferred {
- assert(targ != nil)
- }
+ assert(inferred == nil || len(inferred) == len(tparams) && !containsNil(inferred))
}()
}
@@ -47,14 +44,13 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
n := len(tparams)
assert(n > 0 && len(targs) <= n)
- // Function parameters and arguments must match in number.
+ // Parameters and arguments must match in number.
assert(params.Len() == len(args))
// If we already have all type arguments, we're done.
- if len(targs) == n {
+ if len(targs) == n && !containsNil(targs) {
return targs
}
- // len(targs) < n
// Make sure we have a "full" list of type arguments, some of which may
// be nil (unknown). Make a copy so as to not clobber the incoming slice.
@@ -440,6 +436,16 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
return
}
+// containsNil reports whether list contains a nil entry.
+func containsNil(list []Type) bool {
+ for _, t := range list {
+ if t == nil {
+ return true
+ }
+ }
+ return false
+}
+
// renameTParams renames the type parameters in the given type such that each type
// parameter is given a new identity. renameTParams returns the new type parameters
// and updated type. If the result type is unchanged from the argument type, none
diff --git a/src/go/types/infer.go b/src/go/types/infer.go
index 661ff771c8..9c31d6adf6 100644
--- a/src/go/types/infer.go
+++ b/src/go/types/infer.go
@@ -31,10 +31,7 @@ const enableReverseTypeInference = true // disable for debugging
func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type, params *Tuple, args []*operand) (inferred []Type) {
if debug {
defer func() {
- assert(inferred == nil || len(inferred) == len(tparams))
- for _, targ := range inferred {
- assert(targ != nil)
- }
+ assert(inferred == nil || len(inferred) == len(tparams) && !containsNil(inferred))
}()
}
@@ -49,14 +46,13 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
n := len(tparams)
assert(n > 0 && len(targs) <= n)
- // Function parameters and arguments must match in number.
+ // Parameters and arguments must match in number.
assert(params.Len() == len(args))
// If we already have all type arguments, we're done.
- if len(targs) == n {
+ if len(targs) == n && !containsNil(targs) {
return targs
}
- // len(targs) < n
// Make sure we have a "full" list of type arguments, some of which may
// be nil (unknown). Make a copy so as to not clobber the incoming slice.
@@ -442,6 +438,16 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
return
}
+// containsNil reports whether list contains a nil entry.
+func containsNil(list []Type) bool {
+ for _, t := range list {
+ if t == nil {
+ return true
+ }
+ }
+ return false
+}
+
// renameTParams renames the type parameters in the given type such that each type
// parameter is given a new identity. renameTParams returns the new type parameters
// and updated type. If the result type is unchanged from the argument type, none