Error messages about lifetimes for mutable Iterator are cryptic.

bd2d4ba
Opened by Vitaly Shukela at 2022-12-28 22:55:32

Example: http://is.gd/8dVXWc

<anon>:42:14: 42:33 error: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
<anon>:42         Some(&mut self.cont.item)
                       ^~~~~~~~~~~~~~~~~~~
<anon>:39:5: 43:6 help: consider using an explicit lifetime parameter as shown: fn next(&'a mut self) -> Option<&'a mut V>
<anon>:39     fn next(&mut self) -> Option<&'a mut V> {
<anon>:40         if self.emitted { return None }
<anon>:41         self.emitted = true;
<anon>:42         Some(&mut self.cont.item)
<anon>:43     }
error: aborting due to previous error
playpen: application terminated with error code 101

Compilation failed.

@bluss gave me a helpful link on IRC, stating that is a classic thing.

I think for every "classic" problem there should be a lint giving a link to some article about the problem.

In this case the link can be emitted for any lifetimes problem when mutable references and Iterator trait involved together.

For reference: link to changed version that does compile.

  1. Current output:

    error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
      --> src/main.rs:42:14
       |
    42 |         Some(&mut self.cont.item)
       |              ^^^^^^^^^^^^^^^^^^^
       |
    note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 39:5...
      --> src/main.rs:39:5
       |
    39 | /     fn next(&mut self) -> Option<&'a mut V> {
    40 | |         if self.emitted { return None }
    41 | |         self.emitted = true;
    42 | |         Some(&mut self.cont.item)
    43 | |     }
       | |_____^
    note: ...so that reference does not outlive borrowed content
      --> src/main.rs:42:14
       |
    42 |         Some(&mut self.cont.item)
       |              ^^^^^^^^^^^^^^^^^^^
    note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 37:1...
      --> src/main.rs:37:1
       |
    37 | / impl<'a, V:'a> Iterator for MutableIter<'a,V> {
    38 | |     type Item = &'a mut V;
    39 | |     fn next(&mut self) -> Option<&'a mut V> {
    40 | |         if self.emitted { return None }
    ...  |
    43 | |     }
    44 | | }
       | |_^
    note: ...so that expression is assignable (expected std::option::Option<&'a mut V>, found std::option::Option<&mut V>)
      --> src/main.rs:42:9
       |
    42 |         Some(&mut self.cont.item)
       |         ^^^^^^^^^^^^^^^^^^^^^^^^^
    

    Esteban Kuber at 2018-01-28 22:24:52

  2. It is better.

    Hovewer, Iterator-specific error message may still help (it should add to, no replace the current output).

    Vitaly Shukela at 2018-01-29 00:22:34

  3. Current output:

    error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
      --> src/main.rs:42:14
       |
    42 |         Some(&mut self.cont.item)
       |              ^^^^^^^^^^^^^^^^^^^
       |
    note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 39:5...
      --> src/main.rs:39:5
       |
    39 | /     fn next(&mut self) -> Option<&'a mut V> {
    40 | |         if self.emitted { return None }
    41 | |         self.emitted = true;
    42 | |         Some(&mut self.cont.item)
    43 | |     }
       | |_____^
    note: ...so that reference does not outlive borrowed content
      --> src/main.rs:42:14
       |
    42 |         Some(&mut self.cont.item)
       |              ^^^^^^^^^^^^^^^^^^^
    note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 37:1...
      --> src/main.rs:37:1
       |
    37 | impl<'a, V:'a> Iterator for MutableIter<'a,V> {
       | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       = note: ...so that the expression is assignable:
               expected std::option::Option<&'a mut V>
                  found std::option::Option<&mut V>
    

    Esteban Kuber at 2018-02-12 05:27:28

  4. Triage: no change.

    Esteban Kuber at 2020-01-22 18:52:35

  5. Current output, few changes:

    error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
      --> src/main.rs:42:14
       |
    42 |         Some(&mut self.cont.item)
       |              ^^^^^^^^^^^^^^^^^^^
       |
    note: first, the lifetime cannot outlive the anonymous lifetime defined here...
      --> src/main.rs:39:13
       |
    39 |     fn next(&mut self) -> Option<&'a mut V> {
       |             ^^^^^^^^^
    note: ...so that reference does not outlive borrowed content
      --> src/main.rs:42:14
       |
    42 |         Some(&mut self.cont.item)
       |              ^^^^^^^^^^^^^^^^^^^
    note: but, the lifetime must be valid for the lifetime `'a` as defined here...
      --> src/main.rs:37:6
       |
    37 | impl<'a, V:'a> Iterator for MutableIter<'a,V> {
       |      ^^
    note: ...so that the types are compatible
      --> src/main.rs:42:9
       |
    42 |         Some(&mut self.cont.item)
       |         ^^^^^^^^^^^^^^^^^^^^^^^^^
       = note: expected `Option<&'a mut V>`
                  found `Option<&mut V>`
    

    Esteban Kuber at 2022-04-23 01:27:30

  6. Current output

    error: lifetime may not live long enough
      --> src/main.rs:42:9
       |
    37 | impl<'a, V:'a> Iterator for MutableIter<'a,V> {
       |      -- lifetime `'a` defined here
    38 |     type Item = &'a mut V;
    39 |     fn next(&mut self) -> Option<&'a mut V> {
       |             - let's call the lifetime of this reference `'1`
    ...
    42 |         Some(&mut self.cont.item)
       |         ^^^^^^^^^^^^^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
    

    Esteban Kuber at 2022-12-28 22:55:32