]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/go/types/api_test.go
[dev.typeparams] merge dev.regabi (618e3c1) into dev.typeparams
[gostls13.git] / src / go / types / api_test.go
index 014cd5282e6a1f8c21b91b2108a3d8881c9aa102..3ea14c9316b1c92a9a14ba72beb0779add688e7e 100644 (file)
@@ -188,6 +188,9 @@ func TestValuesInfo(t *testing.T) {
 }
 
 func TestTypesInfo(t *testing.T) {
+       // Test sources that are not expected to typecheck must start with the broken prefix.
+       const broken = "package broken_"
+
        var tests = []struct {
                src  string
                expr string // expression
@@ -200,6 +203,39 @@ func TestTypesInfo(t *testing.T) {
                {`package b3; var x interface{} = 0i`, `0i`, `complex128`},
                {`package b4; var x interface{} = "foo"`, `"foo"`, `string`},
 
+               // uses of nil
+               {`package n0; var _ *int = nil`, `nil`, `untyped nil`},
+               {`package n1; var _ func() = nil`, `nil`, `untyped nil`},
+               {`package n2; var _ []byte = nil`, `nil`, `untyped nil`},
+               {`package n3; var _ map[int]int = nil`, `nil`, `untyped nil`},
+               {`package n4; var _ chan int = nil`, `nil`, `untyped nil`},
+               {`package n5; var _ interface{} = nil`, `nil`, `untyped nil`},
+               {`package n6; import "unsafe"; var _ unsafe.Pointer = nil`, `nil`, `untyped nil`},
+
+               {`package n10; var (x *int; _ = x == nil)`, `nil`, `untyped nil`},
+               {`package n11; var (x func(); _ = x == nil)`, `nil`, `untyped nil`},
+               {`package n12; var (x []byte; _ = x == nil)`, `nil`, `untyped nil`},
+               {`package n13; var (x map[int]int; _ = x == nil)`, `nil`, `untyped nil`},
+               {`package n14; var (x chan int; _ = x == nil)`, `nil`, `untyped nil`},
+               {`package n15; var (x interface{}; _ = x == nil)`, `nil`, `untyped nil`},
+               {`package n15; import "unsafe"; var (x unsafe.Pointer; _ = x == nil)`, `nil`, `untyped nil`},
+
+               {`package n20; var _ = (*int)(nil)`, `nil`, `untyped nil`},
+               {`package n21; var _ = (func())(nil)`, `nil`, `untyped nil`},
+               {`package n22; var _ = ([]byte)(nil)`, `nil`, `untyped nil`},
+               {`package n23; var _ = (map[int]int)(nil)`, `nil`, `untyped nil`},
+               {`package n24; var _ = (chan int)(nil)`, `nil`, `untyped nil`},
+               {`package n25; var _ = (interface{})(nil)`, `nil`, `untyped nil`},
+               {`package n26; import "unsafe"; var _ = unsafe.Pointer(nil)`, `nil`, `untyped nil`},
+
+               {`package n30; func f(*int) { f(nil) }`, `nil`, `untyped nil`},
+               {`package n31; func f(func()) { f(nil) }`, `nil`, `untyped nil`},
+               {`package n32; func f([]byte) { f(nil) }`, `nil`, `untyped nil`},
+               {`package n33; func f(map[int]int) { f(nil) }`, `nil`, `untyped nil`},
+               {`package n34; func f(chan int) { f(nil) }`, `nil`, `untyped nil`},
+               {`package n35; func f(interface{}) { f(nil) }`, `nil`, `untyped nil`},
+               {`package n35; import "unsafe"; func f(unsafe.Pointer) { f(nil) }`, `nil`, `untyped nil`},
+
                // comma-ok expressions
                {`package p0; var x interface{}; var _, _ = x.(int)`,
                        `x.(int)`,
@@ -281,25 +317,27 @@ func TestTypesInfo(t *testing.T) {
                },
 
                // tests for broken code that doesn't parse or type-check
-               {`package x0; func _() { var x struct {f string}; x.f := 0 }`, `x.f`, `string`},
-               {`package x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}`, `z`, `string`},
-               {`package x2; func _() { var a, b string; type x struct {f string}; z := &x{f: a, f: b,}}`, `b`, `string`},
-               {`package x3; var x = panic("");`, `panic`, `func(interface{})`},
+               {broken + `x0; func _() { var x struct {f string}; x.f := 0 }`, `x.f`, `string`},
+               {broken + `x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}`, `z`, `string`},
+               {broken + `x2; func _() { var a, b string; type x struct {f string}; z := &x{f: a; f: b;}}`, `b`, `string`},
+               {broken + `x3; var x = panic("");`, `panic`, `func(interface{})`},
                {`package x4; func _() { panic("") }`, `panic`, `func(interface{})`},
-               {`package x5; func _() { var x map[string][...]int; x = map[string][...]int{"": {1,2,3}} }`, `x`, `map[string][-1]int`},
+               {broken + `x5; func _() { var x map[string][...]int; x = map[string][...]int{"": {1,2,3}} }`, `x`, `map[string][-1]int`},
 
                // parameterized functions
                {genericPkg + `p0; func f[T any](T); var _ = f(int)`, `f`, `func[T₁ any](T₁)`},
                {genericPkg + `p1; func f[T any](T); var _ = f(int)`, `f(int)`, `func(int)`},
-               {genericPkg + `p2; func f[T any](T); var _ = f(42)`, `f`, `func[T₁ any](T₁)`},
-               {genericPkg + `p2; func f[T any](T); var _ = f(42)`, `f(42)`, `()`},
+               {genericPkg + `p2; func f[T any](T); func _() { f(42) }`, `f`, `func[T₁ any](T₁)`},
+               {genericPkg + `p3; func f[T any](T); func _() { f(42) }`, `f(42)`, `()`},
 
                // type parameters
                {genericPkg + `t0; type t[] int; var _ t`, `t`, `generic_t0.t`}, // t[] is a syntax error that is ignored in this test in favor of t
                {genericPkg + `t1; type t[P any] int; var _ t[int]`, `t`, `generic_t1.t[P₁ any]`},
                {genericPkg + `t2; type t[P interface{}] int; var _ t[int]`, `t`, `generic_t2.t[P₁ interface{}]`},
                {genericPkg + `t3; type t[P, Q interface{}] int; var _ t[int, int]`, `t`, `generic_t3.t[P₁, Q₂ interface{}]`},
-               {genericPkg + `t4; type t[P, Q interface{ m() }] int; var _ t[int, int]`, `t`, `generic_t4.t[P₁, Q₂ interface{m()}]`},
+
+               // TODO (rFindley): compare with types2, which resolves the type broken_t4.t[P₁, Q₂ interface{m()}] here
+               {broken + `t4; type t[P, Q interface{ m() }] int; var _ t[int, int]`, `t`, `broken_t4.t`},
 
                // instantiated types must be sanitized
                {genericPkg + `g0; type t[P any] int; var x struct{ f t[int] }; var _ = x.f`, `x.f`, `generic_g0.t[int]`},
@@ -307,7 +345,17 @@ func TestTypesInfo(t *testing.T) {
 
        for _, test := range tests {
                info := Info{Types: make(map[ast.Expr]TypeAndValue)}
-               name, _ := mayTypecheck(t, "TypesInfo", test.src, &info)
+               var name string
+               if strings.HasPrefix(test.src, broken) {
+                       var err error
+                       name, err = mayTypecheck(t, "TypesInfo", test.src, &info)
+                       if err == nil {
+                               t.Errorf("package %s: expected to fail but passed", name)
+                               continue
+                       }
+               } else {
+                       name = mustTypecheck(t, "TypesInfo", test.src, &info)
+               }
 
                // look for expression type
                var typ Type