diff --git a/src/go/types/README b/src/go/types/README index 92a3646b4f..0b8211e493 100644 --- a/src/go/types/README +++ b/src/go/types/README @@ -1,20 +1,21 @@ -This version of go/types (and related go/*) libraries contains the changes -to type-check generic code as outlined in the latest contracts proposal, as -presented by Ian Taylor at GopherCon 2019. +This version of go/types (and related go/*) libraries contains changes +to type-check generic code as outlined in the latest contracts proposal, +as presented by Ian Taylor at GopherCon 2019. -NOTE: THIS IS A PROTOTYPE. NOT EVERYTHING IS IMPLEMENTED. THERE ARE BUGS. +CAUTUION: EARLY PROTOTYPE. A LOT IS STILL MISSING. THERE ARE BUGS. -The code is not very well tested, some parts were hacked up quickly, -and no code review has happened. Read and use the code at your own risk. +The code is not tested enough, many parts need a rewrite/cleanup +and no code review has happened. Read and use at your own risk. -Specifically, the following pieces are missing from type-checking or lead -to unexpected behavior: +Specifically, the following pieces (and more) are missing from type- +checking or lead to unexpected behavior: - Importing of packages with type parameters or contracts. - Type-checking of contracts and type parameter lists with contracts. - Alias type names with type parameters. +- gofmt (and any other tools) don't work for parameterized code. -The following is "working" (as in passes simple tests): +The following is "working" (as in "passes simple tests"): - Parsing of parameterized types and functions. - Parsing of contract declarations. @@ -22,6 +23,9 @@ The following is "working" (as in passes simple tests): - Declaration and use (calls) of parameterized functions without contracts, including type inference from function arguments. +Error messages, where present, are in usable condition but expect +them to be significantly better in a real implementation. + To play with this prototype: - Cherry-pick this CL on top of tip: @@ -37,6 +41,10 @@ To play with this prototype: - Run it against a test case (assuming gotype was installed in a location that is in your $PATH): - gotype example.go2 + gotype $GOROOT/src/go/types/examples/functions.go2 See also `gotype -h` for more information. + +Note: Currently, files containing parameterized code have extension ".go2". +This is solely to distinguish them from regular Go code and to prevent gofmt +from touching them. We expect a proper implementation to keep using ".go". diff --git a/src/go/types/examples/contracts.go2 b/src/go/types/examples/contracts.go2 new file mode 100644 index 0000000000..009a504f6c --- /dev/null +++ b/src/go/types/examples/contracts.go2 @@ -0,0 +1,50 @@ +// Copyright 2019 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 shows examples of contract declarations. +// They are not type-checked at the moment. + +package p + +// A contract declaration, like any other declaration, +// starts with a keyword, followed by the contract name +// and the contract type parameters, and then the contract +// specification. +contract C(T) { + T m() +} + +// Contracts may be empty. +contract Empty() {} + +// Contracts may be grouped. +contract ( + C1(T) {} + C2(T) {} + C3(T) {} +) + +// A contract specifies methods and types for each of the +// type parameters it constrains. +contract Stringer(T) { + T String() string +} + +contract Sequence(T) { + T string, []byte +} + +// Contracts may constrain multiple type parameters +// in mutually recursive ways. +contract G(Node, Edge) { + Node Edges() []Edge + Edge Nodes() (from Node, to Node) +} + +type Graph (type Node, Edge G) struct { /* ... */ } + +func New (type Node, Edge G) (nodes []Node) *Graph(Node, Edge) { panic("unimplemented") } + +func (g *Graph(Node, Edge)) ShortestPath(from, to Node) []Edge { panic("unimplemented") } + diff --git a/src/go/types/examples/functions.go2 b/src/go/types/examples/functions.go2 index 11b4deee97..e1024117ff 100644 --- a/src/go/types/examples/functions.go2 +++ b/src/go/types/examples/functions.go2 @@ -62,3 +62,11 @@ var s = foo(int, string, float64)(1, []string{"first"}, new(float64)()) // Or we can use type inference. var _ float64 = foo(42, []float64{1.0}, &s) +// Type inference works in a straight-forward manner even +// for variadic functions. +func variadic(type A, B)(A, B, ...B) int { panic("unimplemented") } + +// var _ = variadic(1) // ERROR not enough arguments +var _ = variadic(1, 2.3) +var _ = variadic(1, 2.3, 3.4, 4.5) +var _ = variadic(int, float64)(1, 2.3, 3.4, 4) \ No newline at end of file diff --git a/src/go/types/testdata/contracts.go2 b/src/go/types/testdata/contracts.go2 index 9a3da55464..f2eb3d7c83 100644 --- a/src/go/types/testdata/contracts.go2 +++ b/src/go/types/testdata/contracts.go2 @@ -11,7 +11,7 @@ contract _(A, B, C){} contract _(A, B, A /* ERROR A redeclared */ ){} // For now we also allow this form of contract declaration. -// TODO(gri) probably not a good idea. Disallow a local level for sure. +// TODO(gri) probably not a good idea. Disallow at local level for sure. type _ contract(){} type _ contract(A, B, A /* ERROR A redeclared */ ){}