@@ -414,52 +414,171 @@ func TestBasics(t *testing.T) {
414
414
}
415
415
416
416
func TestDuplicable (t * testing.T ) {
417
- runTests (t , []testcase {
418
- {
419
- "Empty strings are duplicable." ,
420
- `func f(s string) { print(s, s) }` ,
421
- `func _() { f("") }` ,
422
- `func _() { print("", "") }` ,
423
- },
424
- {
425
- "Non-empty string literals are not duplicable." ,
426
- `func f(s string) { print(s, s) }` ,
427
- `func _() { f("hi") }` ,
428
- `func _() {
417
+ t .Run ("basic" , func (t * testing.T ) {
418
+ runTests (t , []testcase {
419
+ {
420
+ "Empty strings are duplicable." ,
421
+ `func f(s string) { print(s, s) }` ,
422
+ `func _() { f("") }` ,
423
+ `func _() { print("", "") }` ,
424
+ },
425
+ {
426
+ "Non-empty string literals are not duplicable." ,
427
+ `func f(s string) { print(s, s) }` ,
428
+ `func _() { f("hi") }` ,
429
+ `func _() {
429
430
var s string = "hi"
430
431
print(s, s)
431
432
}` ,
432
- },
433
- {
434
- "Empty array literals are duplicable." ,
435
- `func f(a [2]int) { print(a, a) }` ,
436
- `func _() { f([2]int{}) }` ,
437
- `func _() { print([2]int{}, [2]int{}) }` ,
438
- },
439
- {
440
- "Non-empty array literals are not duplicable." ,
441
- `func f(a [2]int) { print(a, a) }` ,
442
- `func _() { f([2]int{1, 2}) }` ,
443
- `func _() {
433
+ },
434
+ {
435
+ "Empty array literals are duplicable." ,
436
+ `func f(a [2]int) { print(a, a) }` ,
437
+ `func _() { f([2]int{}) }` ,
438
+ `func _() { print([2]int{}, [2]int{}) }` ,
439
+ },
440
+ {
441
+ "Non-empty array literals are not duplicable." ,
442
+ `func f(a [2]int) { print(a, a) }` ,
443
+ `func _() { f([2]int{1, 2}) }` ,
444
+ `func _() {
444
445
var a [2]int = [2]int{1, 2}
445
446
print(a, a)
446
447
}` ,
447
- },
448
- {
449
- "Empty struct literals are duplicable." ,
450
- `func f(s S) { print(s, s) }; type S struct { x int }` ,
451
- `func _() { f(S{}) }` ,
452
- `func _() { print(S{}, S{}) }` ,
453
- },
454
- {
455
- "Non-empty struct literals are not duplicable." ,
456
- `func f(s S) { print(s, s) }; type S struct { x int }` ,
457
- `func _() { f(S{x: 1}) }` ,
458
- `func _() {
448
+ },
449
+ {
450
+ "Empty struct literals are duplicable." ,
451
+ `func f(s S) { print(s, s) }; type S struct { x int }` ,
452
+ `func _() { f(S{}) }` ,
453
+ `func _() { print(S{}, S{}) }` ,
454
+ },
455
+ {
456
+ "Non-empty struct literals are not duplicable." ,
457
+ `func f(s S) { print(s, s) }; type S struct { x int }` ,
458
+ `func _() { f(S{x: 1}) }` ,
459
+ `func _() {
459
460
var s S = S{x: 1}
460
461
print(s, s)
461
462
}` ,
462
- },
463
+ },
464
+ })
465
+ })
466
+
467
+ t .Run ("conversions" , func (t * testing.T ) {
468
+ runTests (t , []testcase {
469
+ {
470
+ "Conversions to integer are duplicable." ,
471
+ `func f(i int) { print(i, i) }` ,
472
+ `func _() { var i int8 = 1; f(int(i)) }` ,
473
+ `func _() { var i int8 = 1; print(int(i), int(i)) }` ,
474
+ },
475
+ {
476
+ "Implicit conversions from underlying types are duplicable." ,
477
+ `func f(i I) { print(i, i) }; type I int` ,
478
+ `func _() { f(1) }` ,
479
+ `func _() { print(I(1), I(1)) }` ,
480
+ },
481
+ {
482
+ "Conversions to array are duplicable." ,
483
+ `func f(a [2]int) { print(a, a) }; type A [2]int` ,
484
+ `func _() { var a A; f([2]int(a)) }` ,
485
+ `func _() { var a A; print([2]int(a), [2]int(a)) }` ,
486
+ },
487
+ {
488
+ "Conversions from array are duplicable." ,
489
+ `func f(a A) { print(a, a) }; type A [2]int` ,
490
+ `func _() { var a [2]int; f(A(a)) }` ,
491
+ `func _() { var a [2]int; print(A(a), A(a)) }` ,
492
+ },
493
+ {
494
+ "Conversions from byte slice to string are duplicable." ,
495
+ `func f(s string) { print(s, s) }` ,
496
+ `func _() { var b []byte; f(string(b)) }` ,
497
+ `func _() { var b []byte; print(string(b), string(b)) }` ,
498
+ },
499
+ {
500
+ "Conversions from string to byte slice are not duplicable." ,
501
+ `func f(b []byte) { print(b, b) }` ,
502
+ `func _() { var s string; f([]byte(s)) }` ,
503
+ `func _() {
504
+ var s string
505
+ var b []byte = []byte(s)
506
+ print(b, b)
507
+ }` ,
508
+ },
509
+ {
510
+ "Conversions from string to uint8 slice are not duplicable." ,
511
+ `func f(b []uint8) { print(b, b) }` ,
512
+ `func _() { var s string; f([]uint8(s)) }` ,
513
+ `func _() {
514
+ var s string
515
+ var b []uint8 = []uint8(s)
516
+ print(b, b)
517
+ }` ,
518
+ },
519
+ {
520
+ "Conversions from string to rune slice are not duplicable." ,
521
+ `func f(r []rune) { print(r, r) }` ,
522
+ `func _() { var s string; f([]rune(s)) }` ,
523
+ `func _() {
524
+ var s string
525
+ var r []rune = []rune(s)
526
+ print(r, r)
527
+ }` ,
528
+ },
529
+ {
530
+ "Conversions from string to named type with underlying byte slice are not duplicable." ,
531
+ `func f(b B) { print(b, b) }; type B []byte` ,
532
+ `func _() { var s string; f(B(s)) }` ,
533
+ `func _() {
534
+ var s string
535
+ var b B = B(s)
536
+ print(b, b)
537
+ }` ,
538
+ },
539
+ {
540
+ "Conversions from string to named type of string are duplicable." ,
541
+ `func f(s S) { print(s, s) }; type S string` ,
542
+ `func _() { var s string; f(S(s)) }` ,
543
+ `func _() { var s string; print(S(s), S(s)) }` ,
544
+ },
545
+ {
546
+ "Built-in function calls are not duplicable." ,
547
+ `func f(i int) { print(i, i) }` ,
548
+ `func _() { f(len("")) }` ,
549
+ `func _() {
550
+ var i int = len("")
551
+ print(i, i)
552
+ }` ,
553
+ },
554
+ {
555
+ "Built-in function calls are not duplicable." ,
556
+ `func f(c complex128) { print(c, c) }` ,
557
+ `func _() { f(complex(1.0, 2.0)) }` ,
558
+ `func _() {
559
+ var c complex128 = complex(1.0, 2.0)
560
+ print(c, c)
561
+ }` ,
562
+ },
563
+ {
564
+ "Non built-in function calls are not duplicable." ,
565
+ `func f(i int) { print(i, i) }
566
+ //go:noinline
567
+ func f1(i int) int { return i + 1 }` ,
568
+ `func _() { f(f1(1)) }` ,
569
+ `func _() {
570
+ var i int = f1(1)
571
+ print(i, i)
572
+ }` ,
573
+ },
574
+ {
575
+ "Conversions between function types are duplicable." ,
576
+ `func f(f F) { print(f, f) }; type F func(); func f1() {}` ,
577
+ `func _() { f(F(f1)) }` ,
578
+ `func _() { print(F(f1), F(f1)) }` ,
579
+ },
580
+ })
581
+
463
582
})
464
583
}
465
584
@@ -1358,6 +1477,23 @@ func TestSubstitutionPreservesParameterType(t *testing.T) {
1358
1477
})
1359
1478
}
1360
1479
1480
+ func TestRedundantConversions (t * testing.T ) {
1481
+ runTests (t , []testcase {
1482
+ {
1483
+ "Type conversion must be added if the constant is untyped." ,
1484
+ `func f(i int32) { print(i) }` ,
1485
+ `func _() { f(1) }` ,
1486
+ `func _() { print(int32(1)) }` ,
1487
+ },
1488
+ {
1489
+ "Type conversion must not be added if the constant is typed." ,
1490
+ `func f(i int32) { print(i) }` ,
1491
+ `func _() { f(int32(1)) }` ,
1492
+ `func _() { print(int32(1)) }` ,
1493
+ },
1494
+ })
1495
+ }
1496
+
1361
1497
func runTests (t * testing.T , tests []testcase ) {
1362
1498
for _ , test := range tests {
1363
1499
test := test
0 commit comments