diff --git a/src/go/types/decl.go b/src/go/types/decl.go index 7c612ed9b5..3643a5024c 100644 --- a/src/go/types/decl.go +++ b/src/go/types/decl.go @@ -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 diff --git a/src/go/types/resolver.go b/src/go/types/resolver.go index 82948c6019..f2ece15620 100644 --- a/src/go/types/resolver.go +++ b/src/go/types/resolver.go @@ -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) } } diff --git a/src/go/types/subst.go b/src/go/types/subst.go index 5abfc4d2a9..cb4995c64a 100644 --- a/src/go/types/subst.go +++ b/src/go/types/subst.go @@ -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)