go/types: use named receiver type for contract methods

Change-Id: Ib82a8c41490d75ee80cd96fbf862412fdc5657c2
This commit is contained in:
Robert Griesemer 2019-12-17 16:50:52 -08:00
parent 609756301c
commit 74d0d556d9
2 changed files with 7 additions and 5 deletions

View File

@ -33,7 +33,7 @@ func (check *Checker) contractType(contr *Contract, name string, e *ast.Contract
// C2(P1, P2, ... Pn), ... Cn(P1, P2, ... Pn) with the respective underlying interfaces
// representing the type constraints for each of the type parameters (C1 for P1, C2 for P2, etc.).
bounds := make(map[*TypeName]*Named)
ifaceFor := func(tpar *TypeName) *Interface {
ifaceFor := func(tpar *TypeName) *Named {
named := bounds[tpar]
if named == nil {
index := tpar.typ.(*TypeParam).index
@ -42,7 +42,7 @@ func (check *Checker) contractType(contr *Contract, name string, e *ast.Contract
named = NewNamed(tname, new(Interface), nil)
bounds[tpar] = named
}
return named.underlying.(*Interface)
return named
}
// collect constraints
@ -82,7 +82,8 @@ func (check *Checker) contractType(contr *Contract, name string, e *ast.Contract
}
tpar := obj.(*TypeName)
iface := ifaceFor(tpar)
ifaceName := ifaceFor(tpar)
iface := ifaceName.underlying.(*Interface)
switch nmethods {
case 0:
// type constraints
@ -103,8 +104,7 @@ func (check *Checker) contractType(contr *Contract, name string, e *ast.Contract
// add receiver to signature
// (TODO(gri) verify that this matches what we do elsewhere, e.g., in NewInterfaceType)
assert(sig.recv == nil)
recvTyp := tpar.typ
sig.recv = NewVar(pos, check.pkg, "", recvTyp)
sig.recv = NewVar(pos, check.pkg, "_", ifaceName)
// add the method
mname := c.MNames[0]
m := NewFunc(mname.Pos(), check.pkg, mname.Name, sig)

View File

@ -775,6 +775,8 @@ func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
// bound is (possibly) parameterized in the context of the
// receiver type declaration. Substitute parameters for the
// current context.
// TODO(gri) should we assume now that bounds always exist?
// (no bound == empty interface)
if bound != nil {
bound = check.subst(tname.pos, bound, recvTParams, list)
tname.typ.(*TypeParam).bound = bound