Many times, I found the need to ask the compiler to unify the lifetime in function signatures.
For example, the signature below
trait User {
fn update_user_name(&self, name: &str) -> Pin<Box<dyn Future<Output=()> + Send + '_>>>;
}
if having the (unnamed) lifetimes unified, it will be like
trait User {
fn update_user_name<'a>(&'a self, name: &'a str) -> Pin<Box<dyn Future<Output=()> + Send + 'a>>>;
}
(Note the above does not declared as async
because, if you want this to be a method of a dyn object
that's what you have to write without async-trait
crate)
The other use case is when using arenas like bumpalo
, you almost certain will end up with a lot of things like &'a MyStruct<'a>
where the 'a
is the lifetime of the arena. And then your method signatures will have more lifetimes to unify.
My proposal is to allow an anotation #[unify_lifetime]
to indicate every implicit lifetime in the signature are the same.
So the above example (the unified one) is written
trait User {
#[unify_lifetime]
fn update_user_name(&self, name: &str) -> Pin<Box<dyn Future<Output=()> + Send + '_>>>;
}
To my (limited of cause) experience, this is already way too common - almost every time when I have to manually introduce lifetime arguments I don't have more than one to add.
This is why I believe this small change can significantly increase ergonomic, and flatten the learning curve for new users.
For the implementation bit, I believe a simple proc-macro can do the job. But if it is in std
, the compiler message can be updated to prompt the user to use this, further lowering the learning curve.