Lifetime of struct returned from function


Hi, i have 2 structs as such:
struct HCICommand<'a>
ogf: u8,
ocf: u16,
command: &'a [u8],

struct HCIResponse<'a>
eventcode: u8,
length: u8,
params: &'a [u8],

And a function:
fn bt_send_hci_command(cmd: &HCICommand) -> HCIResponse
let mut ret = HCIResponse{eventcode: 0, length: 0, params: &[0 as u8]};

Which gets me an error on “-> HCIResponse” in the function
missing lifetime specifier [E0106]:
this function’s return type contains a borrowed value, but the signature does not say which one of cmd's 2 elided lifetimes it is borrowed from
expected lifetime parameter

which says there is a problem with the lifetimes in HCICommand?


You need to define an explicit lifetime for bt_send_hci_command(), like so:

fn bt_send_hci_command<'a>(cmd: &'a HCICommand) -> HCIResponse<'a> {}

But your code still won’t build because of this line:

params: &[0 as u8],

The struct doesn’t own the array, only a reference to it. So once you return from the function, the array is freed from the stack and you end up pointing to garbage.


The problem is that cmd argument has two lifetime parameters, and Rust doesn’t know what you want in '?:

fn send<'a, 'b>(cmd: &'a HCICommand<'b>) -> HCIResponse<'?>

If you want to return params that are a part of cmd.command (or just cmd.command), then the valid annotation would be:

fn bt_send_hci_command<'a>(cmd: &HCICommand<'a>) -> HCIResponse<'a>
    HCIResponse { eventcode: 0, length: 0, params: &cmd.command[1..5] }

If you want to create params from scratch, as in your example, you need to change the params field from &[u8] to just Vec<u8> and return a vector.