From 7ad6dd2e38b80ab87e0f3e2b3f412c2203122a98 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 16 Jan 2020 21:19:20 -0800 Subject: [PATCH] go/types: add testdata/todos.go2 for documenting unimplemented features Also: Updated NOTES file. Change-Id: I9f760693a486433d5a496d155627cad330630e90 --- src/go/types/NOTES | 16 +++++----- src/go/types/check_test.go | 1 + src/go/types/expr.go | 2 ++ src/go/types/testdata/todos.go2 | 54 +++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 src/go/types/testdata/todos.go2 diff --git a/src/go/types/NOTES b/src/go/types/NOTES index 24f09ba377..b70e6e7d36 100644 --- a/src/go/types/NOTES +++ b/src/go/types/NOTES @@ -1,4 +1,4 @@ -This file works as a sort of notebook/implementation log. It replaces my notebook based approach +This file works as a sort of notebook/implementation log. It replaces my notebook-based approach so we have a better track record. I only switched to this file in Nov 2019, hence it is incomplete. ---------------------------------------------------------------------------------------------------- @@ -26,15 +26,17 @@ KNOWN ISSUES ---------------------------------------------------------------------------------------------------- OPEN QUESTIONS -- for len/cap(x) where x is of type parameter type and the bound contains arrays only, should the - result be a constant? (right now it is not) -- confirm that it's ok to use inference in missingMethod to compare parameterized methods -- now that we allow parenthesized embedded interfaces, should we allow parenthesized embedded fields? +- What is the exact nature of a generic type? Does it act as a named type (it can have methods)? +- For len/cap(x) where x is of type parameter type and the bound contains arrays only, should the + result be a constant? (right now it is not). What are the implications for alternative, non- + monomorphizing implementation methods? +- Confirm that it's ok to use inference in missingMethod to compare parameterized methods +- Now that we allow parenthesized embedded interfaces, should we allow parenthesized embedded fields? (probably yes, for symmetry and consistency). - What does it mean to explicitly instantiate a contract with a non-type parameter argument? (e.g., contract C(T) { T int }; func _(type T C(int))(...) ... seems invalid. What are the rules?) -- Should we be able to parenthesize embedded contracts (like we allow for interfaces)? (currently this - is not permitted syntactically) +- Should we be able to parenthesize embedded contracts like we allow for interfaces (currently this + is not permitted syntactically)? ---------------------------------------------------------------------------------------------------- DESIGN/IMPLEMENTATION diff --git a/src/go/types/check_test.go b/src/go/types/check_test.go index 27d13add74..3ed9708e63 100644 --- a/src/go/types/check_test.go +++ b/src/go/types/check_test.go @@ -105,6 +105,7 @@ var tests = [][]string{ {"testdata/typeinst.go2"}, {"testdata/typeinst2.go2"}, {"testdata/contracts.go2"}, + {"testdata/todos.go2"}, // Go 2 examples from design doc {"testdata/slices.go2"}, diff --git a/src/go/types/expr.go b/src/go/types/expr.go index 89eecebfb6..1261f06dfb 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -1384,6 +1384,8 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { e = t.elem case *Map: e = t.elem + case *TypeParam: + check.errorf(x.pos(), "type of %s contains a type parameter - cannot index (implementation restriction)", x) } if e != nil && (e == elem || elem == nil) { elem = e diff --git a/src/go/types/testdata/todos.go2 b/src/go/types/testdata/todos.go2 new file mode 100644 index 0000000000..675385a51d --- /dev/null +++ b/src/go/types/testdata/todos.go2 @@ -0,0 +1,54 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file is meant as "dumping ground" for tests +// of not yet implemented features. It will grow and +// shrink over time. + +package p + +// indexing on generic types containing type parameters in their type list +// is not yet supported +func _(type T interface { type T })(x T) { + _ = x /* ERROR type parameter */ /* ERROR cannot index */ [0] +} + +// channel sends and receives on generic types is not yet supported +func _(type T interface{ type chan int })(ch T) { + ch <- /* ERROR cannot send */ 0 + _ = <- ch /* ERROR cannot receive */ +} + +// local variable declaration with underlying generic type is not fully supported +func _(type T)() { + type L T // local variable declaration + var x L + _ = x /* ERROR not defined */ + x +} + +// pointer indirection of generic types is not yet supported +func _(type T interface{ type *int })(p T) { + _ = *p /* ERROR cannot indirect */ +} + +// type assertions over generic types are not yet supported +func _(type T interface{ type int })(x T) { + _ = T /* ERROR not an expression */ .(int) + _ = x /* ERROR not an interface */ .(int) +} + +// calling of a generic variable is not yet supported +func _(type T interface{ type func() })(f T) { + f /* ERROR cannot call */ () + go f /* ERROR cannot call */ () +} + +// need to investigate the exact nature of a generic type (is it a named type)? +func _(type T interface{ type int})(x T) { + type myint int + var _ int = x /* ERROR cannot use */ + var _ T = 42 + var _ T = int /* ERROR cannot use */ (42) + var _ T = myint /* ERROR cannot use */ (42) +}