From 054710ce46d5613db8e861eff49cd9cb3e3d0589 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Tue, 7 Sep 2021 15:13:24 -0700 Subject: [PATCH] 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 Reviewed-by: Robert Findley --- src/cmd/compile/internal/types2/decl.go | 36 +++++++++++-------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/cmd/compile/internal/types2/decl.go b/src/cmd/compile/internal/types2/decl.go index 278ee76bfac..cd97080824a 100644 --- a/src/cmd/compile/internal/types2/decl.go +++ b/src/cmd/compile/internal/types2/decl.go @@ -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;