Issue with borrow checker and returned references

I want to make an object that wraps a HashMap, similar to the example below:

use rand;
use rand::distributions::{Alphanumeric, DistString};
use std::collections::HashMap;

struct StringBank {
    strings: HashMap<usize, String>

impl StringBank {
    fn new() -> Self {
        StringBank {
            strings: HashMap::new()
    fn get_string_by_length(&mut self, length: usize) -> &str {
        match self.strings.get(&length) {
            Some(s) => &s,
            None => {
                let string = Alphanumeric.sample_string(&mut rand::thread_rng(), length);
                self.strings.insert(length, string);

However, this example fails to compile because "cannot borrow 'self.strings' as mutable because it is also borrowed as immutable". I believe this problem is related to the fact that the returned reference can come from an immutable borrow from self.strings, and that borrow can live long enough for a potential mutable borrow of self.strings, but I don't understand how I can solve this.

(Note: I have no plans of making a remove_string_by_length, remake_string_by_length, or get_string_by_length_mut method, so the string that is returned should live as long as the StringBank and be immutable.)

It's a known NLL issue to be solved.

A fix here would be:

    fn get_string_by_length(&mut self, length: usize) -> &str {
        self.strings.entry(length).or_insert_with(|| {
            Alphanumeric.sample_string(&mut rand::thread_rng(), length)
1 Like

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.