Life time in trait

Hi , I am trying to abstract a layar from another using traits and I get some lifetime error.

#![cfg(not(any(target_os = "none", target_os = "linux")))]
use crate::kline::KlineMessage;
use crate::kline::{KlineHardwareHandshake, KlineHardwareTransmit};
use alloc::format;
use alloc::rc::Rc;
use core::cell::RefCell;
use core::marker::PhantomData;
use esp_idf_hal::delay::FreeRtos;
use esp_idf_hal::gpio::{InputPin, Output, OutputPin, PinDriver};
use esp_idf_hal::peripheral::Peripheral;
use esp_idf_hal::uart::{config::Config, Uart as Uart_idf, UartDriver};
use protocols::config;
// an abstract layer for uart for my library
pub struct Uart<'d> {
    serial: esp_idf_hal::uart::UartDriver<'d>,
    _p: PhantomData<&'d mut ()>,
}

impl<'d> Uart<'d> {
    pub fn new(serial: esp_idf_hal::uart::UartDriver<'d>) -> Self {
        Self {
            serial,
            _p: PhantomData,
        }
    }
}

impl<'d> KlineHardwareTransmit for Uart<'d> {
    fn transmit(&mut self, frame: &KlineMessage) {
        platform::functions::print_string(format!("frame is : {:?}", frame.data));
        self.serial.write(&frame.data).expect("could not send");
    }
    fn read(&self, buf: &mut [u8], delay: u32) -> Result<usize, ()> {
        platform::functions::print_string(format!("read frame is : {:?}", buf));
        match self.serial.read(buf, delay) {
            Ok(size) => Ok(size),
            _ => Err(()),
        }
    }
}

unsafe impl<'d> Send for Uart<'d> {}

pub struct KlinePeripherals<Tx, Rx, U> {
    tx: Rc<RefCell<Tx>>,
    rx: Rc<RefCell<Rx>>,
    uart: Rc<RefCell<U>>,
}

impl<'d, Tx: Peripheral + 'd, Rx: Peripheral + 'd, U: Peripheral + 'd> KlinePeripherals<Tx, Rx, U>
where
    Tx::P: OutputPin,
    Rx::P: InputPin,
    U::P: Uart_idf,
{
    pub fn new(tx: Tx, rx: Rx, uart: U) -> Self {
        Self {
            tx: Rc::new(RefCell::new(tx)),
            rx: Rc::new(RefCell::new(rx)),
            uart: Rc::new(RefCell::new(uart)),
        }
    }

    pub fn to_uart(&self, config: &Config) -> Result<Uart, ()> {
        let serial = Uart::new(
            UartDriver::new(
                self.uart.borrow_mut(),
                self.tx.borrow_mut(),
                self.rx.borrow_mut(),
                config,
            )
            .unwrap(),
        );
        Ok(serial)
    }
}

impl<
        'd,
        Tx: Peripheral + 'd + esp_idf_hal::gpio::OutputPin,
        Rx: Peripheral + 'd,
        U: Peripheral + 'd,
    > crate::kline::ToHandshake<'d, Handshake<'d, Tx>> for KlinePeripherals<Tx, Rx, U>
where
    Tx::P: OutputPin,
    Rx::P: InputPin,
    U::P: Uart_idf,
{
    fn to_handshake(&'d mut self) -> Handshake<'d, Tx> {
        Handshake {
            kline_tx: PinDriver::output(self.tx.borrow_mut()).unwrap(),
            _p: PhantomData,
        }
    }
}

pub struct Handshake<'d, Tx: OutputPin> {
    kline_tx: PinDriver<'d, Tx, Output>,
    _p: PhantomData<&'d ()>,
}
impl<'d, Tx: OutputPin> KlineHardwareHandshake for Handshake<'d, Tx> {
    fn init(&mut self, init_type: config::KlineInitType) {
        match init_type {
            config::KlineInitType::KLINE_INIT_TYPE_FAST => {
                self.kline_tx.set_low();
                FreeRtos::delay_ms(25);
                self.kline_tx.set_high();
                FreeRtos::delay_ms(25);
            }
            config::KlineInitType::KLINE_INIT_TYPE_5_BAUD => {
                self.kline_tx.set_low();
                FreeRtos::delay_ms(400);
                self.kline_tx.set_high();
                FreeRtos::delay_ms(400);
            }
        }
        platform::functions::print_str("handshake");
    }
}

this is my code and the error is

error: lifetime may not live long enough
   --> modules/ecu/src/kline/mod.rs:118:25
    |
78  | impl<'d, U, H, Tx: ToUart<U> + ToHandshake<'d, H>> KlineTransceiver<'d, U, H, Tx>
    |      -- lifetime `'d` defined here
...
111 |     pub fn process(&mut self) {
    |                    - let's call the lifetime of this reference `'1`
...
118 |                         self.kline_transceiver.to_handshake().init(self.init_type);
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'d`                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'d`

I should tell the compiler that handshake may live less that the main prephrials. But as it seems I am doing it wrong.

The error message you provide is incomplete. A full error message will be outputted if you use cargo check (or other cargo commands) in the terminal. An error message begins with error[E…]: …message… and ends when the next error (or warning) begins.

1 Like