1

I have a struct containing a RefCell wrapping a TlsStream<TcpStream>. I tested replacing the TlsStream<IO> with an i32 and am able to mutate the struct member, but the compiler errors when using the stream. I get the following error when attempting to write to it:

error[E0596]: cannot borrow data in a `&` reference as mutable
  --> src/main.rs:18:9
   |
18 | /         self.i
19 | |             .tcp4_stream
20 | |             .borrow_mut()
21 | |             .as_ref()
22 | |             .unwrap()
   | |_____________________^ cannot borrow as mutable

MCVE:

[package]
name = "mvce"
version = "0.1.0"
authors = ["Joshua Abraham <sinisterpatrician@gmail.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
async-std = "1.6.3"
async-tls = "0.9.0"
use async_std::net::TcpStream;
use async_std::prelude::*;
use async_tls::client::TlsStream;
use std::{cell::RefCell, rc::Rc};

#[derive(Default, Clone)]
struct Client {
    i: Rc<ClientInternal>,
}

#[derive(Default)]
struct ClientInternal {
    tcp4_stream: RefCell<Option<TlsStream<TcpStream>>>,
}

impl Client {
    async fn send(&self) {
        self.i
            .tcp4_stream
            .borrow_mut()
            .as_ref()
            .unwrap()
            .write_all(b"hello world!")
            .await;
    }
}

fn main() {
    println!("Hello, world!");
}

How can I make use of interior mutability here?

Josh Abraham
  • 959
  • 1
  • 8
  • 18
  • It's hard to answer your question because it doesn't include a [MRE]. We can't tell what crates (**and their versions**), types, traits, fields, etc. are present in the code. It would make it easier for us to help you if you try to reproduce your error on the [Rust Playground](https://play.rust-lang.org) if possible, otherwise in a brand new Cargo project, then [edit] your question to include the additional info. There are [Rust-specific MRE tips](//stackoverflow.com/tags/rust/info) you can use to reduce your original code for posting here. Thanks! – Shepmaster Aug 24 '20 at 12:36
  • 1
    It seems you've already achieved interior mutability, but by calling `as_ref()` you effectively discard your mutable reference and take an immutable one – Alexey S. Larionov Aug 24 '20 at 12:38
  • 1
    TL;DR the fix: `.as_mut()`, not `.as_ref()`. – Shepmaster Aug 24 '20 at 12:39
  • @Shepmaster thanks for the tip. I edited the question to include Crate versions, let me know if I should delete it – Josh Abraham Aug 24 '20 at 12:42
  • There's nothing inherently wrong with duplicates on Stack Overflow — they serve as signposts in case other people phrase their question the same way you do. Besides that, at least two people upvoted your question, so they saw value in it. – Shepmaster Aug 24 '20 at 12:43
  • 1
    @SvenMarnach you may believe it, but you are wrong :-). `error[E0507]: cannot move out of dereference of \`std::cell::RefMut<'_, std::option::Option>>\`` – Shepmaster Aug 24 '20 at 12:44
  • Ah, I see it now. :) – Sven Marnach Aug 24 '20 at 12:44

0 Answers0