[release-branch.go1.2] encoding/gob: do not use MarshalText, UnmarshalText

««« CL 22770044 / 23fc3139589c
encoding/gob: do not use MarshalText, UnmarshalText

This seems to be the best of a long list of bad ways to fix this issue.

Fixes #6760.

R=r
CC=golang-dev
https://golang.org/cl/22770044
»»»

R=golang-dev
CC=golang-dev
https://golang.org/cl/28110043
diff --git a/doc/go1.2.html b/doc/go1.2.html
index 9d890b2..c7a9f84 100644
--- a/doc/go1.2.html
+++ b/doc/go1.2.html
@@ -736,7 +736,8 @@
 even if they are not. That is, it ignores them completely. Previously they would
 trigger an error, which could cause unexpected compatibility problems if an
 embedded structure added such a field.
-The package also now supports the generic encoding interfaces of the
+The package also now supports the generic <code>BinaryMarshaler</code> and
+<code>BinaryUnmarshaler</code> interfaces of the
 <a href="/pkg/encoding/"><code>encoding</code></a> package
 described above.
 </li>
diff --git a/src/pkg/encoding/gob/doc.go b/src/pkg/encoding/gob/doc.go
index 28f0c05..d0acaba 100644
--- a/src/pkg/encoding/gob/doc.go
+++ b/src/pkg/encoding/gob/doc.go
@@ -86,13 +86,13 @@
 at top the level will fail. A struct field of chan or func type is treated exactly
 like an unexported field and is ignored.
 
-Gob can encode a value of any type implementing the GobEncoder,
-encoding.BinaryMarshaler, or encoding.TextMarshaler interfaces by calling the
-corresponding method, in that order of preference.
+Gob can encode a value of any type implementing the GobEncoder or
+encoding.BinaryMarshaler interfaces by calling the corresponding method,
+in that order of preference.
 
-Gob can decode a value of any type implementing the GobDecoder,
-encoding.BinaryUnmarshaler, or encoding.TextUnmarshaler interfaces by calling
-the corresponding method, again in that order of preference.
+Gob can decode a value of any type implementing the GobDecoder or
+encoding.BinaryUnmarshaler interfaces by calling the corresponding method,
+again in that order of preference.
 
 Encoding Details
 
diff --git a/src/pkg/encoding/gob/gobencdec_test.go b/src/pkg/encoding/gob/gobencdec_test.go
index 301551d..0193e2b 100644
--- a/src/pkg/encoding/gob/gobencdec_test.go
+++ b/src/pkg/encoding/gob/gobencdec_test.go
@@ -11,6 +11,7 @@
 	"errors"
 	"fmt"
 	"io"
+	"net"
 	"strings"
 	"testing"
 	"time"
@@ -767,3 +768,17 @@
 		t.Fatalf("expected nil, got %v", err2)
 	}
 }
+
+func TestNetIP(t *testing.T) {
+	// Encoding of net.IP{1,2,3,4} in Go 1.1.
+	enc := []byte{0x07, 0x0a, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04}
+
+	var ip net.IP
+	err := NewDecoder(bytes.NewReader(enc)).Decode(&ip)
+	if err != nil {
+		t.Fatalf("decode: %v", err)
+	}
+	if ip.String() != "1.2.3.4" {
+		t.Errorf("decoded to %v, want 1.2.3.4", ip.String())
+	}
+}
diff --git a/src/pkg/encoding/gob/type.go b/src/pkg/encoding/gob/type.go
index 65bf17b..cad1452 100644
--- a/src/pkg/encoding/gob/type.go
+++ b/src/pkg/encoding/gob/type.go
@@ -88,18 +88,25 @@
 		ut.externalEnc, ut.encIndir = xGob, indir
 	} else if ok, indir := implementsInterface(ut.user, binaryMarshalerInterfaceType); ok {
 		ut.externalEnc, ut.encIndir = xBinary, indir
-	} else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok {
-		ut.externalEnc, ut.encIndir = xText, indir
 	}
 
+	// NOTE(rsc): Would like to allow MarshalText here, but results in incompatibility
+	// with older encodings for net.IP. See golang.org/issue/6760.
+	// } else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok {
+	// 	ut.externalEnc, ut.encIndir = xText, indir
+	// }
+
 	if ok, indir := implementsInterface(ut.user, gobDecoderInterfaceType); ok {
 		ut.externalDec, ut.decIndir = xGob, indir
 	} else if ok, indir := implementsInterface(ut.user, binaryUnmarshalerInterfaceType); ok {
 		ut.externalDec, ut.decIndir = xBinary, indir
-	} else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok {
-		ut.externalDec, ut.decIndir = xText, indir
 	}
 
+	// See note above.
+	// } else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok {
+	// 	ut.externalDec, ut.decIndir = xText, indir
+	// }
+
 	userTypeCache[rt] = ut
 	return
 }