How to return reference to local variable?

I have a custom type called u24:

#[derive(Copy, Clone, Debug, Default)]
#[repr(C)]
pub struct u24(pub [u8; 3]);

impl From<u32> for u24 {
    fn from(num: u32) -> Self {
        let [a, b, c, _] = num.to_le_bytes();
        u24([a, b, c])
    }
}

And implement a Deref trait for u24 like so:

impl Deref for u24 {
    type Target = u32;
    fn deref(&self) -> &'static u32 {
        let u24([a, b, c]) = *self;
        &u32::from_le_bytes([a, b, c, 0])
    }
}

I got this error:

   |      &u32::from_le_bytes([a, b, c, 0])
   |      ^--------------------------------
   |      ||
   |      |temporary value created here
   |      returns a reference to data owned by the current function

I know what this error message is about, So I did something like this:

    fn deref(&self) -> &'static u32 {
        let u24([a, b, c]) = *self;
        &u32::from_le_bytes([a, b, c, 0]).clone()
    }

My Idea is, instead of returning reference, return a clone version ? So How to create a clone and return that reference?

You cannot directly return a reference to a local - the reference is effectively a "pointer" and once the function returns, the local is dropped and so a reference to it is dangling.
What you need to do is to store the u32 in the struct and then return a reference to it.
As a side note, why are you implementing Deref trait for a type that is supposed to behave like a primitive?

1 Like

Deref (any any method that returns a borrowed reference) is for giving access to bytes that already exist in memory, exactly in their final form. You can't use it to transform the value on the fly.

References can only borrow something that has longer-lived storage. Variables inside functions are always destroyed before the function returns, so they can't be used after the function returns. It's not a matter of syntax, it's just a hard limitation reflecting how the code works (if you force it through with unsafe and raw pointers, you're going to get strange bugs and crashes).

You'll have to return endian-flipped bytes by value, from a custom method, not deref.

2 Likes

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.