@@ -414,52 +414,171 @@ func TestBasics(t *testing.T) {
414414}
415415
416416func 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 _() {
429430 var s string = "hi"
430431 print(s, s)
431432}` ,
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 _() {
444445 var a [2]int = [2]int{1, 2}
445446 print(a, a)
446447}` ,
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 _() {
459460 var s S = S{x: 1}
460461 print(s, s)
461462}` ,
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+
463582 })
464583}
465584
@@ -1358,6 +1477,23 @@ func TestSubstitutionPreservesParameterType(t *testing.T) {
13581477 })
13591478}
13601479
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+
13611497func runTests (t * testing.T , tests []testcase ) {
13621498 for _ , test := range tests {
13631499 test := test
0 commit comments