dtolnay / async-trait

Type erasure for async trait methods
Apache License 2.0
1.81k stars 84 forks source link

Spans for elided lifetimes for references are suboptimal. #229

Closed steffahn closed 1 year ago

steffahn commented 1 year ago

Given how hints like ----- lifetime `'life0` defined here below point to the async keyword, whereas the usage of '_ makes the span of the lifetime argument point to the '_ syntax itself, I believe it could be an improvement in UX if the span of lifetime arguments generated for & and &mut implicit (i.e. without “'_”) elided lifetimes could point to the & or the &mut instead.

#[async_trait::async_trait]
trait Foo {
    async fn bar(&self, x: &str, y: &'_ str) -> &'static str;
}
struct S(String);
#[async_trait::async_trait]
impl Foo for S {
    async fn bar(&self, x: &str, y: &'_ str) -> &'static str {
        if false {
            &self.0
        } else if false {
            x
        } else {
            y
        }
    }
}
   Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
 --> src/lib.rs:8:49
  |
8 |     async fn bar(&self, x: &str, y: &'_ str) -> &'static str {
  |     ----- lifetime `'life0` defined here        ^^^^^^^^^^^^ type annotation requires that `'life0` must outlive `'static`

error: lifetime may not live long enough
 --> src/lib.rs:8:49
  |
8 |     async fn bar(&self, x: &str, y: &'_ str) -> &'static str {
  |     ----- lifetime `'life1` defined here        ^^^^^^^^^^^^ type annotation requires that `'life1` must outlive `'static`

error: lifetime may not live long enough
 --> src/lib.rs:8:49
  |
8 |     async fn bar(&self, x: &str, y: &'_ str) -> &'static str {
  |                                      --         ^^^^^^^^^^^^ type annotation requires that `'life2` must outlive `'static`
  |                                      |
  |                                      lifetime `'life2` defined here

help: the following changes may resolve your lifetime errors
  |
  = help: replace `'life0` with `'static`
  = help: replace `'life1` with `'static`
  = help: replace `'life2` with `'static`

error: could not compile `playground` due to 3 previous errors

the improvement should make it look more like:

   Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
 --> src/lib.rs:8:49
  |
8 |     async fn bar(&self, x: &str, y: &'_ str) -> &'static str {
  |                  -                              ^^^^^^^^^^^^ type annotation requires that `'life2` must outlive `'static`
  |                  |
  |                  lifetime `'life0` defined here

error: lifetime may not live long enough
 --> src/lib.rs:8:49
  |
8 |     async fn bar(&self, x: &str, y: &'_ str) -> &'static str {
  |                            -                    ^^^^^^^^^^^^ type annotation requires that `'life2` must outlive `'static`
  |                            |
  |                            lifetime `'life1` defined here

error: lifetime may not live long enough
 --> src/lib.rs:8:49
  |
8 |     async fn bar(&self, x: &str, y: &'_ str) -> &'static str {
  |                                      --         ^^^^^^^^^^^^ type annotation requires that `'life2` must outlive `'static`
  |                                      |
  |                                      lifetime `'life2` defined here

help: the following changes may resolve your lifetime errors
  |
  = help: replace `'life0` with `'static`
  = help: replace `'life1` with `'static`
  = help: replace `'life2` with `'static`

error: could not compile `playground` due to 3 previous errors
dtolnay commented 1 year ago

Good idea; thank you.

Fixed in async-trait 0.1.62.

steffahn commented 1 year ago

This was done so quickly, thank you!