[ NEWBIE ] `Arc` cannot borrow as mutable

i am trying to .next() on an Arc, but i cannot go past this error

error[E0596]: cannot borrow data in an `Arc` as mutable
  --> src/reply.rs:26:32
   |
26 |         while let Some(line) = self.reader.next().await {
   |                                ^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
   |
   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Arc<FramedRead<tokio::net::tcp::OwnedReadHalf, ReplyDecoder>>`

Code

use std::sync::Arc;
use tokio::net::tcp::OwnedReadHalf;
use tokio_util::codec::FramedRead;
use tokio_stream::StreamExt;
use std::fmt::Debug;

use crate::{ ReplyDecoder, ReplyError };

#[derive(Debug)]
pub struct Reply {
    reader: Arc<FramedRead<OwnedReadHalf, ReplyDecoder>>,
    code: u16,
    data: String,
}

impl Reply {
    pub fn new(mut reader: Arc<FramedRead<OwnedReadHalf, ReplyDecoder>>) -> Self {
        Self {
            reader,
            code: 0,
            data: String::new()
        }
    }

    pub async fn get(&mut self) -> Result<(u16, String), ReplyError> {
        while let Some(line) = self.reader.next().await {
            println!("> {:?}", line);
        }

        Ok((220, String::new()))
    }
}

You can't mutate through an Arc, because a reference-counted pointer may be shared, and shared mutation is exactly what Rust is trying to prevent.

Usually, this kind of design requires interior mutability (i.e., Arc<Mutex<…>>), however, I would recommend you to stop and think if you really want to circumvent static borrow checking. What are you trying to achieve? Why do you think you need to mutate state through an Arc?

1 Like

i want to read the response comming from the server, i am using FramedRead which uses StreamExt::next() chich take a &mut self as an argument.

The question here is why are you using Arc<T> instead of Box<T> or just T. If you don't need the shared ownership semantic of Arc, don't use it.

2 Likes

Yeah, generally I would not put a FramedRead in an Arc. Just remove the Arc.

(No reason to put a Box either.)

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.