diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index de528e85368cb..88ec884b79c30 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -549,6 +549,7 @@ where
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(notable_trait)]
 #[cfg_attr(not(test), rustc_diagnostic_item = "IoRead")]
+#[rustc_must_implement_one_of(read, read_buf)]
 pub trait Read {
     /// Pull some bytes from this source into the specified buffer, returning
     /// how many bytes were read.
@@ -630,7 +631,10 @@ pub trait Read {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
+    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
+        let mut buf = BorrowedBuf::from(buf);
+        self.read_buf(buf.unfilled()).map(|()| buf.len())
+    }
 
     /// Like `read`, except that it reads into a slice of buffers.
     ///