]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: explicitly look for nil type arguments in infer
authorRobert Griesemer <gri@golang.org>
Tue, 9 May 2023 21:02:07 +0000 (14:02 -0700)
committerGopher Robot <gobot@golang.org>
Wed, 10 May 2023 13:59:32 +0000 (13:59 +0000)
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>

src/cmd/compile/internal/types2/infer.go
src/go/types/infer.go

index 94a59f94bbf777dc2305e1ac8cb9b6ef18fef390..d8c81820f8884b9df00d77e231dfc489fdfe6cd4 100644 (file)
@@ -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
index 661ff771c838e03fb81a5e2d3f87ae5b57aa4191..9c31d6adf62c8c9512e060f02645e1a3536286f4 100644 (file)
@@ -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