Stuck with getting lifetime right

⚓ Rust    📅 2025-12-20    👤 surdeus    👁️ 1      

surdeus

I have a struct, that contains a vec of enums.
Some of the enums have references in them
the struct impl supports a trait overloaded method for adding to that vec for all sorts of different types.

struct:

pub struct FuncDef<'argval> {
    ...
    pub(crate) arg_vals: Vec<ArgVal<'argval>>,
}

enum:

pub enum ArgVal<'argval> {
    Pointer(*mut c_void),
    U64(u64),
    F64(f64),
    I64(i64),
    I32(i32),
    U32(u32),
    I16(i16),
    U16(u16),
    F32(f32),
    Char(u8),
    CString(CString),
    RustString(&'argval String),  <<< note lifetimed ref
    None,
}

trait

pub trait ToMutArg<'argval> {
    fn to_mut_arg(&mut self, func: &mut FuncDef<'argval>) -> *mut c_void;
}

generic push using that trait

impl<'argval> FuncDef<'argval> {

    pub fn push_mut_arg<T>(&mut self, value: &mut T)
    where
        T: ToMutArg<'argval> + ?Sized,
    {
        let argp = value.to_mut_arg(self);
        self.arg_ptrs.push(argp);
    }

trait impl for String (my first one to implement)

impl<'argval> ToMutArg<'argval> for String {
    fn to_mut_arg(&mut self, func: &mut FuncDef<'argval>) -> *mut c_void {
        let arg_idx = func.arg_ptrs.len();
        let arg_type = &func.arg_types[arg_idx];

        match arg_type {
            ArgType::OCString => {
                let mut buffer = self.as_mut_ptr() as *mut c_void;
                func.arg_vals.push(ArgVal::Pointer(buffer));

                func.arg_vals.push(ArgVal::RustString(self));

produces

error: lifetime may not live long enough
  --> src\args.rs:91:17
   |
81 | impl<'argval> ToMutArg<'argval> for String {
   |      ------- lifetime `'argval` defined here
82 |     fn to_mut_arg(&mut self, func: &mut FuncDef<'argval>) -> *mut c_void {
   |                   - let's call the lifetime of this reference `'1`
...
91 |                 func.arg_vals.push(ArgVal::RustString(self));
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'argval`
   |

I thought I had understood lifetimes, clearly not well enough

2 posts - 2 participants

Read full topic

🏷️ Rust_feed