diff options
author | Robert Griesemer <gri@golang.org> | 2021-07-29 11:10:04 -0700 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2021-08-05 19:36:47 +0000 |
commit | bb5608dd5d056519bd90666b815e0b2bf65e5ee8 (patch) | |
tree | ce15dcdb79b6a54969dda7ec002a630c71ff40fb /src/cmd/compile/internal/types2/testdata | |
parent | 6dadee759c812961300c8d1a44959d14299fd9f8 (diff) | |
download | go-bb5608dd5d056519bd90666b815e0b2bf65e5ee8.tar.gz go-bb5608dd5d056519bd90666b815e0b2bf65e5ee8.zip |
[dev.typeparams] cmd/compile/internal/types2: implement type sets with term lists
This CL resolves several known issues and TODOs.
- Represent type sets with term lists and using term list abstractions.
- Represent Unions internally as a list of (syntactical) terms.
Use term operations to print terms and detect overlapping union
entries.
- Compute type sets corresponding to unions lazily, on demand.
- Adjust code throughout.
- Adjusted error check in test/typeparam/mincheck.dir/main.go
to make test pass.
Change-Id: Ib36fb7e1d343c2b6aec51d304f0f7d1ad415f999
Reviewed-on: https://go-review.googlesource.com/c/go/+/338310
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src/cmd/compile/internal/types2/testdata')
4 files changed, 79 insertions, 45 deletions
diff --git a/src/cmd/compile/internal/types2/testdata/check/typeinst2.go2 b/src/cmd/compile/internal/types2/testdata/check/typeinst2.go2 index 14d8f0ea8c..e90e4dde44 100644 --- a/src/cmd/compile/internal/types2/testdata/check/typeinst2.go2 +++ b/src/cmd/compile/internal/types2/testdata/check/typeinst2.go2 @@ -164,13 +164,13 @@ type _ interface { // for them to be all in a single list, and we report the error // as well.) type _ interface { - ~int|~int /* ERROR duplicate term int */ - ~int|int /* ERROR duplicate term int */ - int|int /* ERROR duplicate term int */ + ~int|~int /* ERROR overlapping terms ~int */ + ~int|int /* ERROR overlapping terms int */ + int|int /* ERROR overlapping terms int */ } type _ interface { - ~struct{f int} | ~struct{g int} | ~struct /* ERROR duplicate term */ {f int} + ~struct{f int} | ~struct{g int} | ~struct /* ERROR overlapping terms */ {f int} } // Interface type lists can contain any type, incl. *Named types. diff --git a/src/cmd/compile/internal/types2/testdata/check/typeparams.go2 b/src/cmd/compile/internal/types2/testdata/check/typeparams.go2 index 54efd1485b..7392b88555 100644 --- a/src/cmd/compile/internal/types2/testdata/check/typeparams.go2 +++ b/src/cmd/compile/internal/types2/testdata/check/typeparams.go2 @@ -149,37 +149,40 @@ func _[T interface{}](x T) { for range x /* ERROR cannot range */ {} } -func _[T interface{ ~string | ~[]string }](x T) { - for range x {} - for i := range x { _ = i } - for i, _ := range x { _ = i } - for i, e := range x /* ERROR must have the same element type */ { _ = i } - for _, e := range x /* ERROR must have the same element type */ {} - var e rune - _ = e - for _, (e) = range x /* ERROR must have the same element type */ {} -} - - -func _[T interface{ ~string | ~[]rune | ~map[int]rune }](x T) { - for _, e := range x { _ = e } - for i, e := range x { _ = i; _ = e } -} - -func _[T interface{ ~string | ~[]rune | ~map[string]rune }](x T) { - for _, e := range x { _ = e } - for i, e := range x /* ERROR must have the same key type */ { _ = e } -} - -func _[T interface{ ~string | ~chan int }](x T) { - for range x {} - for i := range x { _ = i } - for i, _ := range x { _ = i } // TODO(gri) should get an error here: channels only return one value -} - -func _[T interface{ ~string | ~chan<-int }](x T) { - for i := range x /* ERROR send-only channel */ { _ = i } -} +// Disabled for now until we have clarified semantics of range. +// TODO(gri) fix this +// +// func _[T interface{ ~string | ~[]string }](x T) { +// for range x {} +// for i := range x { _ = i } +// for i, _ := range x { _ = i } +// for i, e := range x /* ERROR must have the same element type */ { _ = i } +// for _, e := range x /* ERROR must have the same element type */ {} +// var e rune +// _ = e +// for _, (e) = range x /* ERROR must have the same element type */ {} +// } +// +// +// func _[T interface{ ~string | ~[]rune | ~map[int]rune }](x T) { +// for _, e := range x { _ = e } +// for i, e := range x { _ = i; _ = e } +// } +// +// func _[T interface{ ~string | ~[]rune | ~map[string]rune }](x T) { +// for _, e := range x { _ = e } +// for i, e := range x /* ERROR must have the same key type */ { _ = e } +// } +// +// func _[T interface{ ~string | ~chan int }](x T) { +// for range x {} +// for i := range x { _ = i } +// for i, _ := range x { _ = i } // TODO(gri) should get an error here: channels only return one value +// } +// +// func _[T interface{ ~string | ~chan<-int }](x T) { +// for i := range x /* ERROR send-only channel */ { _ = i } +// } // type inference checks diff --git a/src/cmd/compile/internal/types2/testdata/examples/constraints.go2 b/src/cmd/compile/internal/types2/testdata/examples/constraints.go2 index 28aa19bb12..f40d18c63e 100644 --- a/src/cmd/compile/internal/types2/testdata/examples/constraints.go2 +++ b/src/cmd/compile/internal/types2/testdata/examples/constraints.go2 @@ -18,18 +18,25 @@ type ( } ) +type MyInt int + type ( // Arbitrary types may be embedded like interfaces. _ interface{int} _ interface{~int} // Types may be combined into a union. - _ interface{int|~string} + union interface{int|~string} - // Union terms must be unique independent of whether they are ~ or not. - _ interface{int|int /* ERROR duplicate term int */ } - _ interface{int|~ /* ERROR duplicate term int */ int } - _ interface{~int|~ /* ERROR duplicate term int */ int } + // Union terms must describe disjoint (non-overlapping) type sets. + _ interface{int|int /* ERROR overlapping terms int */ } + _ interface{int|~ /* ERROR overlapping terms ~int */ int } + _ interface{~int|~ /* ERROR overlapping terms ~int */ int } + _ interface{~int|MyInt /* ERROR overlapping terms p.MyInt and ~int */ } + _ interface{int|interface{}} + _ interface{int|~string|union} + _ interface{int|~string|interface{int}} + _ interface{union|union /* ERROR overlapping terms p.union and p.union */ } // For now we do not permit interfaces with methods in unions. _ interface{~ /* ERROR invalid use of ~ */ interface{}} @@ -45,6 +52,15 @@ type ( _ interface{~ /* ERROR invalid use of ~ */ bar } ) +// Stand-alone type parameters are not permitted as elements or terms in unions. +type ( + _[T interface{ *T } ] struct{} // ok + _[T interface{ int | *T } ] struct{} // ok + _[T interface{ T /* ERROR cannot embed a type parameter */ } ] struct{} + _[T interface{ ~T /* ERROR cannot embed a type parameter */ } ] struct{} + _[T interface{ int|T /* ERROR cannot embed a type parameter */ }] struct{} +) + // Multiple embedded union elements are intersected. The order in which they // appear in the interface doesn't matter since intersection is a symmetric // operation. @@ -58,3 +74,18 @@ func _[T interface{ ~int; myInt1|myInt2 }]() T { return T(0) } // Here the intersections are empty - there's no type that's in the type set of T. func _[T interface{ myInt1|myInt2; int }]() T { return T(0 /* ERROR cannot convert */ ) } func _[T interface{ int; myInt1|myInt2 }]() T { return T(0 /* ERROR cannot convert */ ) } + +// Union elements may be interfaces as long as they don't define +// any methods or embed comparable. + +type ( + Integer interface{ ~int|~int8|~int16|~int32|~int64 } + Unsigned interface{ ~uint|~uint8|~uint16|~uint32|~uint64 } + Floats interface{ ~float32|~float64 } + Complex interface{ ~complex64|~complex128 } + Number interface{ Integer|Unsigned|Floats|Complex } + Ordered interface{ Integer|Unsigned|Floats|~string } + + _ interface{ Number | error /* ERROR cannot use error in union */ } + _ interface{ Ordered | comparable /* ERROR cannot use comparable in union */ } +) diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue41124.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue41124.go2 index ab535049dd..60650432a4 100644 --- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue41124.go2 +++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue41124.go2 @@ -47,7 +47,7 @@ type _ struct{ } type _ struct{ - I3 // ERROR interface contains type constraints + I3 // ERROR interface is .* comparable } // General composite types. @@ -59,19 +59,19 @@ type ( _ []I1 // ERROR interface is .* comparable _ []I2 // ERROR interface contains type constraints - _ *I3 // ERROR interface contains type constraints + _ *I3 // ERROR interface is .* comparable _ map[I1 /* ERROR interface is .* comparable */ ]I2 // ERROR interface contains type constraints - _ chan I3 // ERROR interface contains type constraints + _ chan I3 // ERROR interface is .* comparable _ func(I1 /* ERROR interface is .* comparable */ ) _ func() I2 // ERROR interface contains type constraints ) // Other cases. -var _ = [...]I3 /* ERROR interface contains type constraints */ {} +var _ = [...]I3 /* ERROR interface is .* comparable */ {} func _(x interface{}) { - _ = x.(I3 /* ERROR interface contains type constraints */ ) + _ = x.(I3 /* ERROR interface is .* comparable */ ) } type T1[_ any] struct{} |