@@ -11,7 +11,6 @@ import (
11
11
"io"
12
12
"math"
13
13
"reflect"
14
- "runtime"
15
14
"strings"
16
15
"testing"
17
16
"time"
@@ -112,6 +111,19 @@ func (p *P) String() string {
112
111
return "String(p)"
113
112
}
114
113
114
+ // Fn is a function type with a String method.
115
+ type Fn func () int
116
+
117
+ func (fn Fn ) String () string { return "String(fn)" }
118
+
119
+ var fnValue Fn
120
+
121
+ // U is a type with two unexported function fields.
122
+ type U struct {
123
+ u func () string
124
+ fn Fn
125
+ }
126
+
115
127
var barray = [5 ]renamedUint8 {1 , 2 , 3 , 4 , 5 }
116
128
var bslice = barray [:]
117
129
@@ -714,7 +726,6 @@ var fmtTests = []struct {
714
726
// go syntax
715
727
{"%#v" , A {1 , 2 , "a" , []int {1 , 2 }}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}` },
716
728
{"%#v" , new (byte ), "(*uint8)(0xPTR)" },
717
- {"%#v" , TestFmtInterface , "(func(*testing.T))(0xPTR)" },
718
729
{"%#v" , make (chan int ), "(chan int)(0xPTR)" },
719
730
{"%#v" , uint64 (1 << 64 - 1 ), "0xffffffffffffffff" },
720
731
{"%#v" , 1000000000 , "1000000000" },
@@ -737,6 +748,54 @@ var fmtTests = []struct {
737
748
{"%#v" , 1.2345678 , "1.2345678" },
738
749
{"%#v" , float32 (1.2345678 ), "1.2345678" },
739
750
751
+ // functions
752
+ {"%v" , TestFmtInterface , "0xPTR" }, // simple function
753
+ {"%v" , reflect .ValueOf (TestFmtInterface ), "0xPTR" },
754
+ {"%v" , G .GoString , "0xPTR" }, // method expression
755
+ {"%v" , reflect .ValueOf (G .GoString ), "0xPTR" },
756
+ {"%v" , G (23 ).GoString , "0xPTR" }, // method value
757
+ {"%v" , reflect .ValueOf (G (23 ).GoString ), "0xPTR" },
758
+ {"%v" , reflect .ValueOf (G (23 )).Method (0 ), "0xPTR" },
759
+ {"%v" , Fn .String , "0xPTR" }, // method of function type
760
+ {"%v" , reflect .ValueOf (Fn .String ), "0xPTR" },
761
+ {"%v" , fnValue , "String(fn)" }, // variable of function type with String method
762
+ {"%v" , reflect .ValueOf (fnValue ), "String(fn)" },
763
+ {"%v" , [1 ]Fn {fnValue }, "[String(fn)]" }, // array of function type with String method
764
+ {"%v" , reflect .ValueOf ([1 ]Fn {fnValue }), "[String(fn)]" },
765
+ {"%v" , fnValue .String , "0xPTR" }, // method value from function type
766
+ {"%v" , reflect .ValueOf (fnValue .String ), "0xPTR" },
767
+ {"%v" , reflect .ValueOf (fnValue ).Method (0 ), "0xPTR" },
768
+ {"%v" , U {}.u , "<nil>" }, // unexported function field
769
+ {"%v" , reflect .ValueOf (U {}.u ), "<nil>" },
770
+ {"%v" , reflect .ValueOf (U {}).Field (0 ), "<nil>" },
771
+ {"%v" , U {fn : fnValue }.fn , "String(fn)" }, // unexported field of function type with String method
772
+ {"%v" , reflect .ValueOf (U {fn : fnValue }.fn ), "String(fn)" },
773
+ {"%v" , reflect .ValueOf (U {fn : fnValue }).Field (1 ), "<nil>" },
774
+
775
+ // functions with go syntax
776
+ {"%#v" , TestFmtInterface , "(func(*testing.T))(0xPTR)" }, // simple function
777
+ {"%#v" , reflect .ValueOf (TestFmtInterface ), "(func(*testing.T))(0xPTR)" },
778
+ {"%#v" , G .GoString , "(func(fmt_test.G) string)(0xPTR)" }, // method expression
779
+ {"%#v" , reflect .ValueOf (G .GoString ), "(func(fmt_test.G) string)(0xPTR)" },
780
+ {"%#v" , G (23 ).GoString , "(func() string)(0xPTR)" }, // method value
781
+ {"%#v" , reflect .ValueOf (G (23 ).GoString ), "(func() string)(0xPTR)" },
782
+ {"%#v" , reflect .ValueOf (G (23 )).Method (0 ), "(func() string)(0xPTR)" },
783
+ {"%#v" , Fn .String , "(func(fmt_test.Fn) string)(0xPTR)" }, // method of function type
784
+ {"%#v" , reflect .ValueOf (Fn .String ), "(func(fmt_test.Fn) string)(0xPTR)" },
785
+ {"%#v" , fnValue , "(fmt_test.Fn)(nil)" }, // variable of function type with String method
786
+ {"%#v" , reflect .ValueOf (fnValue ), "(fmt_test.Fn)(nil)" },
787
+ {"%#v" , [1 ]Fn {fnValue }, "[1]fmt_test.Fn{(fmt_test.Fn)(nil)}" }, // array of function type with String method
788
+ {"%#v" , reflect .ValueOf ([1 ]Fn {fnValue }), "[1]fmt_test.Fn{(fmt_test.Fn)(nil)}" },
789
+ {"%#v" , fnValue .String , "(func() string)(0xPTR)" }, // method value from function type
790
+ {"%#v" , reflect .ValueOf (fnValue .String ), "(func() string)(0xPTR)" },
791
+ {"%#v" , reflect .ValueOf (fnValue ).Method (0 ), "(func() string)(0xPTR)" },
792
+ {"%#v" , U {}.u , "(func() string)(nil)" }, // unexported function field
793
+ {"%#v" , reflect .ValueOf (U {}.u ), "(func() string)(nil)" },
794
+ {"%#v" , reflect .ValueOf (U {}).Field (0 ), "(func() string)(nil)" },
795
+ {"%#v" , U {fn : fnValue }.fn , "(fmt_test.Fn)(nil)" }, // unexported field of function type with String method
796
+ {"%#v" , reflect .ValueOf (U {fn : fnValue }.fn ), "(fmt_test.Fn)(nil)" },
797
+ {"%#v" , reflect .ValueOf (U {fn : fnValue }).Field (1 ), "(fmt_test.Fn)(nil)" },
798
+
740
799
// Whole number floats are printed without decimals. See Issue 27634.
741
800
{"%#v" , 1.0 , "1" },
742
801
{"%#v" , 1000000.0 , "1e+06" },
@@ -1438,6 +1497,9 @@ var mallocTest = []struct {
1438
1497
{0 , `Fprintf(buf, "%s")` , func () { mallocBuf .Reset (); Fprintf (& mallocBuf , "%s" , "hello" ) }},
1439
1498
{0 , `Fprintf(buf, "%x")` , func () { mallocBuf .Reset (); Fprintf (& mallocBuf , "%x" , 7 ) }},
1440
1499
{0 , `Fprintf(buf, "%x")` , func () { mallocBuf .Reset (); Fprintf (& mallocBuf , "%x" , 1 << 16 ) }},
1500
+ {1 , `Fprintf(buf, "%x")` , func () { mallocBuf .Reset (); i := 1 << 16 ; Fprintf (& mallocBuf , "%x" , i ) }}, // not constant
1501
+ {4 , `Fprintf(buf, "%v")` , func () { mallocBuf .Reset (); s := []int {1 , 2 }; Fprintf (& mallocBuf , "%v" , s ) }},
1502
+ {1 , `Fprintf(buf, "%v")` , func () { mallocBuf .Reset (); type P struct { x , y int }; Fprintf (& mallocBuf , "%v" , P {1 , 2 }) }},
1441
1503
{2 , `Fprintf(buf, "%80000s")` , func () { mallocBuf .Reset (); Fprintf (& mallocBuf , "%80000s" , "hello" ) }}, // large buffer (>64KB)
1442
1504
// If the interface value doesn't need to allocate, amortized allocation overhead should be zero.
1443
1505
{0 , `Fprintf(buf, "%x %x %x")` , func () {
@@ -1452,8 +1514,6 @@ func TestCountMallocs(t *testing.T) {
1452
1514
switch {
1453
1515
case testing .Short ():
1454
1516
t .Skip ("skipping malloc count in short mode" )
1455
- case runtime .GOMAXPROCS (0 ) > 1 :
1456
- t .Skip ("skipping; GOMAXPROCS>1" )
1457
1517
case race .Enabled :
1458
1518
t .Skip ("skipping malloc count under race detector" )
1459
1519
}
0 commit comments