Skip to content

Confusing lifetime error: expected (&Location<'_>,), found (&Location<'_>,) #79033

Description

@camelid

For one, I'm not sure why this isn't working since Location is Copy, but you can fix this by just storing self.start.line and self.end.line in locals and adding move before the closure. One of the weird things about this error is it says

expected (&Location<'_>,), found (&Location<'_>,)

but those are the same! Also, why are they 1-tuples? The error is a bit different on stable, the message I showed is on nightly:

expected &Location<'_>, found &Location<'_>


Code

#[derive(Debug, Clone, Copy)]
pub struct Location<'a> {
    pub filename: &'a str,
    pub start: LocationHalf,
    pub end: LocationHalf,
}

#[derive(Debug, Clone, Copy)]
pub struct LocationHalf {
    pub line: u32,
    pub column: u32,
}

impl Location<'_> {
    /// Returns an iterator over the line numbers of this location.
    pub fn line_numbers(self) -> impl Iterator<Item = u32> {
        self.start.line..=self.end.line
    }

    /// Returns an iterator over the line numbers and lines of this location.
    pub fn lines<'a>(self, source: &'a str) -> impl Iterator<Item = (u32, &'a str)> {
        let lines = source.split('\n');
        lines.enumerate().filter_map(|(i, line)| {
            if self.start.line as usize <= i && i <= self.end.line as usize {
                Some((i as u32 + 1, line))
            } else {
                None
            }
        })
    }
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
  --> src/lib.rs:23:38
   |
23 |           lines.enumerate().filter_map(|(i, line)| {
   |  ______________________________________^
24 | |             if self.start.line as usize <= i && i <= self.end.line as usize {
25 | |                 Some((i as u32 + 1, line))
26 | |             } else {
27 | |                 None
28 | |             }
29 | |         })
   | |_________^
   |
note: first, the lifetime cannot outlive the lifetime `'_` as defined on the impl at 14:15...
  --> src/lib.rs:14:15
   |
14 | impl Location<'_> {
   |               ^^
note: ...so that the types are compatible
  --> src/lib.rs:23:38
   |
23 |           lines.enumerate().filter_map(|(i, line)| {
   |  ______________________________________^
24 | |             if self.start.line as usize <= i && i <= self.end.line as usize {
25 | |                 Some((i as u32 + 1, line))
26 | |             } else {
27 | |                 None
28 | |             }
29 | |         })
   | |_________^
   = note: expected `(&Location<'_>,)`
              found `(&Location<'_>,)`
note: but, the lifetime must be valid for the lifetime `'a` as defined on the method body at 21:18...
  --> src/lib.rs:21:18
   |
21 |     pub fn lines<'a>(self, source: &'a str) -> impl Iterator<Item = (u32, &'a str)> {
   |                  ^^
note: ...so that return value is valid for the call
  --> src/lib.rs:21:48
   |
21 |     pub fn lines<'a>(self, source: &'a str) -> impl Iterator<Item = (u32, &'a str)> {
   |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0495`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-lifetimesArea: Lifetimes / regionsD-confusingDiagnostics: Confusing error or lint that should be reworked.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.P-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions