]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.typeparams] go/types: disallow type list handling
authorRob Findley <rfindley@google.com>
Thu, 10 Jun 2021 15:26:08 +0000 (11:26 -0400)
committerRobert Findley <rfindley@google.com>
Thu, 17 Jun 2021 02:14:52 +0000 (02:14 +0000)
This is a port of CL 324571 to go/types, though type list handling is
guarded by a const rather than a config option.

Change-Id: I91c940fead048980603e0bb56fcc896dbef4f94c
Reviewed-on: https://go-review.googlesource.com/c/go/+/326683
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/api.go
src/go/types/api_test.go
src/go/types/api_typeparams_test.go
src/go/types/interface.go
src/go/types/testdata/examples/constraints.go2
src/go/types/typestring_test.go

index 30f8ded744adcd42d46dd97638aa34002efd6a2f..d3a95bc9910b8a7aa714701c67ab7894fcffb0d1 100644 (file)
@@ -34,6 +34,8 @@ import (
        "go/token"
 )
 
+const allowTypeLists = false
+
 // An Error describes a type-checking error; it implements the error interface.
 // A "soft" error is an error that still permits a valid interpretation of a
 // package (such as "unused variable"); "hard" errors may lead to unpredictable
index 5a2d4a4ca38e187cd0d21696718d8a4fe77bf7d4..6a7218d90f46f59299b049dd9364349fcd31528c 100644 (file)
@@ -349,7 +349,7 @@ func TestTypesInfo(t *testing.T) {
                {genericPkg + `g0; type t[P any] int; var x struct{ f t[int] }; var _ = x.f`, `x.f`, `generic_g0.t[int]`},
 
                // issue 45096
-               {genericPkg + `issue45096; func _[T interface{ type int8, int16, int32  }](x T) { _ = x < 0 }`, `0`, `T₁`},
+               {genericPkg + `issue45096; func _[T interface{ ~int8 | ~int16 | ~int32  }](x T) { _ = x < 0 }`, `0`, `T₁`},
        }
 
        for _, test := range tests {
index 4a2adce9a29774d2d6464568912c806cd262a9ca..d9117b84129bc362788281369923239cd299d374 100644 (file)
@@ -45,38 +45,38 @@ func TestInferredInfo(t *testing.T) {
                        `func(float64, *byte, ...[]byte)`,
                },
 
-               {genericPkg + `s1; func f[T any, P interface{type *T}](x T); func _(x string) { f(x) }`,
+               {genericPkg + `s1; func f[T any, P interface{~*T}](x T); func _(x string) { f(x) }`,
                        `f`,
                        []string{`string`, `*string`},
                        `func(x string)`,
                },
-               {genericPkg + `s2; func f[T any, P interface{type *T}](x []T); func _(x []int) { f(x) }`,
+               {genericPkg + `s2; func f[T any, P interface{~*T}](x []T); func _(x []int) { f(x) }`,
                        `f`,
                        []string{`int`, `*int`},
                        `func(x []int)`,
                },
-               {genericPkg + `s3; type C[T any] interface{type chan<- T}; func f[T any, P C[T]](x []T); func _(x []int) { f(x) }`,
+               {genericPkg + `s3; type C[T any] interface{~chan<- T}; func f[T any, P C[T]](x []T); func _(x []int) { f(x) }`,
                        `f`,
                        []string{`int`, `chan<- int`},
                        `func(x []int)`,
                },
-               {genericPkg + `s4; type C[T any] interface{type chan<- T}; func f[T any, P C[T], Q C[[]*P]](x []T); func _(x []int) { f(x) }`,
+               {genericPkg + `s4; type C[T any] interface{~chan<- T}; func f[T any, P C[T], Q C[[]*P]](x []T); func _(x []int) { f(x) }`,
                        `f`,
                        []string{`int`, `chan<- int`, `chan<- []*chan<- int`},
                        `func(x []int)`,
                },
 
-               {genericPkg + `t1; func f[T any, P interface{type *T}]() T; func _() { _ = f[string] }`,
+               {genericPkg + `t1; func f[T any, P interface{~*T}]() T; func _() { _ = f[string] }`,
                        `f`,
                        []string{`string`, `*string`},
                        `func() string`,
                },
-               {genericPkg + `t2; type C[T any] interface{type chan<- T}; func f[T any, P C[T]]() []T; func _() { _ = f[int] }`,
+               {genericPkg + `t2; type C[T any] interface{~chan<- T}; func f[T any, P C[T]]() []T; func _() { _ = f[int] }`,
                        `f`,
                        []string{`int`, `chan<- int`},
                        `func() []int`,
                },
-               {genericPkg + `t3; type C[T any] interface{type chan<- T}; func f[T any, P C[T], Q C[[]*P]]() []T; func _() { _ = f[int] }`,
+               {genericPkg + `t3; type C[T any] interface{~chan<- T}; func f[T any, P C[T], Q C[[]*P]]() []T; func _() { _ = f[int] }`,
                        `f`,
                        []string{`int`, `chan<- int`, `chan<- []*chan<- int`},
                        `func() []int`,
index 9b4d080c813f8a9686d5873fab527a067cda4e02..947e76dc17eb634041b80b305d469da28112e0a1 100644 (file)
@@ -34,7 +34,13 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
                        continue // ignore
                }
 
+               // TODO(rfindley) Remove type list handling once the parser doesn't accept type lists anymore.
                if name.Name == "type" {
+                       // Report an error for the first type list per interface
+                       // if we don't allow type lists, but continue.
+                       if !allowTypeLists && tlist == nil {
+                               check.softErrorf(name, _Todo, "use generalized embedding syntax instead of a type list")
+                       }
                        // For now, collect all type list entries as if it
                        // were a single union, where each union element is
                        // of the form ~T.
@@ -43,7 +49,9 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
                        op.Op = token.TILDE
                        op.X = f.Type
                        tlist = append(tlist, op)
-                       if tname != nil && tname != name {
+                       // Report an error if we have multiple type lists in an
+                       // interface, but only if they are permitted in the first place.
+                       if allowTypeLists && tname != nil && tname != name {
                                check.errorf(name, _Todo, "cannot have multiple type lists in an interface")
                        }
                        tname = name
index f6291ccf7dd73650dab795bf11881f468e1099f1..61992e4c2a8e408197bccc1d1e11d404b6628530 100644 (file)
@@ -6,6 +6,18 @@
 
 package p
 
+type (
+       // Type lists are processed as unions but an error is reported.
+       // TODO(gri) remove this once the parser doesn't accept type lists anymore.
+       _ interface{
+               type /* ERROR use generalized embedding syntax instead of a type list */ int
+       }
+       _ interface{
+               type /* ERROR use generalized embedding syntax instead of a type list */ int
+               type float32
+       }
+)
+
 type (
        // Arbitrary types may be embedded like interfaces.
        _ interface{int}
index 0e35a3dbf1c54d19ad03f3702d3cc3fb42d15546..f02c0d9c18db8aba78693058341612fe25ad6b04 100644 (file)
@@ -95,7 +95,6 @@ var independentTestTypes = []testEntry{
        dup("interface{}"),
        dup("interface{m()}"),
        dup(`interface{String() string; m(int) float32}`),
-       {"interface{type int, float32, complex128}", "interface{~int|~float32|~complex128}"},
        dup("interface{int|float32|complex128}"),
        dup("interface{int|~float32|~complex128}"),