title: Interior mutability abuse in API design?
body: <p>My background in C++ makes me uncomfortable about <em>interior mutability</em>.
  The code below is my investigation around this topic.</p>
  <p>I agree that, from the borrow checker point of view, dealing with
  many references on every single struct which internal state could
  be altered soon or later is impossible; that's clearly where
  interior mutability can help.</p>
  <p>Moreover, in chapter <a href="https://doc.rust-lang.org/book/ch15-05-interior-mutability.html" rel="noreferrer">15.5 &quot;RefCell and the Interior Mutability Pattern&quot;</a> of <em>The Rust Programming Language</em>, the example
  about the <code>Messenger</code> trait and its implementation on the
  <code>MockMessenger</code> struct makes me think that it is a common API
  design to systematically prefer <code>&amp;self</code> over <code>&amp;mut self</code> even
  if its quite obvious that some kind mutability will be mandatory
  soon or later.
  How could an implementation of <code>Messenger</code> not alter its internal
  state when sending a message?
  The exception is just printing the message, which is consistent
  with <code>&amp;self</code>, but the <em>general case</em> would probably consist in
  writing to some kind of inner stream, which could imply buffering,
  updating error flags...
  All of this certainly requires <code>&amp;mut self</code>, as for example
  <a href="https://doc.rust-lang.org/std/fs/struct.File.html#impl-Write" rel="noreferrer"><code>impl Write for File</code></a>.</p>
  <p>Relying on interior mutability to solve this problem sounds to me
  like, in C++, <code>const_cast</code>ing or abusing of <code>mutable</code> members just
  because elsewhere in the application we were not consistent about
  <code>const</code>ness (common mistake for learners of C++).</p>
  <p>So, back to my example code below, should I:</p>
  <ul>
  <li>use <code>&amp;mut self</code> (the compiler doesn't complain, even if it's
  not mandatory) from <code>change_e()</code> to <code>change_i()</code> in order to
  keep consistent with the fact that I alter the values of the
  stored integers?</li>
  <li>keep using <code>&amp;self</code>, because interior mutability allows it, even
  if I actually alter the values of the stored integers?</li>
  </ul>
  <p>This decision is not only local to the struct itself but will
  have a large influence on what could be expressed in the
  application using this struct.
  The second solution will certainly help a lot, because only
  shared references are involved, but is it consistent with what
  is expected in Rust.</p>
  <p>I cannot find an answer to this question in
  <a href="https://rust-lang.github.io/api-guidelines/" rel="noreferrer">Rust API Guidelines</a>.
  Is there any other Rust documentation similar to
  <a href="http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines" rel="noreferrer">C++CoreGuidelines</a>?</p>
  <pre><code>/*
      $ rustc int_mut.rs &amp;&amp; ./int_mut
       initial:   1   2   3   4   5   6   7   8   9
      change_a:  11   2   3   4   5   6   7   8   9
      change_b:  11  22   3   4   5   6   7   8   9
      change_c:  11  22  33   4   5   6   7   8   9
      change_d:  11  22  33  44   5   6   7   8   9
      change_e:  11  22  33  44  55   6   7   8   9
      change_f:  11  22  33  44  55  66   7   8   9
      change_g:  11  22  33  44  55  66  77   8   9
      change_h:  11  22  33  44  55  66  77  88   9
      change_i:  11  22  33  44  55  66  77  88  99
  */
  
  struct Thing {
      a: i32,
      b: std::boxed::Box&lt;i32&gt;,
      c: std::rc::Rc&lt;i32&gt;,
      d: std::sync::Arc&lt;i32&gt;,
      e: std::sync::Mutex&lt;i32&gt;,
      f: std::sync::RwLock&lt;i32&gt;,
      g: std::cell::UnsafeCell&lt;i32&gt;,
      h: std::cell::Cell&lt;i32&gt;,
      i: std::cell::RefCell&lt;i32&gt;,
  }
  
  impl Thing {
      fn new() -&gt; Self {
          Self {
              a: 1,
              b: std::boxed::Box::new(2),
              c: std::rc::Rc::new(3),
              d: std::sync::Arc::new(4),
              e: std::sync::Mutex::new(5),
              f: std::sync::RwLock::new(6),
              g: std::cell::UnsafeCell::new(7),
              h: std::cell::Cell::new(8),
              i: std::cell::RefCell::new(9),
          }
      }
  
      fn show(&amp;self) -&gt; String // &amp; is enough (read-only)
      {
          format!(
              &quot;{:3} {:3} {:3} {:3} {:3} {:3} {:3} {:3} {:3}&quot;,
              self.a,
              self.b,
              self.c,
              self.d,
              self.e.lock().unwrap(),
              self.f.read().unwrap(),
              unsafe { *self.g.get() },
              self.h.get(),
              self.i.borrow(),
          )
      }
  
      fn change_a(&amp;mut self) // &amp;mut is mandatory
      {
          let target = &amp;mut self.a;
          *target += 10;
      }
  
      fn change_b(&amp;mut self) // &amp;mut is mandatory
      {
          let target = self.b.as_mut();
          *target += 20;
      }
  
      fn change_c(&amp;mut self) // &amp;mut is mandatory
      {
          let target = std::rc::Rc::get_mut(&amp;mut self.c).unwrap();
          *target += 30;
      }
  
      fn change_d(&amp;mut self) // &amp;mut is mandatory
      {
          let target = std::sync::Arc::get_mut(&amp;mut self.d).unwrap();
          *target += 40;
      }
  
      fn change_e(&amp;self) // !!! no &amp;mut here !!!
      {
          // With C++, a std::mutex protecting a separate integer (e)
          // would have been used as two data members of the structure.
          // As our intent is to alter the integer (e), and because
          // std::mutex::lock() is _NOT_ const (but it's an internal
          // that could have been hidden behind the mutable keyword),
          // this member function would _NOT_ be const in C++.
          // But here, &amp;self (equivalent of a const member function)
          // is accepted although we actually change the internal
          // state of the structure (the protected integer).
          let mut target = self.e.lock().unwrap();
          *target += 50;
      }
  
      fn change_f(&amp;self) // !!! no &amp;mut here !!!
      {
          // actually alters the integer (as with e)
          let mut target = self.f.write().unwrap();
          *target += 60;
      }
  
      fn change_g(&amp;self) // !!! no &amp;mut here !!!
      {
          // actually alters the integer (as with e, f)
          let target = self.g.get();
          unsafe { *target += 70 };
      }
  
      fn change_h(&amp;self) // !!! no &amp;mut here !!!
      {
          // actually alters the integer (as with e, f, g)
          self.h.set(self.h.get() + 80);
      }
  
      fn change_i(&amp;self) // !!! no &amp;mut here !!!
      {
          // actually alters the integer (as with e, f, g, h)
          let mut target = self.i.borrow_mut();
          *target += 90;
      }
  }
  
  fn main() {
      let mut t = Thing::new();
      println!(&quot; initial: {}&quot;, t.show());
      t.change_a();
      println!(&quot;change_a: {}&quot;, t.show());
      t.change_b();
      println!(&quot;change_b: {}&quot;, t.show());
      t.change_c();
      println!(&quot;change_c: {}&quot;, t.show());
      t.change_d();
      println!(&quot;change_d: {}&quot;, t.show());
      t.change_e();
      println!(&quot;change_e: {}&quot;, t.show());
      t.change_f();
      println!(&quot;change_f: {}&quot;, t.show());
      t.change_g();
      println!(&quot;change_g: {}&quot;, t.show());
      t.change_h();
      println!(&quot;change_h: {}&quot;, t.show());
      t.change_i();
      println!(&quot;change_i: {}&quot;, t.show());
  }
  </code></pre>