Reputation: 35
I'm trying to shorten a function signature by introducing a type alias. The type specification of the parameter looks like this
writer: Arc<Mutex<&mut (dyn AsyncWrite + Unpin + Send + Sync)>> // working
which I thought could be shortened by introducing this type alias
pub type RefAsyncWriter<'a> = &'a mut (dyn AsyncWrite + Unpin + Send + Sync);
so the type parameter becomes just
writer: Arc<Mutex<RefAsyncWriter>> // error[E0726]: implicit elided lifetime not allowed here
Unfortunately this change gets me into trouble with lifetimes.
Here I made a brief example
use tokio::io::AsyncWrite;
use tokio::fs::File;
use std::sync::{Arc,Mutex};
use std::path::PathBuf;
pub type RefAsyncWriter<'a> = &'a mut (dyn AsyncWrite + Unpin + Send + Sync);
#[tokio::main]
async fn main() {
let f = File::create(PathBuf::from("/tmp/test.txt")).await.unwrap();
w(Arc::new(Mutex::new(&mut f)));
}
async fn w(writer: Arc<Mutex<RefAsyncWriter>>) {
// TODO
}
The result is the following
Compiling playground v0.0.1 (/playground)
error[E0726]: implicit elided lifetime not allowed here
--> src/main.rs:13:31
|
13 | async fn w (writer: Arc<Mutex<RefAsyncWriter>>) {}
| ^^^^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
error: aborting due to previous error
If somebody could explain to me (1) if there is a way to get this working and maybe (2) why the type alias actually makes such a difference to the compiler that would be of great help.
Thanks a lot in advance.
Upvotes: 1
Views: 445
Reputation: 16925
Since you introduce an explicit lifetime 'a
in the type alias, you need to specify it when you use this type.
async fn w<'a>(writer: Arc<Mutex<RefAsyncWriter<'a>>>) {}
It seems to work in the playground you provided.
And as the compiler suggests, the anonymous litetime is equivalent.
async fn w(writer: Arc<Mutex<RefAsyncWriter<'_>>>) {}
The original version of your function (with the very long type written down after writer:
is somewhat equivalent to print1()
, print2()
and print3()
in this documentation.
If you introduce a reference as parameter, then a lifetime parameter necessarily exists for this function; the elision brings just some comfort to save some keystrokes when no confusion is possible about this lifetime.
When defining a type alias containing a reference, the compiler wants us to make the lifetime explicit, probably to prevent someone using this type alias from forgetting that there is a reference hidden inside.
Then, using this type alias requires the <'...>
notation.
But again, when no confusion is possible at usage, the anonymous lifetime <'_>
saves some keystrokes, avoiding writing <'a>
twice (after the function name, and in the parameter).
Upvotes: 3