From 66f0d35f7145ca8d4e45b04292f44831d6610b3b Mon Sep 17 00:00:00 2001 From: Robert Findley Date: Wed, 8 Sep 2021 19:03:37 -0400 Subject: [PATCH] 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 Run-TryBot: Robert Findley TryBot-Result: Go Bot Reviewed-by: Robert Griesemer --- src/go/types/decl.go | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/go/types/decl.go b/src/go/types/decl.go index 8ebe7c6f5b6..c1506f6dbdb 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;