0

I'm trying to initialize a struct like the following:

struct UsbCommandPort<'a> {
    serial: SerialPort<'a, UsbBus<USB>>,
    usb_dev: UsbDevice<'a, UsbBus<USB>>,
}

impl UsbCommandPort<'_> {
    pub fn new() -> Self
    {
        let usb: USB = USB::new();
        let usb_bus: UsbBusAllocator<UsbBus<USB>> = UsbBus::new(usb);

        let serial:SerialPort<'_, UsbBus<USB>> = SerialPort::new(&usb_bus);

        let usb_dev:UsbDevice<'_, UsbBus<USB>> = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
            .device_class(usbd_serial::USB_CLASS_CDC)
            .build();

        UsbCommandPort { 
            serial: serial, 
            usb_dev: usb_dev,
        }
    }

Both SerialPort::new and UsbDeviceBuilder::new take a reference to usb_bus.

This function fails to compile with the error

error[E0515]: cannot return value referencing local variable `usb_bus`

This makes sense, as usb_bus will cease to exist when the function returns, and the references will be dangling.

To prevent this from happening, I'd like to transfer ownership of usb_bus to the struct. So I add it as as a member variable:

struct UsbCommandPort<'a> {
    usb_bus: UsbBusAllocator<UsbBus<USB>>,
    serial: SerialPort<'a, UsbBus<USB>>,
    usb_dev: UsbDevice<'a, UsbBus<USB>>,
}

impl UsbCommandPort<'_> {
    pub fn new() -> Self
    {
        let usb: USB = USB::new();
        let usb_bus: UsbBusAllocator<UsbBus<USB>> = UsbBus::new(usb);

        let serial:SerialPort<'_, UsbBus<USB>> = SerialPort::new(&usb_bus);

        let usb_dev:UsbDevice<'_, UsbBus<USB>> = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
            .device_class(usbd_serial::USB_CLASS_CDC)
            .build();

        UsbCommandPort {
            usb_bus: usb_bus, 
            serial: serial, 
            usb_dev: usb_dev,
        }
    }

However this also fails to compile. The previous error is still there:

error[E0515]: cannot return value referencing local variable `usb_bus`

and now there is a new error:

error[E0505]: cannot move out of `usb_bus` because it is borrowed

I cannot transfer ownership of usb_bus to the struct because it is already borrowed. However, I cannot create the struct without initializing serial and usb_dev which require the borrows.

Can I somehow incrementially initalize the struct, by first assigning usb_bus, then update it by assigning serial and usb_dev with references to the struct-owned usb_bus?

cafce25
  • 15,907
  • 4
  • 25
  • 31
bcattle
  • 12,115
  • 6
  • 62
  • 82

0 Answers0