mirror of
https://github.com/golang/go
synced 2024-11-22 20:40:03 -07:00
[dev.typeparams] cmd/compile/internal/types2: add Config.AllowTypeLists to control type list handling
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>
This commit is contained in:
parent
10d6b36ca3
commit
95c618e99a
@ -38,6 +38,7 @@ func checkFiles(noders []*noder, importer types2.Importer) (posMap, *types2.Pack
|
|||||||
GoVersion: base.Flag.Lang,
|
GoVersion: base.Flag.Lang,
|
||||||
IgnoreLabels: true, // parser already checked via syntax.CheckBranches mode
|
IgnoreLabels: true, // parser already checked via syntax.CheckBranches mode
|
||||||
CompilerErrorMessages: true, // use error strings matching existing compiler errors
|
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) {
|
Error: func(err error) {
|
||||||
terr := err.(types2.Error)
|
terr := err.(types2.Error)
|
||||||
base.ErrorfAt(m.makeXPos(terr.Pos), "%s", terr.Msg)
|
base.ErrorfAt(m.makeXPos(terr.Pos), "%s", terr.Msg)
|
||||||
|
@ -125,6 +125,12 @@ type Config struct {
|
|||||||
// TODO(gri) Consolidate error messages and remove this flag.
|
// TODO(gri) Consolidate error messages and remove this flag.
|
||||||
CompilerErrorMessages bool
|
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
|
// If go115UsesCgo is set, the type checker expects the
|
||||||
// _cgo_gotypes.go file generated by running cmd/cgo to be
|
// _cgo_gotypes.go file generated by running cmd/cgo to be
|
||||||
// provided as a package source file. Qualified identifiers
|
// provided as a package source file. Qualified identifiers
|
||||||
|
@ -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]`},
|
{genericPkg + `g0; type t[P any] int; var x struct{ f t[int] }; var _ = x.f`, `x.f`, `generic_g0.t[int]`},
|
||||||
|
|
||||||
// issue 45096
|
// 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 {
|
for _, test := range tests {
|
||||||
@ -454,38 +454,38 @@ func TestInferredInfo(t *testing.T) {
|
|||||||
// `func(float64)`,
|
// `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`,
|
`f`,
|
||||||
[]string{`string`, `*string`},
|
[]string{`string`, `*string`},
|
||||||
`func(x 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`,
|
`f`,
|
||||||
[]string{`int`, `*int`},
|
[]string{`int`, `*int`},
|
||||||
`func(x []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`,
|
`f`,
|
||||||
[]string{`int`, `chan<- int`},
|
[]string{`int`, `chan<- int`},
|
||||||
`func(x []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`,
|
`f`,
|
||||||
[]string{`int`, `chan<- int`, `chan<- []*chan<- int`},
|
[]string{`int`, `chan<- int`, `chan<- []*chan<- int`},
|
||||||
`func(x []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`,
|
`f`,
|
||||||
[]string{`string`, `*string`},
|
[]string{`string`, `*string`},
|
||||||
`func() 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`,
|
`f`,
|
||||||
[]string{`int`, `chan<- int`},
|
[]string{`int`, `chan<- int`},
|
||||||
`func() []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`,
|
`f`,
|
||||||
[]string{`int`, `chan<- int`, `chan<- []*chan<- int`},
|
[]string{`int`, `chan<- int`, `chan<- []*chan<- int`},
|
||||||
`func() []int`,
|
`func() []int`,
|
||||||
|
@ -34,18 +34,25 @@ func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType
|
|||||||
continue // ignore
|
continue // ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(gri) Remove type list handling once the parser doesn't accept type lists anymore.
|
||||||
if name == "type" {
|
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
|
// For now, collect all type list entries as if it
|
||||||
// were a single union, where each union element is
|
// were a single union, where each union element is
|
||||||
// of the form ~T.
|
// of the form ~T.
|
||||||
// TODO(gri) remove once we disallow type lists
|
|
||||||
op := new(syntax.Operation)
|
op := new(syntax.Operation)
|
||||||
// We should also set the position (but there is no setter);
|
// We should also set the position (but there is no setter);
|
||||||
// we don't care because this code will eventually go away.
|
// we don't care because this code will eventually go away.
|
||||||
op.Op = syntax.Tilde
|
op.Op = syntax.Tilde
|
||||||
op.X = f.Type
|
op.X = f.Type
|
||||||
tlist = append(tlist, op)
|
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")
|
check.error(f.Name, "cannot have multiple type lists in an interface")
|
||||||
}
|
}
|
||||||
tname = f.Name
|
tname = f.Name
|
||||||
|
@ -6,6 +6,18 @@
|
|||||||
|
|
||||||
package p
|
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 (
|
type (
|
||||||
// Arbitrary types may be embedded like interfaces.
|
// Arbitrary types may be embedded like interfaces.
|
||||||
_ interface{int}
|
_ interface{int}
|
||||||
|
@ -91,7 +91,6 @@ var independentTestTypes = []testEntry{
|
|||||||
dup("interface{}"),
|
dup("interface{}"),
|
||||||
dup("interface{m()}"),
|
dup("interface{m()}"),
|
||||||
dup(`interface{String() string; m(int) float32}`),
|
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}"),
|
||||||
dup("interface{int|~float32|~complex128}"),
|
dup("interface{int|~float32|~complex128}"),
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user