Lifetime error messages should have better spans

e880929
Opened by mdinger at 2023-10-16 20:22:04

This error has an arrow pointing where the lifetime issue is (though I don't know why it isn't more precise):

struct Mine<'a> { s: &'a str }

impl <'a>Iterator<&'a str> for Mine<'a> {
    fn next(&mut self) -> Option<&str> { Some("h") }
}

fn main() {}
<anon>:4:5: 4:53 error: method `next` has an incompatible type for trait: expected concrete lifetime, found bound lifetime parameter  [E0053]
<anon>:4     fn next(&mut self) -> Option<&str> { Some("h") }
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<anon>:4:40: 4:53 note: expected concrete lifetime is the lifetime 'a as defined on the block at 4:39
<anon>:4     fn next(&mut self) -> Option<&str> { Some("h") }
                                                ^~~~~~~~~~~~~
error: aborting due to previous error
playpen: application terminated with error code 101

This won't because next() is multiline:

struct Mine<'a> { s: &'a str }

impl <'a>Iterator<&'a str> for Mine<'a> {
    fn next(&mut self) -> Option<&str> {
        Some("h")
    }
}

fn main() {}
<anon>:4:5: 6:6 error: method `next` has an incompatible type for trait: expected concrete lifetime, found bound lifetime parameter  [E0053]
<anon>:4     fn next(&mut self) -> Option<&str> {
<anon>:5         Some("h")
<anon>:6     }
<anon>:4:40: 6:6 note: expected concrete lifetime is the lifetime 'a as defined on the block at 4:39
<anon>:4     fn next(&mut self) -> Option<&str> {
<anon>:5         Some("h")
<anon>:6     }
error: aborting due to previous error
playpen: application terminated with error code 101

Best would be:

<anon>:4:40: 4:53 note: expected concrete lifetime is the lifetime 'a as defined on the block at 4:39
<anon>:4     fn next(&mut self) -> Option<&str> { Some("h") }
                                           ^~~~~~~~~~~~~

Someone might easily put the lifetime on next(&'a self) instead of Option<&'a str> because it didn't point and they didn't understand the message.

  1. Triage: updated code:

    struct Mine<'a> { s: &'a str }
    
    impl <'a>Iterator for Mine<'a> {
        type Item = &'a str;
        fn next(&mut self) -> Option<&str> { Some("h") }
    }
    
    fn main() {}
    

    same error, same problem.

    Steve Klabnik at 2016-02-02 22:03:27

  2. Current output (updated 2018-02-11):

    error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements
     --> src/main.rs:5:5
      |
    5 |     fn next(&mut self) -> Option<&str> { Some("h") }
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
    note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 5:5...
     --> src/main.rs:5:5
      |
    5 |     fn next(&mut self) -> Option<&str> { Some("h") }
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      = note: ...so that the method type is compatible with trait:
              expected fn(&mut Mine<'a>) -> std::option::Option<&str>
                 found fn(&mut Mine<'a>) -> std::option::Option<&str>
    note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 3:1...
     --> src/main.rs:3:1
      |
    3 | impl <'a>Iterator for Mine<'a> {
      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      = note: ...so that the types are compatible:
              expected std::iter::Iterator
                 found std::iter::Iterator
    

    This case should look more like the following:

    error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements
     --> src/main.rs:5:5
      |
    5 |     fn next(&mut self) -> Option<&str> { Some("h") }
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
    note: the method `next` is defined in the trait as returning `Option<Self::Item>`, which is defined in the impl as `&'a str`...
     --> src/main.rs:4:5
      |
    4 |     type Item = &'a str;
      |     ^^^^^^^^^^^^^^^^^^^^
    note: ...but the implementation of `next` returns `Option<&str>`:
     --> src/main.rs:5:5
      |
    5 |     fn next(&mut self) -> Option<&str> { Some("h") }
      |                           ^^^^^^^^^^^^
    help: change the return type for `next` to match the trait:
     --> src/main.rs:5:5
      |
    5 |     fn next(&mut self) -> Option<&'a str> { Some("h") }
      |                           ^^^^^^^^^^^^^^^
    
    

    Esteban Kuber at 2017-11-15 22:13:21

  3. Current output, few changes:

    error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements
     --> src/main.rs:5:5
      |
    5 |     fn next(&mut self) -> Option<&str> { Some("h") }
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
    note: first, the lifetime cannot outlive the anonymous lifetime defined here...
     --> src/main.rs:5:13
      |
    5 |     fn next(&mut self) -> Option<&str> { Some("h") }
      |             ^^^^^^^^^
    note: ...so that the method type is compatible with trait
     --> src/main.rs:5:5
      |
    5 |     fn next(&mut self) -> Option<&str> { Some("h") }
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      = note: expected `fn(&mut Mine<'a>) -> Option<&str>`
                 found `fn(&mut Mine<'a>) -> Option<&str>`
    note: but, the lifetime must be valid for the lifetime `'a` as defined here...
     --> src/main.rs:3:7
      |
    3 | impl <'a>Iterator for Mine<'a> {
      |       ^^
    note: ...so that the types are compatible
     --> src/main.rs:5:5
      |
    5 |     fn next(&mut self) -> Option<&str> { Some("h") }
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      = note: expected `<Mine<'a> as Iterator>`
                 found `<Mine<'_> as Iterator>`
    

    Esteban Kuber at 2022-04-23 01:26:14

  4. Current output:

    error: `impl` item signature doesn't match `trait` item signature
     --> src/main.rs:5:5
      |
    5 |     fn next(&mut self) -> Option<&str> { Some("h") }
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 mut Mine<'a>) -> Option<&'1 str>`
     --> /rustc/42b1224e9eb37177f608d3f6a6f2be2ee13902e4/library/core/src/iter/traits/iterator.rs:112:5
      |
      = note: expected `fn(&'1 mut Mine<'a>) -> Option<&'a str>`
      |
      = note: expected signature `fn(&'1 mut Mine<'a>) -> Option<&'a str>`
                 found signature `fn(&'1 mut Mine<'a>) -> Option<&'1 str>`
      = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
      = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
    

    Esteban Kuber at 2023-10-16 20:22:04