From ed8d54fb3a2abaa38e246f85f929b79a75667670 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 11 Dec 2019 16:44:11 -0800 Subject: [PATCH] go/types: added testdata/linalg.go2 to test suite, disabled some code Context-specific customization of parameterized interface methods of type parameter bounds is missing; as a result some of linalg.go2 fails. Change-Id: I3e749ee040d2b3ae8f73ae26680984bc1b4b79ef --- src/go/types/NOTES | 3 ++- src/go/types/call.go | 3 +++ src/go/types/check_test.go | 1 + src/go/types/testdata/linalg.go2 | 17 ++++++++++------- src/go/types/testdata/tmp.go2 | 16 ++++++++++++++++ src/go/types/typestring.go | 4 ++-- 6 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/go/types/NOTES b/src/go/types/NOTES index 83241ad5a3..895ba3c1c1 100644 --- a/src/go/types/NOTES +++ b/src/go/types/NOTES @@ -7,7 +7,8 @@ TODO OPEN ISSUES - contracts slip through in places where only types are permitted - +- conversions against parameterized types are not implemented +- parameterized interface methods (of type bounds) need to be customized (subst) for context DESIGN DECISIONS - 12/4/2019: do not allow parenthesized generic uninstantiated types (unless instantiated implicitly) diff --git a/src/go/types/call.go b/src/go/types/call.go index 2f64d364b3..f6b942da67 100644 --- a/src/go/types/call.go +++ b/src/go/types/call.go @@ -475,6 +475,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { // methods may not have a fully set up signature yet if m, _ := obj.(*Func); m != nil { + // check.dump("### found method %s", m) check.objDecl(m, nil) // If m has a parameterized receiver type, infer the type parameter // values from the actual receiver provided and then substitute the @@ -491,6 +492,8 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { copy.typ = check.subst(e.Pos(), m.typ, m.tparams, targs) obj = © } + // TODO(gri) we also need to do substitution for parameterized interface methods + // (this breaks code in testdata/linalg.go2 at the moment) } if x.mode == typexpr { diff --git a/src/go/types/check_test.go b/src/go/types/check_test.go index 857b60ab8b..27d13add74 100644 --- a/src/go/types/check_test.go +++ b/src/go/types/check_test.go @@ -111,6 +111,7 @@ var tests = [][]string{ {"testdata/chans.go2"}, {"testdata/map.go2"}, {"testdata/map2.go2"}, + {"testdata/linalg.go2"}, // Go 2 prototype examples {"examples/contracts.go2"}, diff --git a/src/go/types/testdata/linalg.go2 b/src/go/types/testdata/linalg.go2 index 35b046af87..3a8dfcc363 100644 --- a/src/go/types/testdata/linalg.go2 +++ b/src/go/types/testdata/linalg.go2 @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// TODO(gri) add this file to the test suite once it type-checks. - package linalg import "math" @@ -66,9 +64,10 @@ contract Complex(T) { type OrderedAbs(type T OrderedNumeric) T func (a OrderedAbs(T)) Abs() T { - if a < 0 { - return -a - } + // TODO(gri) implement conversions against parameterized types + // if a < 0 { + // return -a + // } return a } @@ -84,9 +83,13 @@ func (a ComplexAbs(T)) Abs() T { } func OrderedAbsDifference(type T OrderedNumeric)(a, b T) T { - return T(AbsDifference(OrderedAbs(T)(a), OrderedAbs(T)(b))) + // TODO(gri) fix this + // return T(AbsDifference(OrderedAbs(T)(a), OrderedAbs(T)(b))) + return a } func ComplexAbsDifference(type T Complex)(a, b T) T { - return T(AbsDifference(ComplexAbs(T)(a), ComplexAbs(T)(b))) + // TODO(gri) fix this + // return T(AbsDifference(ComplexAbs(T)(a), ComplexAbs(T)(b))) + return a } diff --git a/src/go/types/testdata/tmp.go2 b/src/go/types/testdata/tmp.go2 index cbb358b144..3c4dc575c8 100644 --- a/src/go/types/testdata/tmp.go2 +++ b/src/go/types/testdata/tmp.go2 @@ -3,3 +3,19 @@ // license that can be found in the LICENSE file. package p + +contract C(T) { + T int + T Abs() T +} + +type B(type T) interface { + type int + Abs() T +} + +func AbsDifference(type T C)(a, b T) T { + d := a - b + // TODO(gri) make this work + return d /* ERROR cannot use */ .Abs() +} \ No newline at end of file diff --git a/src/go/types/typestring.go b/src/go/types/typestring.go index f9d261b115..86651e3d3e 100644 --- a/src/go/types/typestring.go +++ b/src/go/types/typestring.go @@ -276,7 +276,7 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) { if i > 0 { buf.WriteString(", ") } - buf.WriteString(tpar.name) + writeType(buf, tpar.typ, qf, visited) } buf.WriteString("){") i := 0 @@ -284,7 +284,7 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) { if i > 0 { buf.WriteString("; ") } - buf.WriteString(tpar.name) + writeType(buf, tpar.typ, qf, visited) buf.WriteByte(' ') writeType(buf, iface, qf, visited) i++