-1
\$\begingroup\$

So I have this piece of code that produces following error:

cannot return value referencing local variable `key_name`
returns a value referencing data owned by the current function

I want it to evaluate the Key range and produce a map of strings, but it fails on the line map. I can't seem to set up the ownership right. This is what I came up with:

use std::collections::HashMap;

use evdev::Key;

const KEY_RANGE_START : Key = Key::KEY_ESC;
const KEY_RANGE_END : Key = Key::KEY_SLASH;

const KEY_RANGE_COUNT: u16 = KEY_RANGE_END.code() - KEY_RANGE_START.code();

use lazy_static::lazy_static;

lazy_static! {
    static ref KEY_NAMES: HashMap<u16, &'static str> = {
        let mut map = HashMap::new();
        
        for index in 0..KEY_RANGE_COUNT {
            let code = index+KEY_RANGE_START.code();
            let key = Key::new(code);
            let key_name = format!("{:?}", key);

            let short_key_name = key_name.strip_prefix("KEY_").unwrap();

            map.insert(code, short_key_name.clone());
        }

        map
    };
}
\$\endgroup\$
1
\$\begingroup\$

short_key_name is a &str that was borrowed from key_name, a String allocated inside the loop and which will be dropped at the end of each loop iteration. Thus, it is not a &'static str.

You can use Box::leak to create an allocation that will stick around for the rest of the life of the program. (This is reasonable for lazy static initialization, but other uses can easily create a memory leak, as the name suggests!)

let short_key_name = &*Box::leak(Box::<str>::from(short_key_name));
map.insert(code, short_key_name);

This

  1. copies the characters of the &str into a Box<str>,
  2. forgets about the existence of the box (so it is never deallocated) and creates an &'static mut str to its contents, and
  3. converts the &'static mut str to an &'static str, matching the type needed for the HashMap.

Do not use Box::leak for any code that runs more than once! As the name says, it leaks!

\$\endgroup\$
1
  • \$\begingroup\$ Thank you very much, mr Reid. Rust has a bit of a learning curve and you helped me significantly. \$\endgroup\$
    – loa_in_
    Jul 25 '21 at 21:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.