]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/types2: reduce number of delayed functions (optimization)
authorRobert Griesemer <gri@golang.org>
Tue, 7 Sep 2021 22:13:24 +0000 (15:13 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 8 Sep 2021 15:51:14 +0000 (15:51 +0000)
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>
src/cmd/compile/internal/types2/decl.go

index 278ee76bfac214a5be328b3dd4f14ca1826d72f4..cd97080824a0db918fac8b3aa5e32f6d8bf35270 100644 (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;