aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2023-01-30 14:44:42 -0800
committerGopher Robot <gobot@golang.org>2023-02-01 21:30:36 +0000
commitcda461bb79624f9ee14fd0619bef456d27d23d88 (patch)
treea9a673f6f379d3bbac9a4f74ea7c67516da73e35
parentbd749504b825677ecc0b8c0f4df785f074719051 (diff)
downloadgo-cda461bb79624f9ee14fd0619bef456d27d23d88.tar.xz
go/types, types2: unifier constructor to accept type parameters and arguments
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>
-rw-r--r--src/cmd/compile/internal/types2/infer.go18
-rw-r--r--src/cmd/compile/internal/types2/unify.go16
-rw-r--r--src/go/types/infer.go18
-rw-r--r--src/go/types/unify.go16
4 files changed, 28 insertions, 40 deletions
diff --git a/src/cmd/compile/internal/types2/infer.go b/src/cmd/compile/internal/types2/infer.go
index b5565b78b0..b9defb3e81 100644
--- a/src/cmd/compile/internal/types2/infer.go
+++ b/src/cmd/compile/internal/types2/infer.go
@@ -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
diff --git a/src/cmd/compile/internal/types2/unify.go b/src/cmd/compile/internal/types2/unify.go
index 221700b33d..bdafdf9c6a 100644
--- a/src/cmd/compile/internal/types2/unify.go
+++ b/src/cmd/compile/internal/types2/unify.go
@@ -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}
}
diff --git a/src/go/types/infer.go b/src/go/types/infer.go
index f86cc3b266..70d256bed7 100644
--- a/src/go/types/infer.go
+++ b/src/go/types/infer.go
@@ -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
diff --git a/src/go/types/unify.go b/src/go/types/unify.go
index 094aa22fa6..03c4739814 100644
--- a/src/go/types/unify.go
+++ b/src/go/types/unify.go
@@ -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}
}