How to use the Rustonomicon's way to interpret this returned lifetime issue

Consider this example:

use std::collections::HashMap;
fn get_default2<'r>(map: &'r mut HashMap<i32, ()>, key: i32) -> &'r mut () {
    if map.contains_key(&key) {
        // ^~~~~~~~~~~~~~~~~~ 'n
        return match map.get_mut(&key) {  // #1
            // + 'r
            Some(value) => value,   // |
            None => unreachable!(), // |
        }; // v
    }

    // At this point, `map.get_mut` was never
    // called! (As opposed to having been called,
    // but its result no longer being in use.)
    // #2
    map.insert(key, ()); // OK now.
    map.get_mut(&key).unwrap()
}

This code is sourced from 2094-nll - The Rust RFC Book. From the perspective of NLL, the example is ok because the Control-flow graph that goes through #1 won't go through #2, so the loan at #1 does not include the point #2.

However, I don't know how to interpret this example in terms of the Rustonomicon's way. I tried to annotate the example in Rustonomicon's manner:

fn get_default2<'r>(map: &'r mut HashMap<i32, ()>, key: i32) -> &'r mut () {
    'body:{
        if 't:{ map.contains_key(&'t key) } {
            return match map.get_mut(&'r key) {  // #1
                Some(value) => value,   
                None => unreachable!(),
            }; 
        }
        // #2
        map.insert(key, ()); // OK now.
        map.get_mut(&key).unwrap()
    }
}
/*
  'r:{
      get_default2(&'r map,0);
   }
*/

The lifetime 'r contains the function call, so the whole 'body is contained within 'r, so the borrowing borrowed at #1 should be alive at #2, which should conflict with the borrowing at #2.

Out-of-curiously, I wonder how to use the Rustonomicon's mental model to interpret this tricky problem.

There is no labeling of lexical scopes that can fully describe the NLL approach to lifetimes in all cases. That's why it’s called “non-lexical lifetimes”. The part of the Nomicon you are reading was written before NLL, and only lightly updated afterward.

2 Likes

You mean, with analogy to lexical blocks? You probably can't, it's too inaccurate. I would advise not bothering.

Note that this chapter was authored before the NLL RFC was submitted as a PR, much less stabilized.

1 Like

Okay, I see. The approach outlined in Rustonomicon is ineffective in addressing this complex lifetime issue.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.