]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types, types2: unifier constructor to accept type parameters and arguments
authorRobert Griesemer <gri@golang.org>
Mon, 30 Jan 2023 22:44:42 +0000 (14:44 -0800)
committerGopher Robot <gobot@golang.org>
Wed, 1 Feb 2023 21:30:36 +0000 (21:30 +0000)
Change-Id: I2f20cb8f1dd95ba97de7630d0bbe6dee4e019f94
Reviewed-on: https://go-review.googlesource.com/c/go/+/463990
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>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/types2/infer.go
src/cmd/compile/internal/types2/unify.go
src/go/types/infer.go
src/go/types/unify.go

index b5565b78b025fb936398615df28006910ded629d..b9defb3e81aa214cb85cec5df9442b1d542f9711 100644 (file)
@@ -135,14 +135,7 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
        // Unify parameter and argument types for generic parameters with typed arguments
        // and collect the indices of generic parameters with untyped arguments.
        // Terminology: generic parameter = function parameter with a type-parameterized type
-       u := newUnifier(tparams)
-
-       // Set the type arguments which we know already.
-       for i, targ := range targs {
-               if targ != nil {
-                       u.set(tparams[i], targ)
-               }
-       }
+       u := newUnifier(tparams, targs)
 
        errorf := func(kind string, tpar, targ Type, arg *operand) {
                // provide a better error message if we can
@@ -462,14 +455,7 @@ func (check *Checker) inferB(tparams []*TypeParam, targs []Type) (types []Type,
        }
 
        // Unify type parameters with their constraints.
-       u := newUnifier(tparams)
-
-       // Set the type arguments which we know already.
-       for i, targ := range targs {
-               if targ != nil {
-                       u.set(tparams[i], targ)
-               }
-       }
+       u := newUnifier(tparams, targs)
 
        // Repeatedly apply constraint type inference as long as
        // there are still unknown type arguments and progress is
index 221700b33d42b4c979b02e5dfa34628f9039b1a9..bdafdf9c6a9b9fb6127e06758dbf3f4244edc758 100644 (file)
@@ -61,15 +61,23 @@ type unifier struct {
        depth   int // recursion depth during unification
 }
 
-// newUnifier returns a new unifier initialized with the given type parameter list.
-func newUnifier(tparams []*TypeParam) *unifier {
+// newUnifier returns a new unifier initialized with the given type parameter
+// and corresponding type argument lists. The type argument list may be shorter
+// than the type parameter list, and it may contain nil types. Matching type
+// parameters and arguments must have the same index.
+func newUnifier(tparams []*TypeParam, targs []Type) *unifier {
+       assert(len(tparams) >= len(targs))
        handles := make(map[*TypeParam]*Type, len(tparams))
        // Allocate all handles up-front: in a correct program, all type parameters
        // must be resolved and thus eventually will get a handle.
        // Also, sharing of handles caused by unified type parameters is rare and
        // so it's ok to not optimize for that case (and delay handle allocation).
-       for _, x := range tparams {
-               handles[x] = new(Type)
+       for i, x := range tparams {
+               var t Type
+               if i < len(targs) {
+                       t = targs[i]
+               }
+               handles[x] = &t
        }
        return &unifier{tparams, handles, 0}
 }
index f86cc3b266433ef99ba6a16f413d0477c89b4ad0..70d256bed7ef3e0e16fcc754619f3e6deaf97491 100644 (file)
@@ -137,14 +137,7 @@ func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type,
        // Unify parameter and argument types for generic parameters with typed arguments
        // and collect the indices of generic parameters with untyped arguments.
        // Terminology: generic parameter = function parameter with a type-parameterized type
-       u := newUnifier(tparams)
-
-       // Set the type arguments which we know already.
-       for i, targ := range targs {
-               if targ != nil {
-                       u.set(tparams[i], targ)
-               }
-       }
+       u := newUnifier(tparams, targs)
 
        errorf := func(kind string, tpar, targ Type, arg *operand) {
                // provide a better error message if we can
@@ -464,14 +457,7 @@ func (check *Checker) inferB(tparams []*TypeParam, targs []Type) (types []Type,
        }
 
        // Unify type parameters with their constraints.
-       u := newUnifier(tparams)
-
-       // Set the type arguments which we know already.
-       for i, targ := range targs {
-               if targ != nil {
-                       u.set(tparams[i], targ)
-               }
-       }
+       u := newUnifier(tparams, targs)
 
        // Repeatedly apply constraint type inference as long as
        // there are still unknown type arguments and progress is
index 094aa22fa6a4b111689ffe40525f9d5c658b5d9f..03c4739814f4a17062041146613d5567a08fcff3 100644 (file)
@@ -63,15 +63,23 @@ type unifier struct {
        depth   int // recursion depth during unification
 }
 
-// newUnifier returns a new unifier initialized with the given type parameter list.
-func newUnifier(tparams []*TypeParam) *unifier {
+// newUnifier returns a new unifier initialized with the given type parameter
+// and corresponding type argument lists. The type argument list may be shorter
+// than the type parameter list, and it may contain nil types. Matching type
+// parameters and arguments must have the same index.
+func newUnifier(tparams []*TypeParam, targs []Type) *unifier {
+       assert(len(tparams) >= len(targs))
        handles := make(map[*TypeParam]*Type, len(tparams))
        // Allocate all handles up-front: in a correct program, all type parameters
        // must be resolved and thus eventually will get a handle.
        // Also, sharing of handles caused by unified type parameters is rare and
        // so it's ok to not optimize for that case (and delay handle allocation).
-       for _, x := range tparams {
-               handles[x] = new(Type)
+       for i, x := range tparams {
+               var t Type
+               if i < len(targs) {
+                       t = targs[i]
+               }
+               handles[x] = &t
        }
        return &unifier{tparams, handles, 0}
 }