diff --git a/src/go/types/testdata/linalg.go2 b/src/go/types/testdata/linalg.go2 index 2d63dd86f9..35b046af87 100644 --- a/src/go/types/testdata/linalg.go2 +++ b/src/go/types/testdata/linalg.go2 @@ -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. diff --git a/src/go/types/testdata/tmp.go2 b/src/go/types/testdata/tmp.go2 index 119b909d98..ad1656ac25 100644 --- a/src/go/types/testdata/tmp.go2 +++ b/src/go/types/testdata/tmp.go2 @@ -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 diff --git a/src/go/types/typestring.go b/src/go/types/typestring.go index e35b02f720..4ad4bf8ffe 100644 --- a/src/go/types/typestring.go +++ b/src/go/types/typestring.go @@ -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 diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go index 77f96b7344..2e5884ff27 100644 --- a/src/go/types/typexpr.go +++ b/src/go/types/typexpr.go @@ -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 {