1
- // UNREVIEWED
2
1
// Copyright 2013 The Go Authors. All rights reserved.
3
2
// Use of this source code is governed by a BSD-style
4
3
// license that can be found in the LICENSE file.
@@ -22,9 +21,21 @@ func unimplemented() {
22
21
panic ("unimplemented" )
23
22
}
24
23
24
+ // genericPkg is a source prefix for packages that contain generic code.
25
+ const genericPkg = "package generic_"
26
+
27
+ // brokenPkg is a source prefix for packages that are not expected to parse
28
+ // or type-check cleanly. They are always parsed assuming that they contain
29
+ // generic code.
30
+ const brokenPkg = "package broken_"
31
+
25
32
func parseSrc (path , src string ) (* syntax.File , error ) {
33
+ var mode syntax.Mode
34
+ if strings .HasPrefix (src , genericPkg ) || strings .HasPrefix (src , brokenPkg ) {
35
+ mode = syntax .AllowGenerics
36
+ }
26
37
errh := func (error ) {} // dummy error handler so that parsing continues in presence of errors
27
- return syntax .Parse (syntax .NewFileBase (path ), strings .NewReader (src ), errh , nil , syntax . AllowGenerics )
38
+ return syntax .Parse (syntax .NewFileBase (path ), strings .NewReader (src ), errh , nil , mode )
28
39
}
29
40
30
41
func pkgFor (path , source string , info * Info ) (* Package , error ) {
@@ -182,9 +193,6 @@ func TestValuesInfo(t *testing.T) {
182
193
}
183
194
184
195
func TestTypesInfo (t * testing.T ) {
185
- // Test sources that are not expected to typecheck must start with the broken prefix.
186
- const broken = "package broken_"
187
-
188
196
var tests = []struct {
189
197
src string
190
198
expr string // expression
@@ -315,37 +323,37 @@ func TestTypesInfo(t *testing.T) {
315
323
},
316
324
317
325
// tests for broken code that doesn't parse or type-check
318
- {broken + `x0; func _() { var x struct {f string}; x.f := 0 }` , `x.f` , `string` },
319
- {broken + `x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}` , `z` , `string` },
320
- {broken + `x2; func _() { var a, b string; type x struct {f string}; z := &x{f: a, f: b,}}` , `b` , `string` },
321
- {broken + `x3; var x = panic("");` , `panic` , `func(interface{})` },
326
+ {brokenPkg + `x0; func _() { var x struct {f string}; x.f := 0 }` , `x.f` , `string` },
327
+ {brokenPkg + `x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}` , `z` , `string` },
328
+ {brokenPkg + `x2; func _() { var a, b string; type x struct {f string}; z := &x{f: a, f: b,}}` , `b` , `string` },
329
+ {brokenPkg + `x3; var x = panic("");` , `panic` , `func(interface{})` },
322
330
{`package x4; func _() { panic("") }` , `panic` , `func(interface{})` },
323
- {broken + `x5; func _() { var x map[string][...]int; x = map[string][...]int{"": {1,2,3}} }` , `x` , `map[string][-1]int` },
331
+ {brokenPkg + `x5; func _() { var x map[string][...]int; x = map[string][...]int{"": {1,2,3}} }` , `x` , `map[string][-1]int` },
324
332
325
333
// parameterized functions
326
- {`package p0; func f[T any](T); var _ = f[int]` , `f` , `func[T₁ interface{}](T₁)` },
327
- {`package p1; func f[T any](T); var _ = f[int]` , `f[int]` , `func(int)` },
328
- {`package p2; func f[T any](T); func _() { f(42) }` , `f` , `func[T₁ interface{}](T₁)` },
329
- {`package p3; func f[T any](T); func _() { f(42) }` , `f(42)` , `()` },
334
+ {genericPkg + ` p0; func f[T any](T); var _ = f[int]` , `f` , `func[T₁ interface{}](T₁)` },
335
+ {genericPkg + ` p1; func f[T any](T); var _ = f[int]` , `f[int]` , `func(int)` },
336
+ {genericPkg + ` p2; func f[T any](T); func _() { f(42) }` , `f` , `func[T₁ interface{}](T₁)` },
337
+ {genericPkg + ` p3; func f[T any](T); func _() { f(42) }` , `f(42)` , `()` },
330
338
331
339
// type parameters
332
- {`package t0; type t[] int; var _ t` , `t` , `t0 .t` }, // t[] is a syntax error that is ignored in this test in favor of t
333
- {`package t1; type t[P any] int; var _ t[int]` , `t` , `t1 .t[P₁ interface{}]` },
334
- {`package t2; type t[P interface{}] int; var _ t[int]` , `t` , `t2 .t[P₁ interface{}]` },
335
- {`package t3; type t[P, Q interface{}] int; var _ t[int, int]` , `t` , `t3 .t[P₁, Q₂ interface{}]` },
336
- {broken + `t4; type t[P, Q interface{ m() }] int; var _ t[int, int]` , `t` , `broken_t4.t[P₁, Q₂ interface{m()}]` },
340
+ {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
341
+ {genericPkg + ` t1; type t[P any] int; var _ t[int]` , `t` , `generic_t1 .t[P₁ interface{}]` },
342
+ {genericPkg + ` t2; type t[P interface{}] int; var _ t[int]` , `t` , `generic_t2 .t[P₁ interface{}]` },
343
+ {genericPkg + ` t3; type t[P, Q interface{}] int; var _ t[int, int]` , `t` , `generic_t3 .t[P₁, Q₂ interface{}]` },
344
+ {brokenPkg + `t4; type t[P, Q interface{ m() }] int; var _ t[int, int]` , `t` , `broken_t4.t[P₁, Q₂ interface{m()}]` },
337
345
338
346
// instantiated types must be sanitized
339
- {`package g0; type t[P any] int; var x struct{ f t[int] }; var _ = x.f` , `x.f` , `g0 .t[int]` },
347
+ {genericPkg + ` g0; type t[P any] int; var x struct{ f t[int] }; var _ = x.f` , `x.f` , `generic_g0 .t[int]` },
340
348
341
349
// issue 45096
342
- {`package issue45096; func _[T interface{ type int8, int16, int32 }](x T) { _ = x < 0 }` , `0` , `T₁` },
350
+ {genericPkg + ` issue45096; func _[T interface{ type int8, int16, int32 }](x T) { _ = x < 0 }` , `0` , `T₁` },
343
351
}
344
352
345
353
for _ , test := range tests {
346
354
info := Info {Types : make (map [syntax.Expr ]TypeAndValue )}
347
355
var name string
348
- if strings .HasPrefix (test .src , broken ) {
356
+ if strings .HasPrefix (test .src , brokenPkg ) {
349
357
var err error
350
358
name , err = mayTypecheck (t , "TypesInfo" , test .src , & info )
351
359
if err == nil {
@@ -383,103 +391,103 @@ func TestInferredInfo(t *testing.T) {
383
391
targs []string
384
392
sig string
385
393
}{
386
- {`package p0; func f[T any](T); func _() { f(42) }` ,
394
+ {genericPkg + ` p0; func f[T any](T); func _() { f(42) }` ,
387
395
`f` ,
388
396
[]string {`int` },
389
397
`func(int)` ,
390
398
},
391
- {`package p1; func f[T any](T) T; func _() { f('@') }` ,
399
+ {genericPkg + ` p1; func f[T any](T) T; func _() { f('@') }` ,
392
400
`f` ,
393
401
[]string {`rune` },
394
402
`func(rune) rune` ,
395
403
},
396
- {`package p2; func f[T any](...T) T; func _() { f(0i) }` ,
404
+ {genericPkg + ` p2; func f[T any](...T) T; func _() { f(0i) }` ,
397
405
`f` ,
398
406
[]string {`complex128` },
399
407
`func(...complex128) complex128` ,
400
408
},
401
- {`package p3; func f[A, B, C any](A, *B, []C); func _() { f(1.2, new(string), []byte{}) }` ,
409
+ {genericPkg + ` p3; func f[A, B, C any](A, *B, []C); func _() { f(1.2, new(string), []byte{}) }` ,
402
410
`f` ,
403
411
[]string {`float64` , `string` , `byte` },
404
412
`func(float64, *string, []byte)` ,
405
413
},
406
- {`package p4; func f[A, B any](A, *B, ...[]B); func _() { f(1.2, new(byte)) }` ,
414
+ {genericPkg + ` p4; func f[A, B any](A, *B, ...[]B); func _() { f(1.2, new(byte)) }` ,
407
415
`f` ,
408
416
[]string {`float64` , `byte` },
409
417
`func(float64, *byte, ...[]byte)` ,
410
418
},
411
419
412
420
// we don't know how to translate these but we can type-check them
413
- {`package q0; type T struct{}; func (T) m[P any](P); func _(x T) { x.m(42) }` ,
421
+ {genericPkg + ` q0; type T struct{}; func (T) m[P any](P); func _(x T) { x.m(42) }` ,
414
422
`x.m` ,
415
423
[]string {`int` },
416
424
`func(int)` ,
417
425
},
418
- {`package q1; type T struct{}; func (T) m[P any](P) P; func _(x T) { x.m(42) }` ,
426
+ {genericPkg + ` q1; type T struct{}; func (T) m[P any](P) P; func _(x T) { x.m(42) }` ,
419
427
`x.m` ,
420
428
[]string {`int` },
421
429
`func(int) int` ,
422
430
},
423
- {`package q2; type T struct{}; func (T) m[P any](...P) P; func _(x T) { x.m(42) }` ,
431
+ {genericPkg + ` q2; type T struct{}; func (T) m[P any](...P) P; func _(x T) { x.m(42) }` ,
424
432
`x.m` ,
425
433
[]string {`int` },
426
434
`func(...int) int` ,
427
435
},
428
- {`package q3; type T struct{}; func (T) m[A, B, C any](A, *B, []C); func _(x T) { x.m(1.2, new(string), []byte{}) }` ,
436
+ {genericPkg + ` q3; type T struct{}; func (T) m[A, B, C any](A, *B, []C); func _(x T) { x.m(1.2, new(string), []byte{}) }` ,
429
437
`x.m` ,
430
438
[]string {`float64` , `string` , `byte` },
431
439
`func(float64, *string, []byte)` ,
432
440
},
433
- {`package q4; type T struct{}; func (T) m[A, B any](A, *B, ...[]B); func _(x T) { x.m(1.2, new(byte)) }` ,
441
+ {genericPkg + ` q4; type T struct{}; func (T) m[A, B any](A, *B, ...[]B); func _(x T) { x.m(1.2, new(byte)) }` ,
434
442
`x.m` ,
435
443
[]string {`float64` , `byte` },
436
444
`func(float64, *byte, ...[]byte)` ,
437
445
},
438
446
439
- {`package r0; type T[P any] struct{}; func (_ T[P]) m[Q any](Q); func _[P any](x T[P]) { x.m(42) }` ,
447
+ {genericPkg + ` r0; type T[P any] struct{}; func (_ T[P]) m[Q any](Q); func _[P any](x T[P]) { x.m(42) }` ,
440
448
`x.m` ,
441
449
[]string {`int` },
442
450
`func(int)` ,
443
451
},
444
452
// TODO(gri) record method type parameters in syntax.FuncType so we can check this
445
- // {`package r1; type T interface{ m[P any](P) }; func _(x T) { x.m(4.2) }`,
453
+ // {genericPkg + ` r1; type T interface{ m[P any](P) }; func _(x T) { x.m(4.2) }`,
446
454
// `x.m`,
447
455
// []string{`float64`},
448
456
// `func(float64)`,
449
457
// },
450
458
451
- {`package s1; func f[T any, P interface{type *T}](x T); func _(x string) { f(x) }` ,
459
+ {genericPkg + ` s1; func f[T any, P interface{type *T}](x T); func _(x string) { f(x) }` ,
452
460
`f` ,
453
461
[]string {`string` , `*string` },
454
462
`func(x string)` ,
455
463
},
456
- {`package s2; func f[T any, P interface{type *T}](x []T); func _(x []int) { f(x) }` ,
464
+ {genericPkg + ` s2; func f[T any, P interface{type *T}](x []T); func _(x []int) { f(x) }` ,
457
465
`f` ,
458
466
[]string {`int` , `*int` },
459
467
`func(x []int)` ,
460
468
},
461
- {`package s3; type C[T any] interface{type chan<- T}; func f[T any, P C[T]](x []T); func _(x []int) { f(x) }` ,
469
+ {genericPkg + ` s3; type C[T any] interface{type chan<- T}; func f[T any, P C[T]](x []T); func _(x []int) { f(x) }` ,
462
470
`f` ,
463
471
[]string {`int` , `chan<- int` },
464
472
`func(x []int)` ,
465
473
},
466
- {`package 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) }` ,
474
+ {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) }` ,
467
475
`f` ,
468
476
[]string {`int` , `chan<- int` , `chan<- []*chan<- int` },
469
477
`func(x []int)` ,
470
478
},
471
479
472
- {`package t1; func f[T any, P interface{type *T}]() T; func _() { _ = f[string] }` ,
480
+ {genericPkg + ` t1; func f[T any, P interface{type *T}]() T; func _() { _ = f[string] }` ,
473
481
`f` ,
474
482
[]string {`string` , `*string` },
475
483
`func() string` ,
476
484
},
477
- {`package t2; type C[T any] interface{type chan<- T}; func f[T any, P C[T]]() []T; func _() { _ = f[int] }` ,
485
+ {genericPkg + ` t2; type C[T any] interface{type chan<- T}; func f[T any, P C[T]]() []T; func _() { _ = f[int] }` ,
478
486
`f` ,
479
487
[]string {`int` , `chan<- int` },
480
488
`func() []int` ,
481
489
},
482
- {`package t3; type C[T any] interface{type chan<- T}; func f[T any, P C[T], Q C[[]*P]]() []T; func _() { _ = f[int] }` ,
490
+ {genericPkg + ` t3; type C[T any] interface{type chan<- T}; func f[T any, P C[T], Q C[[]*P]]() []T; func _() { _ = f[int] }` ,
483
491
`f` ,
484
492
[]string {`int` , `chan<- int` , `chan<- []*chan<- int` },
485
493
`func() []int` ,
@@ -551,10 +559,10 @@ func TestDefsInfo(t *testing.T) {
551
559
552
560
// generic types must be sanitized
553
561
// (need to use sufficiently nested types to provoke unexpanded types)
554
- {`package g0; type t[P any] P; const x = t[int](42)` , `x` , `const g0 .x g0 .t[int]` },
555
- {`package g1; type t[P any] P; var x = t[int](42)` , `x` , `var g1 .x g1 .t[int]` },
556
- {`package g2; type t[P any] P; type x struct{ f t[int] }` , `x` , `type g2 .x struct{f g2 .t[int]}` },
557
- {`package g3; type t[P any] P; func f(x struct{ f t[string] }); var g = f` , `g` , `var g3 .g func(x struct{f g3 .t[string]})` },
562
+ {genericPkg + ` g0; type t[P any] P; const x = t[int](42)` , `x` , `const generic_g0 .x generic_g0 .t[int]` },
563
+ {genericPkg + ` g1; type t[P any] P; var x = t[int](42)` , `x` , `var generic_g1 .x generic_g1 .t[int]` },
564
+ {genericPkg + ` g2; type t[P any] P; type x struct{ f t[int] }` , `x` , `type generic_g2 .x struct{f generic_g2 .t[int]}` },
565
+ {genericPkg + ` g3; type t[P any] P; func f(x struct{ f t[string] }); var g = f` , `g` , `var generic_g3 .g func(x struct{f generic_g3 .t[string]})` },
558
566
}
559
567
560
568
for _ , test := range tests {
@@ -596,10 +604,10 @@ func TestUsesInfo(t *testing.T) {
596
604
597
605
// generic types must be sanitized
598
606
// (need to use sufficiently nested types to provoke unexpanded types)
599
- {`package g0; func _() { _ = x }; type t[P any] P; const x = t[int](42)` , `x` , `const g0 .x g0 .t[int]` },
600
- {`package g1; func _() { _ = x }; type t[P any] P; var x = t[int](42)` , `x` , `var g1 .x g1 .t[int]` },
601
- {`package g2; func _() { type _ x }; type t[P any] P; type x struct{ f t[int] }` , `x` , `type g2 .x struct{f g2 .t[int]}` },
602
- {`package g3; func _() { _ = f }; type t[P any] P; func f(x struct{ f t[string] })` , `f` , `func g3 .f(x struct{f g3 .t[string]})` },
607
+ {genericPkg + ` g0; func _() { _ = x }; type t[P any] P; const x = t[int](42)` , `x` , `const generic_g0 .x generic_g0 .t[int]` },
608
+ {genericPkg + ` g1; func _() { _ = x }; type t[P any] P; var x = t[int](42)` , `x` , `var generic_g1 .x generic_g1 .t[int]` },
609
+ {genericPkg + ` g2; func _() { type _ x }; type t[P any] P; type x struct{ f t[int] }` , `x` , `type generic_g2 .x struct{f generic_g2 .t[int]}` },
610
+ {genericPkg + ` g3; func _() { _ = f }; type t[P any] P; func f(x struct{ f t[string] })` , `f` , `func generic_g3 .f(x struct{f generic_g3 .t[string]})` },
603
611
}
604
612
605
613
for _ , test := range tests {
@@ -1560,6 +1568,50 @@ func F(){
1560
1568
}
1561
1569
}
1562
1570
1571
+ func TestConvertibleTo (t * testing.T ) {
1572
+ for _ , test := range []struct {
1573
+ v , t Type
1574
+ want bool
1575
+ }{
1576
+ {Typ [Int ], Typ [Int ], true },
1577
+ {Typ [Int ], Typ [Float32 ], true },
1578
+ {newDefined (Typ [Int ]), Typ [Int ], true },
1579
+ {newDefined (new (Struct )), new (Struct ), true },
1580
+ {newDefined (Typ [Int ]), new (Struct ), false },
1581
+ {Typ [UntypedInt ], Typ [Int ], true },
1582
+ // Untyped string values are not permitted by the spec, so the below
1583
+ // behavior is undefined.
1584
+ {Typ [UntypedString ], Typ [String ], true },
1585
+ } {
1586
+ if got := ConvertibleTo (test .v , test .t ); got != test .want {
1587
+ t .Errorf ("ConvertibleTo(%v, %v) = %t, want %t" , test .v , test .t , got , test .want )
1588
+ }
1589
+ }
1590
+ }
1591
+
1592
+ func TestAssignableTo (t * testing.T ) {
1593
+ for _ , test := range []struct {
1594
+ v , t Type
1595
+ want bool
1596
+ }{
1597
+ {Typ [Int ], Typ [Int ], true },
1598
+ {Typ [Int ], Typ [Float32 ], false },
1599
+ {newDefined (Typ [Int ]), Typ [Int ], false },
1600
+ {newDefined (new (Struct )), new (Struct ), true },
1601
+ {Typ [UntypedBool ], Typ [Bool ], true },
1602
+ {Typ [UntypedString ], Typ [Bool ], false },
1603
+ // Neither untyped string nor untyped numeric assignments arise during
1604
+ // normal type checking, so the below behavior is technically undefined by
1605
+ // the spec.
1606
+ {Typ [UntypedString ], Typ [String ], true },
1607
+ {Typ [UntypedInt ], Typ [Int ], true },
1608
+ } {
1609
+ if got := AssignableTo (test .v , test .t ); got != test .want {
1610
+ t .Errorf ("AssignableTo(%v, %v) = %t, want %t" , test .v , test .t , got , test .want )
1611
+ }
1612
+ }
1613
+ }
1614
+
1563
1615
func TestIdentical_issue15173 (t * testing.T ) {
1564
1616
// Identical should allow nil arguments and be symmetric.
1565
1617
for _ , test := range []struct {
0 commit comments