]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: reduce number of delayed functions
authorRobert Findley <rfindley@google.com>
Wed, 8 Sep 2021 23:03:37 +0000 (19:03 -0400)
committerRobert Findley <rfindley@google.com>
Thu, 9 Sep 2021 12:57:26 +0000 (12:57 +0000)
This is a port of CL 348018 to go/types. It differs from that CL due to
the way that field lists are represented in go/ast.

Change-Id: Ib5a0243b44d0bf9e95d039f624c668f8c329f8fa
Reviewed-on: https://go-review.googlesource.com/c/go/+/348691
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/decl.go

index 8ebe7c6f5b69baa5c8fcd74da8dc1ddf6e0702a1..c1506f6dbdb04eceb25805ad09df3a288b354aa6 100644 (file)
@@ -663,11 +663,21 @@ func (check *Checker) collectTypeParams(dst **TypeParamList, list *ast.FieldList
 
        index := 0
        var bound Type
+       var bounds []Type
+       var posns []positioner // bound positions
        for _, f := range list.List {
                if f.Type == nil {
                        goto next
                }
-               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).(*ast.Ident); name != nil && name.Name == "any" && check.lookup("any") == universeAny {
+                       bound = universeAny.Type()
+               } else {
+                       bound = check.typ(f.Type)
+               }
+               bounds = append(bounds, bound)
+               posns = append(posns, f.Type)
                for i := range f.Names {
                        tparams[index+i].bound = bound
                }
@@ -675,6 +685,15 @@ func (check *Checker) collectTypeParams(dst **TypeParamList, list *ast.FieldList
        next:
                index += len(f.Names)
        }
+
+       check.later(func() {
+               for i, bound := range bounds {
+                       u := under(bound)
+                       if _, ok := u.(*Interface); !ok && u != Typ[Invalid] {
+                               check.errorf(posns[i], _Todo, "%s is not an interface", bound)
+                       }
+               }
+       })
 }
 
 func (check *Checker) declareTypeParams(tparams []*TypeParam, names []*ast.Ident) []*TypeParam {
@@ -698,25 +717,6 @@ func (check *Checker) declareTypeParams(tparams []*TypeParam, names []*ast.Ident
        return tparams
 }
 
-// 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 ast.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).(*ast.Ident); name != nil && name.Name == "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, _Todo, "%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;