1
0
mirror of https://github.com/golang/go synced 2024-11-24 07:40:17 -07:00

gob: Register should use the original type, not the indirected one.

Fixes a bug reported on golang-nuts.

R=rsc, adg
CC=golang-dev
https://golang.org/cl/3641042
This commit is contained in:
Rob Pike 2010-12-14 15:04:52 -08:00
parent 56452c53ee
commit 8132bb1c74
2 changed files with 32 additions and 1 deletions

View File

@ -354,3 +354,32 @@ func TestStructNonStruct(t *testing.T) {
t.Error("for non-struct/struct expected type error; got", err)
}
}
type interfaceIndirectTestI interface {
F() bool
}
type interfaceIndirectTestT struct{}
func (this *interfaceIndirectTestT) F() bool {
return true
}
// A version of a bug reported on golang-nuts. Also tests top-level
// slice of interfaces. The issue was registering *T caused T to be
// stored as the concrete type.
func TestInterfaceIndirect(t *testing.T) {
Register(&interfaceIndirectTestT{})
b := new(bytes.Buffer)
w := []interfaceIndirectTestI{&interfaceIndirectTestT{}}
err := NewEncoder(b).Encode(w)
if err != nil {
t.Fatal("encode error:", err)
}
var r []interfaceIndirectTestI
err = NewDecoder(b).Decode(&r)
if err != nil {
t.Fatal("decode error:", err)
}
}

View File

@ -470,7 +470,9 @@ func RegisterName(name string, value interface{}) {
if n, ok := concreteTypeToName[rt]; ok && n != name {
panic("gob: registering duplicate names for " + rt.String())
}
nameToConcreteType[name] = rt
// Store the name and type provided by the user....
nameToConcreteType[name] = reflect.Typeof(value)
// but the flattened type in the type table, since that's what decode needs.
concreteTypeToName[rt] = name
}