1
0
mirror of https://github.com/golang/go synced 2024-11-24 04:50:07 -07:00

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>
This commit is contained in:
Robert Griesemer 2023-01-30 14:44:42 -08:00 committed by Gopher Robot
parent bd749504b8
commit cda461bb79
4 changed files with 28 additions and 40 deletions

View 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

View 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}
}

View 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

View 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}
}