]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile/internal/types2: add Config.AllowTypeLists to control...
authorRobert Griesemer <gri@golang.org>
Thu, 3 Jun 2021 00:50:47 +0000 (17:50 -0700)
committerRobert Griesemer <gri@golang.org>
Thu, 3 Jun 2021 03:55:44 +0000 (03:55 +0000)
Eventually the flag should not be set anymore, but we set it in the
compiler until all tests have been converted.

Also, convert some more types2 tests to use the type set notation.

Change-Id: I616599a3473451ab75d67272016b2bd3de6835af
Reviewed-on: https://go-review.googlesource.com/c/go/+/324571
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/noder/irgen.go
src/cmd/compile/internal/types2/api.go
src/cmd/compile/internal/types2/api_test.go
src/cmd/compile/internal/types2/interface.go
src/cmd/compile/internal/types2/testdata/examples/constraints.go2
src/cmd/compile/internal/types2/typestring_test.go

index 3f362e9d2bc86c65e317ad862eee423e310c5274..b70d82d7e674947bec653eee962d8d105f79a985 100644 (file)
@@ -38,6 +38,7 @@ func checkFiles(noders []*noder, importer types2.Importer) (posMap, *types2.Pack
                GoVersion:             base.Flag.Lang,
                IgnoreLabels:          true, // parser already checked via syntax.CheckBranches mode
                CompilerErrorMessages: true, // use error strings matching existing compiler errors
+               AllowTypeLists:        true, // remove this line once all tests use type set syntax
                Error: func(err error) {
                        terr := err.(types2.Error)
                        base.ErrorfAt(m.makeXPos(terr.Pos), "%s", terr.Msg)
index 2939dcc0bdf27356ae1c5a99abfd44c836004060..433250f02c8d92345faef6867730413f0bc25a70 100644 (file)
@@ -125,6 +125,12 @@ type Config struct {
        // TODO(gri) Consolidate error messages and remove this flag.
        CompilerErrorMessages bool
 
+       // If AllowTypeLists is set, the type list syntax is permitted
+       // in an interface in addition to the type set syntax.
+       // TODO(gri) Remove once type lists are no longer supported by
+       //           the parser.
+       AllowTypeLists bool
+
        // If go115UsesCgo is set, the type checker expects the
        // _cgo_gotypes.go file generated by running cmd/cgo to be
        // provided as a package source file. Qualified identifiers
index d82d29cad877939f28a84a0ac3e2d4cc56b33c45..49d710067a8116428235cc7e8d1c7a52b7ebcad8 100644 (file)
@@ -345,7 +345,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`, `generic_issue45096.T₁`},
+               {genericPkg + `issue45096; func _[T interface{ ~int8 | ~int16 | ~int32 }](x T) { _ = x < 0 }`, `0`, `generic_issue45096.T₁`},
        }
 
        for _, test := range tests {
@@ -454,38 +454,38 @@ func TestInferredInfo(t *testing.T) {
                //      `func(float64)`,
                // },
 
-               {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 770b8ba5cc8ae2340d783750faa4489ca931f8bb..c79026f00dd1e74814b616ae5c2b922eb508ded6 100644 (file)
@@ -34,18 +34,25 @@ func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType
                        continue // ignore
                }
 
+               // TODO(gri) Remove type list handling once the parser doesn't accept type lists anymore.
                if name == "type" {
+                       // Report an error for the first type list per interface
+                       // if we don't allow type lists, but continue.
+                       if !check.conf.AllowTypeLists && tlist == nil {
+                               check.softErrorf(f.Name, "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.
-                       // TODO(gri) remove once we disallow type lists
                        op := new(syntax.Operation)
                        // We should also set the position (but there is no setter);
                        // we don't care because this code will eventually go away.
                        op.Op = syntax.Tilde
                        op.X = f.Type
                        tlist = append(tlist, op)
-                       if tname != nil && tname != f.Name {
+                       // Report an error if we have multiple type lists in an
+                       // interface, but only if they are permitted in the first place.
+                       if check.conf.AllowTypeLists && tname != nil && tname != f.Name {
                                check.error(f.Name, "cannot have multiple type lists in an interface")
                        }
                        tname = f.Name
index efefaa2a256ba220d85adceee325adeb70be9856..d9805fe6940a9c665a9a712c63aef9130f0fa4af 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 8d0ca760bfce8b53671670fc9d95f88707347e03..88103b81b12a086f6260dcd2f18351efec8261db 100644 (file)
@@ -91,7 +91,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}"),