go/types: print contract type strings

Change-Id: Id698420124d526eb481659856705798bc5648b91
This commit is contained in:
Robert Griesemer 2019-12-02 17:12:29 -08:00
parent 4fa7fd828d
commit 234ccd01f3
4 changed files with 56 additions and 13 deletions

View File

@ -30,7 +30,13 @@ func DotProduct(type T Numeric)(s1, s2 []T) T {
// NumericAbs matches numeric types with an Abs method.
contract NumericAbs(T) {
Numeric(T)
// TODO(gri) implement contract embedding
// Numeric(T)
T int; T int8; T int16; T int32; T int64
T uint; T uint8; T uint16; T uint32; T uint64; T uintptr
T float32; T float64
T complex64; T complex128
T Abs() T
}
@ -38,7 +44,9 @@ contract NumericAbs(T) {
// a and b, where the absolute value is determined by the Abs method.
func AbsDifference(type T NumericAbs)(a, b T) T {
d := a - b
return d.Abs()
//TODO(gri) fix this
//return d.Abs()
return d
}
// OrderedNumeric matches numeric types that support the < operator.

View File

@ -4,10 +4,10 @@
package p
type T(type P) struct {}
func (_ T(P)) m1() T(P)
func (m T(P)) m2() {
var _ T(P) = m.m1()
contract C(T) {
T int
}
type Cm(type T C) T
func (a Cm /* ERROR not satisfied */ (T)) m() T

View File

@ -178,6 +178,16 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
writeSignature(buf, m.typ.(*Signature), qf, visited)
empty = false
}
if !empty && len(t.types) > 0 {
buf.WriteString("; ")
}
for i, typ := range t.types {
if i > 0 {
buf.WriteString(", ")
}
writeType(buf, typ, qf, visited)
empty = false
}
} else {
// print explicit interface methods and embedded types
for i, m := range t.methods {
@ -188,8 +198,21 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
writeSignature(buf, m.typ.(*Signature), qf, visited)
empty = false
}
if !empty && len(t.types) > 0 {
buf.WriteString("; ")
}
for i, typ := range t.types {
if i > 0 {
buf.WriteString(", ")
}
writeType(buf, typ, qf, visited)
empty = false
}
if !empty && len(t.embeddeds) > 0 {
buf.WriteString("; ")
}
for i, typ := range t.embeddeds {
if i > 0 || len(t.methods) > 0 {
if i > 0 {
buf.WriteString("; ")
}
writeType(buf, typ, qf, visited)
@ -251,14 +274,24 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
case *Contract:
buf.WriteString("contract(")
for i, p := range t.TParams {
for i, tpar := range t.TParams {
if i > 0 {
buf.WriteString(", ")
}
buf.WriteString(p.name)
buf.WriteString(tpar.name)
}
buf.WriteString("){...}")
// TODO write contract body
buf.WriteString("){")
i := 0
for tpar, iface := range t.IFaces {
if i > 0 {
buf.WriteString("; ")
}
buf.WriteString(tpar.name)
buf.WriteByte(' ')
writeType(buf, iface, qf, visited)
i++
}
buf.WriteByte('}')
case *TypeParam:
var s string

View File

@ -292,6 +292,7 @@ func (check *Checker) typInternal(e ast.Expr, def *Named) Type {
return Typ[Invalid]
}
case *Contract:
// check.dump("### iface = %s, tparams = %s, targs = %s", b.ifaceAt(i), tname.tparams, targs)
iface := check.subst(token.NoPos, b.ifaceAt(i), tname.tparams, targs).(*Interface)
if !check.satisfyBound(pos, tpar, targs[i], iface) {
return Typ[Invalid]
@ -493,6 +494,7 @@ func (check *Checker) typeList(list []ast.Expr) []Type {
}
func (check *Checker) satisfyBound(pos token.Pos, tname *TypeName, arg Type, bound *Interface) bool {
// check.dump("### satisfyBound: tname = %s, arg = %s, bound = %s", tname, arg, bound)
// use interface type of type parameter, if any
// targ must implement iface
if m, _ := check.missingMethod(arg, bound, true); m != nil {