Commit 544cf759 authored by Rob Pike's avatar Rob Pike

gob: use pointers in bootstrapType so interfaces behave properly

and don't lead to a nil reflect.Type.
Fixes #1626.

R=rsc
CC=golang-dev
https://golang.org/cl/4289062
parent 6684d550
...@@ -222,22 +222,45 @@ func (t *CommonType) name() string { return t.Name } ...@@ -222,22 +222,45 @@ func (t *CommonType) name() string { return t.Name }
var ( var (
// Primordial types, needed during initialization. // Primordial types, needed during initialization.
tBool = bootstrapType("bool", false, 1) // Always passed as pointers so the interface{} type
tInt = bootstrapType("int", int(0), 2) // goes through without losing its interfaceness.
tUint = bootstrapType("uint", uint(0), 3) tBool = bootstrapType("bool", (*bool)(nil), 1)
tFloat = bootstrapType("float", float64(0), 4) tInt = bootstrapType("int", (*int)(nil), 2)
tBytes = bootstrapType("bytes", make([]byte, 0), 5) tUint = bootstrapType("uint", (*uint)(nil), 3)
tString = bootstrapType("string", "", 6) tFloat = bootstrapType("float", (*float64)(nil), 4)
tComplex = bootstrapType("complex", 0+0i, 7) tBytes = bootstrapType("bytes", (*[]byte)(nil), 5)
tInterface = bootstrapType("interface", interface{}(nil), 8) tString = bootstrapType("string", (*string)(nil), 6)
tComplex = bootstrapType("complex", (*complex128)(nil), 7)
tInterface = bootstrapType("interface", (*interface{})(nil), 8)
// Reserve some Ids for compatible expansion // Reserve some Ids for compatible expansion
tReserved7 = bootstrapType("_reserved1", struct{ r7 int }{}, 9) tReserved7 = bootstrapType("_reserved1", (*struct {
tReserved6 = bootstrapType("_reserved1", struct{ r6 int }{}, 10) r7 int
tReserved5 = bootstrapType("_reserved1", struct{ r5 int }{}, 11) })(nil),
tReserved4 = bootstrapType("_reserved1", struct{ r4 int }{}, 12) 9)
tReserved3 = bootstrapType("_reserved1", struct{ r3 int }{}, 13) tReserved6 = bootstrapType("_reserved1", (*struct {
tReserved2 = bootstrapType("_reserved1", struct{ r2 int }{}, 14) r6 int
tReserved1 = bootstrapType("_reserved1", struct{ r1 int }{}, 15) })(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 // Predefined because it's needed by the Decoder
...@@ -564,9 +587,10 @@ func checkId(want, got typeId) { ...@@ -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 { func bootstrapType(name string, e interface{}, expect typeId) typeId {
rt := reflect.Typeof(e) rt := reflect.Typeof(e).(*reflect.PtrType).Elem()
_, present := types[rt] _, present := types[rt]
if present { if present {
panic("bootstrap type already present: " + name + ", " + rt.String()) panic("bootstrap type already present: " + name + ", " + rt.String())
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment