Skip to content

Random lifetime may not live long enough from other part of the code #96645

Open

Description

I just stumbled across a weird and inconsistent behaviour, that seems unreasonable to me.

The project I'm working on is a big company project (closed source) with quite some files. While fixing a bug and editing one line in one module (src/dispatcher/compiler/module_range.rs) the compiler suddenly decided to reject the code of a function from a completely different module (src/services/module_state_service.rs) that has absolutely nothing to do with the module I'm working on.

The change that I made:

fn get_next_module_start(&self, module: &FunctionalModule<'a>, starter: &'a Fmid) -> Result<usize> {
        // -- snip --
        WorkflowIterator::exe_path_iter(
            self.modules,
            starter,
            |m| m.fmd.next_module.as_ref().into_option(),
-           |m| super::sort_exe_paths(&m.fmd.exe_paths),
+           |m| (m != module).then(|| super::sort_exe_paths(&m.fmd.exe_paths)).into_iter().flatten(),
            |m| m.md.kind,
        )
        // -- snip --
}

The compiler error:

error: lifetime may not live long enough
  --> src/services/module_state_service.rs:35:44
   |
32 |           &'_ self,
   |            -- let's call the lifetime of this reference `'1`
33 |           workflow_id: &WorkflowGroupId,
34 |           fmid: &Fmid,
   |                 - let's call the lifetime of this reference `'2`
35 |       ) -> Option<RwLockReadGuard<'_, [u8]>> {
   |  ____________________________________________^
36 | |         let map_guard = self.module_state.read().await;
37 | |
38 | |         let contains_state = map_guard
...  |
49 | |         }))
50 | |     }
   | |_____^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'2`

error: lifetime may not live long enough
  --> src/services/module_state_service.rs:47:9
   |
32 |           &'_ self,
   |            -- let's call the lifetime of this reference `'1`
33 |           workflow_id: &WorkflowGroupId,
34 |           fmid: &Fmid,
   |                 - let's call the lifetime of this reference `'2`
...
47 | /         Some(RwLockReadGuard::map(map_guard, |map| {
48 | |             &**map.get(workflow_id).unwrap().get(fmid).unwrap()
49 | |         }))
   | |___________^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`

The function the compiler complains about:

pub async fn get_module_state(
    &'_ self,
    workflow_id: &WorkflowGroupId,
    fmid: &Fmid,
) -> Option<RwLockReadGuard<'_, [u8]>> {
    let map_guard = self.module_state.read().await;

    let contains_state = map_guard
        .get(workflow_id)
        .map(|map| map.contains_key(fmid))
        .unwrap_or_default();

    if !contains_state {
        return None;
    }

    Some(RwLockReadGuard::map(map_guard, |map| {
        &**map.get(workflow_id).unwrap().get(fmid).unwrap()
    }))
}

When undoing the one-line change, the code compiled fine again, and after redoing it, it failed to compile again.
Now, after indenting a few pieces of code, to make pasting them into GitHub easier, the compiler again accepts the code.
I'm also no longer able to recreate the error.

I know, that's essentially nothing to work with, and I'm not even able to recreate the issue myself anymore, but it seems worth reporting to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)Area: Non-lexical lifetimes (NLL)A-incr-compArea: Incremental compilationArea: Incremental compilationNLL-completeWorking towards the "valid code works" goalWorking towards the "valid code works" goalP-mediumMedium priorityMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions