mirror of https://github.com/golang/go.git
go/types: remove satisfyContract - now implemented via instantiate
Change-Id: I1561d57709a996112b39aa8a15826387ea062e29
This commit is contained in:
parent
6e1fbb8a53
commit
d941f3db1d
|
|
@ -224,64 +224,3 @@ func (check *Checker) typeConstraint(typ Type, why *string) bool {
|
|||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// satisfyContract reports whether the given type arguments satisfy a contract.
|
||||
// The contract may be nil, in which case it is always satisfied.
|
||||
// The number of type arguments must match the number of contract type parameters.
|
||||
// TODO(gri) missing: good error reporting
|
||||
func (check *Checker) satisfyContract(contr *Contract, targs []Type) bool {
|
||||
if contr == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
assert(len(contr.TParams) == len(targs))
|
||||
|
||||
// A contract is represented by a list of interfaces, one for each
|
||||
// contract type parameter. Each of those interfaces may be parameterized
|
||||
// with any of the other contract type parameters.
|
||||
// We need to verify that each type argument implements its respective
|
||||
// contract interface, but only after substituting any contract type parameters
|
||||
// in that interface with the respective type arguments.
|
||||
//
|
||||
// TODO(gri) This implementation strategy (and implementation) would be
|
||||
// much more direct if we were to replace contracts simply with (parameterized)
|
||||
// interfaces. All the existing machinery would simply fall into place.
|
||||
|
||||
for i, targ := range targs {
|
||||
iface := contr.ifaceAt(i)
|
||||
// If iface is generic, we need to replace the type parameters
|
||||
// with the respective type arguments.
|
||||
// TODO(gri) fix this
|
||||
if IsParameterized(iface) {
|
||||
// check.dump("BEFORE iface(%s) => %s (%s)", targ, iface, fmt.Sprintf("%p", iface))
|
||||
iface = check.subst(token.NoPos, iface, contr.TParams, targs).(*Interface)
|
||||
// check.dump("AFTER iface(%s) => %s (%s)", targ, iface, fmt.Sprintf("%p", iface))
|
||||
}
|
||||
// use interface type of type parameter, if any
|
||||
// targ must implement iface
|
||||
if m, _ := check.missingMethod(targ, iface, true); m != nil {
|
||||
// check.dump("missing %s (%s, %s)", m, targ, iface)
|
||||
return false
|
||||
}
|
||||
// targ's underlying type must also be one of the interface types listed, if any
|
||||
if len(iface.types) > 0 {
|
||||
utyp := targ.Underlying()
|
||||
// TODO(gri) Cannot handle a type argument that is itself parameterized for now
|
||||
switch utyp.(type) {
|
||||
case *Interface, *Contract:
|
||||
panic("unimplemented")
|
||||
}
|
||||
ok := false
|
||||
for _, t := range iface.types {
|
||||
// if we find one matching type, we're ok
|
||||
if Identical(utyp, t) {
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return ok
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue