@@ -42,7 +42,7 @@ func mustTypecheck(t *testing.T, path, source string, info *Info) string {
42
42
return pkg .Name ()
43
43
}
44
44
45
- func mayTypecheck (t * testing.T , path , source string , info * Info ) string {
45
+ func mayTypecheck (t * testing.T , path , source string , info * Info ) ( string , error ) {
46
46
fset := token .NewFileSet ()
47
47
f , err := parser .ParseFile (fset , path , source , 0 )
48
48
if f == nil { // ignore errors unless f is nil
@@ -52,8 +52,8 @@ func mayTypecheck(t *testing.T, path, source string, info *Info) string {
52
52
Error : func (err error ) {},
53
53
Importer : importer .Default (),
54
54
}
55
- pkg , _ := conf .Check (f .Name .Name , fset , []* ast.File {f }, info )
56
- return pkg .Name ()
55
+ pkg , err := conf .Check (f .Name .Name , fset , []* ast.File {f }, info )
56
+ return pkg .Name (), err
57
57
}
58
58
59
59
func TestValuesInfo (t * testing.T ) {
@@ -175,6 +175,9 @@ func TestValuesInfo(t *testing.T) {
175
175
}
176
176
177
177
func TestTypesInfo (t * testing.T ) {
178
+ // Test sources that are not expected to typecheck must start with the broken prefix.
179
+ const broken = "package broken_"
180
+
178
181
var tests = []struct {
179
182
src string
180
183
expr string // expression
@@ -187,6 +190,39 @@ func TestTypesInfo(t *testing.T) {
187
190
{`package b3; var x interface{} = 0i` , `0i` , `complex128` },
188
191
{`package b4; var x interface{} = "foo"` , `"foo"` , `string` },
189
192
193
+ // uses of nil
194
+ {`package n0; var _ *int = nil` , `nil` , `untyped nil` },
195
+ {`package n1; var _ func() = nil` , `nil` , `untyped nil` },
196
+ {`package n2; var _ []byte = nil` , `nil` , `untyped nil` },
197
+ {`package n3; var _ map[int]int = nil` , `nil` , `untyped nil` },
198
+ {`package n4; var _ chan int = nil` , `nil` , `untyped nil` },
199
+ {`package n5; var _ interface{} = nil` , `nil` , `untyped nil` },
200
+ {`package n6; import "unsafe"; var _ unsafe.Pointer = nil` , `nil` , `untyped nil` },
201
+
202
+ {`package n10; var (x *int; _ = x == nil)` , `nil` , `untyped nil` },
203
+ {`package n11; var (x func(); _ = x == nil)` , `nil` , `untyped nil` },
204
+ {`package n12; var (x []byte; _ = x == nil)` , `nil` , `untyped nil` },
205
+ {`package n13; var (x map[int]int; _ = x == nil)` , `nil` , `untyped nil` },
206
+ {`package n14; var (x chan int; _ = x == nil)` , `nil` , `untyped nil` },
207
+ {`package n15; var (x interface{}; _ = x == nil)` , `nil` , `untyped nil` },
208
+ {`package n15; import "unsafe"; var (x unsafe.Pointer; _ = x == nil)` , `nil` , `untyped nil` },
209
+
210
+ {`package n20; var _ = (*int)(nil)` , `nil` , `untyped nil` },
211
+ {`package n21; var _ = (func())(nil)` , `nil` , `untyped nil` },
212
+ {`package n22; var _ = ([]byte)(nil)` , `nil` , `untyped nil` },
213
+ {`package n23; var _ = (map[int]int)(nil)` , `nil` , `untyped nil` },
214
+ {`package n24; var _ = (chan int)(nil)` , `nil` , `untyped nil` },
215
+ {`package n25; var _ = (interface{})(nil)` , `nil` , `untyped nil` },
216
+ {`package n26; import "unsafe"; var _ = unsafe.Pointer(nil)` , `nil` , `untyped nil` },
217
+
218
+ {`package n30; func f(*int) { f(nil) }` , `nil` , `untyped nil` },
219
+ {`package n31; func f(func()) { f(nil) }` , `nil` , `untyped nil` },
220
+ {`package n32; func f([]byte) { f(nil) }` , `nil` , `untyped nil` },
221
+ {`package n33; func f(map[int]int) { f(nil) }` , `nil` , `untyped nil` },
222
+ {`package n34; func f(chan int) { f(nil) }` , `nil` , `untyped nil` },
223
+ {`package n35; func f(interface{}) { f(nil) }` , `nil` , `untyped nil` },
224
+ {`package n35; import "unsafe"; func f(unsafe.Pointer) { f(nil) }` , `nil` , `untyped nil` },
225
+
190
226
// comma-ok expressions
191
227
{`package p0; var x interface{}; var _, _ = x.(int)` ,
192
228
`x.(int)` ,
@@ -268,17 +304,27 @@ func TestTypesInfo(t *testing.T) {
268
304
},
269
305
270
306
// tests for broken code that doesn't parse or type-check
271
- {`package x0; func _() { var x struct {f string}; x.f := 0 }` , `x.f` , `string` },
272
- {`package x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}` , `z` , `string` },
273
- {`package x2; func _() { var a, b string; type x struct {f string}; z := &x{f: a; f: b;}}` , `b` , `string` },
274
- {`package x3; var x = panic("");` , `panic` , `func(interface{})` },
307
+ {broken + ` x0; func _() { var x struct {f string}; x.f := 0 }` , `x.f` , `string` },
308
+ {broken + ` x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}` , `z` , `string` },
309
+ {broken + ` x2; func _() { var a, b string; type x struct {f string}; z := &x{f: a; f: b;}}` , `b` , `string` },
310
+ {broken + ` x3; var x = panic("");` , `panic` , `func(interface{})` },
275
311
{`package x4; func _() { panic("") }` , `panic` , `func(interface{})` },
276
- {`package x5; func _() { var x map[string][...]int; x = map[string][...]int{"": {1,2,3}} }` , `x` , `map[string][-1]int` },
312
+ {broken + ` x5; func _() { var x map[string][...]int; x = map[string][...]int{"": {1,2,3}} }` , `x` , `map[string][-1]int` },
277
313
}
278
314
279
315
for _ , test := range tests {
280
316
info := Info {Types : make (map [ast.Expr ]TypeAndValue )}
281
- name := mayTypecheck (t , "TypesInfo" , test .src , & info )
317
+ var name string
318
+ if strings .HasPrefix (test .src , broken ) {
319
+ var err error
320
+ name , err = mayTypecheck (t , "TypesInfo" , test .src , & info )
321
+ if err == nil {
322
+ t .Errorf ("package %s: expected to fail but passed" , name )
323
+ continue
324
+ }
325
+ } else {
326
+ name = mustTypecheck (t , "TypesInfo" , test .src , & info )
327
+ }
282
328
283
329
// look for expression type
284
330
var typ Type
0 commit comments