]> Cypherpunks repositories - gostls13.git/commitdiff
gob: use pointers in bootstrapType so interfaces behave properly
authorRob Pike <r@golang.org>
Tue, 22 Mar 2011 18:43:00 +0000 (11:43 -0700)
committerRob Pike <r@golang.org>
Tue, 22 Mar 2011 18:43:00 +0000 (11:43 -0700)
and don't lead to a nil reflect.Type.
Fixes #1626.

R=rsc
CC=golang-dev
https://golang.org/cl/4289062

src/pkg/gob/type.go

index 0001f0c2e20840621ef88b0d167b229b46c06416..9c62107b84a4db872064cf3e72e7f33c78063423 100644 (file)
@@ -222,22 +222,45 @@ func (t *CommonType) name() string { return t.Name }
 
 var (
        // Primordial types, needed during initialization.
-       tBool      = bootstrapType("bool", false, 1)
-       tInt       = bootstrapType("int", int(0), 2)
-       tUint      = bootstrapType("uint", uint(0), 3)
-       tFloat     = bootstrapType("float", float64(0), 4)
-       tBytes     = bootstrapType("bytes", make([]byte, 0), 5)
-       tString    = bootstrapType("string", "", 6)
-       tComplex   = bootstrapType("complex", 0+0i, 7)
-       tInterface = bootstrapType("interface", interface{}(nil), 8)
+       // Always passed as pointers so the interface{} type
+       // goes through without losing its interfaceness.
+       tBool      = bootstrapType("bool", (*bool)(nil), 1)
+       tInt       = bootstrapType("int", (*int)(nil), 2)
+       tUint      = bootstrapType("uint", (*uint)(nil), 3)
+       tFloat     = bootstrapType("float", (*float64)(nil), 4)
+       tBytes     = bootstrapType("bytes", (*[]byte)(nil), 5)
+       tString    = bootstrapType("string", (*string)(nil), 6)
+       tComplex   = bootstrapType("complex", (*complex128)(nil), 7)
+       tInterface = bootstrapType("interface", (*interface{})(nil), 8)
        // Reserve some Ids for compatible expansion
-       tReserved7 = bootstrapType("_reserved1", struct{ r7 int }{}, 9)
-       tReserved6 = bootstrapType("_reserved1", struct{ r6 int }{}, 10)
-       tReserved5 = bootstrapType("_reserved1", struct{ r5 int }{}, 11)
-       tReserved4 = bootstrapType("_reserved1", struct{ r4 int }{}, 12)
-       tReserved3 = bootstrapType("_reserved1", struct{ r3 int }{}, 13)
-       tReserved2 = bootstrapType("_reserved1", struct{ r2 int }{}, 14)
-       tReserved1 = bootstrapType("_reserved1", struct{ r1 int }{}, 15)
+       tReserved7 = bootstrapType("_reserved1", (*struct {
+               r7 int
+       })(nil),
+               9)
+       tReserved6 = bootstrapType("_reserved1", (*struct {
+               r6 int
+       })(nil),
+               10)
+       tReserved5 = bootstrapType("_reserved1", (*struct {
+               r5 int
+       })(nil),
+               11)
+       tReserved4 = bootstrapType("_reserved1", (*struct {
+               r4 int
+       })(nil),
+               12)
+       tReserved3 = bootstrapType("_reserved1", (*struct {
+               r3 int
+       })(nil),
+               13)
+       tReserved2 = bootstrapType("_reserved1", (*struct {
+               r2 int
+       })(nil),
+               14)
+       tReserved1 = bootstrapType("_reserved1", (*struct {
+               r1 int
+       })(nil),
+               15)
 )
 
 // Predefined because it's needed by the Decoder
@@ -564,9 +587,10 @@ func checkId(want, got typeId) {
        }
 }
 
-// used for building the basic types; called only from init()
+// used for building the basic types; called only from init().  the incoming
+// interface always refers to a pointer.
 func bootstrapType(name string, e interface{}, expect typeId) typeId {
-       rt := reflect.Typeof(e)
+       rt := reflect.Typeof(e).(*reflect.PtrType).Elem()
        _, present := types[rt]
        if present {
                panic("bootstrap type already present: " + name + ", " + rt.String())