Hello,
I stumbled on a curious case that I don't understand. I would appreciate it if you explain what is going on. .
I have the following code. The method called this_method_doesnt_build doesn't build. However, if I extract literally two lines of it into a separate function, it builds fine (like I did in this_method_builds)
The culprit is somewhere around the tokio::io::split of a reference.
use tokio::net::TcpStream;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::io::{ReadHalf, WriteHalf};
trait AsyncReadWrite : AsyncRead + AsyncWrite + Unpin {
}
impl AsyncReadWrite for TcpStream {
}
async fn stream_data(_stream_rx: ReadHalf<&mut dyn AsyncReadWrite>, _stream_tx: WriteHalf<&mut dyn AsyncReadWrite>) {
}
// This method will fail to build (uncomment to experiment)
async fn this_mthod_doesnt_build(mut stream: Box<dyn AsyncReadWrite>) {
// The compiler will complain here that "^^^^^^^^^^^^^^^ borrowed value does not live long enough"
// I believe somehow getting it through tokio::io::split() which underneath does Arc
// and await causes the problem
// However extracting two calls below (like in this_method_builds) will make it build
let stream_ref = stream.as_mut();
let (stream_rx, stream_tx) = tokio::io::split(stream_ref);
stream_data(stream_rx, stream_tx).await;
}
// These two method will build while being just extraction two lines into a separate method
async fn stream_data_wrapper(stream_ref: &mut dyn AsyncReadWrite) {
let (stream_rx, stream_tx) = tokio::io::split(stream_ref);
stream_data(stream_rx, stream_tx).await;
}
async fn this_method_builds(mut stream: Box<dyn AsyncReadWrite>) {
let stream_ref = stream.as_mut();
stream_data_wrapper(stream_ref).await;
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let stream : Box<dyn AsyncReadWrite> = Box::new(TcpStream::connect("www.google.com:443").await?);
this_method_builds(stream).await;
this_mthod_doesnt_build(stream).await;
Ok(())
}
Regards,
Victor