go/test: steps toward instantiated contracts (partially working)

See testdata/tmp.go for a test that shouldn't succeed.

Change-Id: Iefa738e0b6df6c3abe74670f8bc1d62a3e8c4e46
This commit is contained in:
Robert Griesemer 2020-01-13 16:03:27 -08:00
parent 5d80216f87
commit ee164bc407
3 changed files with 55 additions and 6 deletions

View File

@ -644,7 +644,14 @@ func (check *Checker) collectTypeParams(list *ast.FieldList) (tparams []*TypeNam
}
if targs != nil {
// obj denotes a valid contract that is instantiated with targs
check.errorf(f.Type.Pos(), "explicit contract instantiation not yet implemented")
// Use contract's matching type parameter bound and
// instantiate it with the actual type arguments targs.
// TODO(gri) this is not correct when arguments are permutated. Investigate!
for i, bound := range obj.Bounds {
pos := unparen(f.Type).(*ast.CallExpr).Args[i].Pos() // we must have an *ast.CallExpr
//check.dump("%v: bound %d = %v, under = %v, args = %v", pos, i, bound, bound.Underlying(), targs)
setBoundAt(index+i, check.instantiate(pos, bound, targs, nil))
}
} else {
// obj denotes a valid uninstantiated contract =>
// use the declared type parameters as "arguments"
@ -653,8 +660,7 @@ func (check *Checker) collectTypeParams(list *ast.FieldList) (tparams []*TypeNam
goto next
}
// Use contract's matching type parameter bound and
// instantiate it with the actual type parameters
// (== targs) present.
// instantiate it with the actual type arguments targs.
targs := make([]Type, len(f.Names))
for i, tparam := range tparams[index : index+len(f.Names)] {
targs[i] = tparam.typ

View File

@ -218,6 +218,32 @@ func _(type F, C FloatComplex)(c C) {
c = C(complex(fre, fim))
}
// Use of instantiated contracts
contract ABC(A, B, C) {
A a()
B b()
C int, float64
}
func fa(type A, B, C) (A, B, C)
func fb(type A, B, C ABC) (A, B, C)
func fc(type A, B, C ABC(A, B, C)) (A, B, C)
func fd(type A, B, C ABC(B, C, A)) (A, B, C)
type tA int; func (tA) a()
type tB float64; func (tB) b()
func _() {
var a tA
var b tB
fa(a, b, 0)
fb(a, b, 0)
fc(a, b, 0)
fd(a, b, 0)
fd(tA, tB, int)(a, b, 0) // TODO(gri) this should fail - investigate!
}
// --------------------------------------------------------------------------------------
// Parameterized interfaces as contracts

View File

@ -27,8 +27,25 @@ type II interface{
var _ I = II(nil)
*/
contract C(T) {
T op(T) T
contract C(A, B) {
A a()
B b()
}
func f(type T C /* ERROR not yet implemented */ (T))(x, y T) T //{ return x.op(y) }
//func fa(type A, B, C) (A, B, C)
//func fb(type A, B, C ABC) (A, B, C)
//func fc(type A, B, C ABC(A, B, C)) (A, B, C)
func fd(type A, B C(B, A)) ()
type tA struct{}; func (tA) a()
type tB struct{}; func (tB) b()
func _() {
//var a tA
//var b tB
//fa(a, b, 0)
//(a, b, 0)
//(a, b, 0)
//fd(a, b, 0)
fd(tA, tB)() // TODO(gri) this should fail
}