go/types: move method collection out of type declaration processing

Simplifies Checker.typeDecl. Also, methods can only be added to
top-level types; no need to try to collect them for local types.

Change-Id: I05b926df7ffa70c32c1dd5faed3c68617be8f270
This commit is contained in:
Robert Griesemer 2020-01-31 16:00:58 -08:00
parent 12a7da1eb0
commit e70e49973e
3 changed files with 5 additions and 11 deletions

View File

@ -200,6 +200,7 @@ func (check *Checker) objDecl(obj Object, def *Named) {
case *TypeName:
// invalid recursive types are detected via path
check.typeDecl(obj, d.tdecl, def)
check.collectMethods(obj) // methods can only be added to top-level types
case *Func:
// functions may be recursive - no need to track dependencies
check.funcDecl(obj, d)
@ -580,6 +581,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
if tdecl.TParams != nil {
check.openScope(tdecl, "type parameters")
defer check.closeScope()
named.tparams = check.collectTypeParams(tdecl.TParams)
}
@ -600,16 +602,8 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
// Determine the (final, unnamed) underlying type by resolving
// any forward chain.
named.underlying = check.underlying(named)
// this must happen before addMethodDecls - cannot use defer
// TODO(gri) consider refactoring this
if tdecl.TParams != nil {
check.closeScope()
}
}
check.addMethodDecls(obj)
}
func (check *Checker) collectTypeParams(list *ast.FieldList) (tparams []*TypeName) {
@ -780,7 +774,7 @@ func (check *Checker) declareTypeParams(tparams []*TypeName, names []*ast.Ident)
return tparams
}
func (check *Checker) addMethodDecls(obj *TypeName) {
func (check *Checker) collectMethods(obj *TypeName) {
// get associated methods
// (Checker.collectObjects only collects methods with non-blank names;
// Checker.resolveBaseTypeName ensures that obj is not an alias name

View File

@ -626,7 +626,7 @@ func (check *Checker) packageObjects() {
// add new methods to already type-checked types (from a prior Checker.Files call)
for _, obj := range objList {
if obj, _ := obj.(*TypeName); obj != nil && obj.typ != nil {
check.addMethodDecls(obj)
check.collectMethods(obj)
}
}

View File

@ -187,7 +187,7 @@ func (subst *subster) typ(typ Type) Type {
// TODO(gri) BUG: If we instantiate this signature but it has no value params, we don't get a copy!
// We need to look at the actual type parameters of the signature as well.
// TODO(gri) rethink the recv situation with respect to methods on parameterized types
//recv := s.var_(t.recv) // not strictly needed (receivers cannot be parameterized) (?)
// recv := subst.var_(t.recv) // TODO(gri) this causes a stack overflow - explain
recv := t.recv
params := subst.tuple(t.params)
results := subst.tuple(t.results)