I just want to use tokio::net::TcpStream.split
method in a struct and keep it as its field variable, but I got the error error[E0597]: 'stream' does not live long enough
. I face this kind of problems many times when I am trying to hold a borrowed value to struct's field like Struct std::path::Path
. I know Path
problem will be solved with using PathBuf
, but I'm not sure this time. Could you give me an advise to make it work?
use tokio::net::TcpStream;
use tokio::net::tcp::{ReadHalf, WriteHalf};
struct TT<'a>{
pub reader: Option<ReadHalf<'a>>,
pub writer: Option<WriteHalf<'a>>,
}
impl<'a> TT<'a> {
fn set_reader_and_writer(&mut self, mut stream: TcpStream) {
let (reader, writer) = stream.split();
self.reader = Some(reader);
self.writer = Some(writer);
}
}
$ cargo build [master|…4]
Blocking waiting for file lock on build directory
Compiling tcpst v0.1.0 (/tmp/tcpst)
error[E0597]: `stream` does not live long enough
--> src/main.rs:11:32
|
9 | impl<'a> TT<'a> {
| -- lifetime `'a` defined here
10 | fn set_reader_and_writer(&mut self, mut stream: TcpStream) {
11 | let (reader, writer) = stream.split();
| ^^^^^^ borrowed value does not live long enough
12 | self.reader = Some(reader);
| -------------------------- assignment requires that `stream` is borrowed for `'a`
13 | self.writer = Some(writer);
14 | }
| - `stream` dropped here while still borrowed
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.
error: could not compile `tcpst`.
The problem is that the read and write halves of the stream both borrow references to the stream they were created from. In your code, the original stream is dropped at the end of the function, which would invalidate those references. The easiest solution is to change the signature of set_reader_and_writer
to take a &mut stream
instead of taking ownership.
This is a very understandable mistake to make, as the signature for split
does not make its lifetimes explicit (that stream
must live at least as long as the return values). If you check the source, though, it shows the ReadHalf
and WriteHalf
lifetimes (and why they were permitted to be elided from the function signature).