Cannot return value referencing local variable?

Maybe there is some question something like this, But It did not helped me.

playground

use std::{collections::HashMap, str};

fn parse(&buf: &[u8; 1024]) -> HashMap<&str, &str> {
    let map: HashMap<&str, &str> = str::from_utf8(&buf)
        .unwrap()
        .split("\r\n")
        .map(|string| string.split_once(": "))
        .filter_map(|opt| opt.is_some().then(|| opt.unwrap()))
        .into_iter()
        .collect();

    map
}

My question is why I got this error. And how can I fix it?

error[E0515]: cannot return value referencing local variable `buf`
  --> src/main.rs:16:5
   |
8  |     let map: HashMap<&str, &str> = str::from_utf8(&buf)
   |                                                   ---- `buf` is borrowed here
...
16 |     map
   |     ^^^ returns a value referencing data owned by the current function

Left side of : is a pattern, which performs certain actions. In your case &buf means copying the input to a local, owned buf variable (& on the left of : is like * on the right).

If you use buf: &[u8; 1024], it should be correctly borrowing the data instead of copying.

1 Like

Remove the & from &buf like so.

Changes:

-fn parse(&buf: &[u8; 335]) -> HashMap<&str, &str> {
-    let map: HashMap<&str, &str> = str::from_utf8(&buf)
+fn parse(buf: &[u8; 335]) -> HashMap<&str, &str> {
+    let map: HashMap<&str, &str> = str::from_utf8(buf).unwrap()

Explanation:

  • parse(&buf: &[u8; 1024]) is like parse(buf: [u8; 1024]), so you're passing in the whole buffer.
    • That's why you needed to take a reference in the call to from_utf8
  • It's similar to how these work:
    • if let Some(thing) = foo { /* ... */ }
    • match foo { Some(thing) => {}, None => {} }
  • In particular the & on &buf matched the & on &[_, _] and so buf binded to the [_, _] "underneath"

The keyword to look for to read up on this is "patterns"; it's a somewhat big topic.

3 Likes

Thanks @quinedot, For your valuable time. Also for Great Explanation...

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.