bufio: in Reader.WriteTo, try to use target's ReaderFrom

This is the simple half of https://golang.org/cl/53560043/ with
a new benchmark. pongad is in the C+A files already.

benchmark                         old ns/op     new ns/op     delta
BenchmarkReaderWriteToOptimal     2054          825           -59.83%

Update #6373

LGTM=iant, gri
R=golang-codereviews, iant, gri
CC=golang-codereviews
https://golang.org/cl/69220046
diff --git a/src/pkg/bufio/bufio_test.go b/src/pkg/bufio/bufio_test.go
index 3c86857..e48f5f8 100644
--- a/src/pkg/bufio/bufio_test.go
+++ b/src/pkg/bufio/bufio_test.go
@@ -1094,20 +1094,12 @@
 
 // An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
 type onlyReader struct {
-	r io.Reader
-}
-
-func (r onlyReader) Read(b []byte) (int, error) {
-	return r.r.Read(b)
+	io.Reader
 }
 
 // An onlyWriter only implements io.Writer, no matter what other methods the underlying implementation may have.
 type onlyWriter struct {
-	w io.Writer
-}
-
-func (w onlyWriter) Write(b []byte) (int, error) {
-	return w.w.Write(b)
+	io.Writer
 }
 
 func BenchmarkReaderCopyOptimal(b *testing.B) {
@@ -1152,6 +1144,27 @@
 	}
 }
 
+func BenchmarkReaderWriteToOptimal(b *testing.B) {
+	const bufSize = 16 << 10
+	buf := make([]byte, bufSize)
+	r := bytes.NewReader(buf)
+	srcReader := NewReaderSize(onlyReader{r}, 1<<10)
+	if _, ok := ioutil.Discard.(io.ReaderFrom); !ok {
+		b.Fatal("ioutil.Discard doesn't support ReaderFrom")
+	}
+	for i := 0; i < b.N; i++ {
+		r.Seek(0, 0)
+		srcReader.Reset(onlyReader{r})
+		n, err := srcReader.WriteTo(ioutil.Discard)
+		if err != nil {
+			b.Fatal(err)
+		}
+		if n != bufSize {
+			b.Fatalf("n = %d; want %d", n, bufSize)
+		}
+	}
+}
+
 func BenchmarkWriterCopyOptimal(b *testing.B) {
 	// Optimal case is where the underlying writer implements io.ReaderFrom
 	srcBuf := bytes.NewBuffer(make([]byte, 8192))