cmd/compile/internal/types2: reduce number of delayed functions (optimization)

Rather than create and delay execution of a closure for each type parameter
in a type parameter list, just create one per type parameter list.

While at it, inline the small amount of code for getting the type constraint
and remove the respective function.

Change-Id: I49a00ff0a7b7e43eb53992dd7dbfac25ff23b42c
Reviewed-on: https://go-review.googlesource.com/c/go/+/348018
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Griesemer 2021-09-07 15:13:24 -07:00
parent 73a062c3e7
commit 054710ce46

View file

@ -619,10 +619,25 @@ func (check *Checker) collectTypeParams(dst **TParamList, list []*syntax.Field)
// This also preserves the grouped output of type parameter lists
// when printing type strings.
if i == 0 || f.Type != list[i-1].Type {
bound = check.boundType(f.Type)
// The predeclared identifier "any" is visible only as a type bound in a type parameter list.
// If we allow "any" for general use, this if-statement can be removed (issue #33232).
if name, _ := unparen(f.Type).(*syntax.Name); name != nil && name.Value == "any" && check.lookup("any") == universeAny {
bound = universeAny.Type()
} else {
bound = check.typ(f.Type)
}
}
tparams[i].bound = bound
}
check.later(func() {
for i, tpar := range tparams {
u := under(tpar.bound)
if _, ok := u.(*Interface); !ok && u != Typ[Invalid] {
check.errorf(list[i].Type, "%s is not an interface", tpar.bound)
}
}
})
}
func (check *Checker) declareTypeParam(name *syntax.Name) *TypeParam {
@ -638,25 +653,6 @@ func (check *Checker) declareTypeParam(name *syntax.Name) *TypeParam {
return tpar
}
// boundType type-checks the type expression e and returns its type, or Typ[Invalid].
// The type must be an interface, including the predeclared type "any".
func (check *Checker) boundType(e syntax.Expr) Type {
// The predeclared identifier "any" is visible only as a type bound in a type parameter list.
// If we allow "any" for general use, this if-statement can be removed (issue #33232).
if name, _ := unparen(e).(*syntax.Name); name != nil && name.Value == "any" && check.lookup("any") == universeAny {
return universeAny.Type()
}
bound := check.typ(e)
check.later(func() {
u := under(bound)
if _, ok := u.(*Interface); !ok && u != Typ[Invalid] {
check.errorf(e, "%s is not an interface", bound)
}
})
return bound
}
func (check *Checker) collectMethods(obj *TypeName) {
// get associated methods
// (Checker.collectObjects only collects methods with non-blank names;