diff options
author | Robert Findley <rfindley@google.com> | 2021-09-08 19:03:37 -0400 |
---|---|---|
committer | Robert Findley <rfindley@google.com> | 2021-09-09 12:57:26 +0000 |
commit | 66f0d35f7145ca8d4e45b04292f44831d6610b3b (patch) | |
tree | d6747176e89ebd2aefefcb4871868dff76325ed5 | |
parent | d2a77f1c76dcc960d8548fa47ec29fcb1b2e5833 (diff) | |
download | go-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.go | 40 |
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; |