aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Findley <rfindley@google.com>2021-09-08 19:03:37 -0400
committerRobert Findley <rfindley@google.com>2021-09-09 12:57:26 +0000
commit66f0d35f7145ca8d4e45b04292f44831d6610b3b (patch)
treed6747176e89ebd2aefefcb4871868dff76325ed5
parentd2a77f1c76dcc960d8548fa47ec29fcb1b2e5833 (diff)
downloadgo-66f0d35f7145ca8d4e45b04292f44831d6610b3b.tar.gz
go-66f0d35f7145ca8d4e45b04292f44831d6610b3b.zip
go/types: reduce number of delayed functions
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>
-rw-r--r--src/go/types/decl.go40
1 files changed, 20 insertions, 20 deletions
diff --git a/src/go/types/decl.go b/src/go/types/decl.go
index 8ebe7c6f5b..c1506f6dbd 100644
--- a/src/go/types/decl.go
+++ b/src/go/types/decl.go
@@ -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;