1
0
mirror of https://github.com/golang/go synced 2024-11-17 13:54:46 -07:00

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>
This commit is contained in:
Robert Findley 2021-09-08 19:03:37 -04:00
parent d2a77f1c76
commit 66f0d35f71

View File

@ -663,11 +663,21 @@ func (check *Checker) collectTypeParams(dst **TypeParamList, list *ast.FieldList
index := 0 index := 0
var bound Type var bound Type
var bounds []Type
var posns []positioner // bound positions
for _, f := range list.List { for _, f := range list.List {
if f.Type == nil { if f.Type == nil {
goto next 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 { for i := range f.Names {
tparams[index+i].bound = bound tparams[index+i].bound = bound
} }
@ -675,6 +685,15 @@ func (check *Checker) collectTypeParams(dst **TypeParamList, list *ast.FieldList
next: next:
index += len(f.Names) 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 { 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 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) { func (check *Checker) collectMethods(obj *TypeName) {
// get associated methods // get associated methods
// (Checker.collectObjects only collects methods with non-blank names; // (Checker.collectObjects only collects methods with non-blank names;