Cannot move out of dereference of std::cell::RefMut

Hi friends

pub struct Transporter {
    ingress_receiver : RefCell<UnboundedReceiver<InternalMessage>>,
}


impl Transporter {
    pub fn new(tx:UnboundedSender<InternalMessage>) ->  Transporter {
        Transporter{
            ingress_receiver : RefCell::new(rx),
        }
    }

    pub async fn run(&mut self){
        let borrow = self.ingress_receiver.borrow_mut();
        let ingress_task = borrow.fuse();

        // ...
    }
}
error[E0507]: cannot move out of dereference of `std::cell::RefMut<'_, futures_channel::mpsc::UnboundedReceiver<shuttle::InternalMessage>>`
   --> src/shuttle.rs:105:32
    |
105 |             let ingress_task = borrow.fuse();
    |                                ^^^^^^ move occurs because value has type `futures_channel::mpsc::UnboundedReceiver<shuttle::InternalMessage>`, which does not implement the `Copy` trait

I intent to borrow UnboundedReceiver<InternalMessage>, but why does it say it is moved?
How to fix this compliation error?

Thanks for your help

fuse wraps the future in its own structure. Possible fix might be just to include the Fuse type in your RefCell. (I'm unsure of why you want to be using RefCell at all.)

I thought RefCell would solve my error.

#[allow(dead_code)]
pub struct Transporter {
    ingress_receiver : UnboundedReceiver<InternalMessage>,
}


impl Transporter {
    pub fn new(tx:UnboundedSender<InternalMessage>) ->  Transporter {
        Transporter{
            ingress_receiver : rx,
        }
    }

    pub async fn run(&mut self){
        let ingress_task = self.ingress_receiver.fuse();

    }
}
error[E0507]: cannot move out of `self.ingress_receiver` which is behind a mutable reference
   --> src/shuttle.rs:103:28
    |
103 |         let ingress_task = self.ingress_receiver.fuse();
    |                            ^^^^^^^^^^^^^^^^^^^^^ move occurs because `self.ingress_receiver` has type `futures_channel::mpsc::UnboundedReceiver<shuttle::InternalMessage>`, which does not implement the `Copy` trait

It seems the error has nothing to do with RefCell.
Is there a way to fix it besides storing Fuse ?

Does let ingress_task = self.ingress_receiver.borrow_mut().by_ref().fuse(); solve the problem?
Iterator::fuse() consumes the iterator itself, so Iterator::by_ref() can help .fuse() to consume reference of the iterator instead of the iterator itself.

1 Like

Just fuse it when creating the type

[allow(dead_code)]
pub struct Transporter {
    ingress_receiver : Fuse<UnboundedReceiver<InternalMessage>>,
}


impl Transporter {
    pub fn new(tx:UnboundedSender<InternalMessage>) ->  Transporter {
        Transporter{
            ingress_receiver: rx.fuse(),
        }
    }
}
1 Like