io::{Read, Write} are implemented for &TcpStream. The same is true for fs::File. The reason why such an impl can exist is that these types are merely handles to some OS-level data structure (basically, no more than an int index into some file descriptor table), and they don't themselves need to be modified in order to be written to or read from.
If you're familiar with interior mutability, aka shared mutability, you can think of OS data types like TcpStream as types that use shared mutability to change their state, even when you only have a shared reference to them.[1]
Whatever changes are necessary happen in the OS, not Rust code, but I find this a handy mental model. âŠī¸