title: How to store and use closures that use a common region of memory?
body: <p>I'm writing a piece of Rust code that simulates a small (typed) toy language with closures, but I'm not sure how I should store them in an <code>enum</code> so that they are still able to access/use a common heap when I evaluate the closures.</p>
  
  <p>I'd like the program's data to be stored on a heap, and I allow all of the closures to take in this heap as an argument in case it needs to allocate something, retrieve a value, etc. I'm okay if the closure code itself is dynamically allocated by Rust, but I want the pointers to the closures themselves to be in my <code>Heap</code> struct.</p>
  
  <p>I've tried storing the data as a function pointer (like <code>fn(usize, usize, &amp;mut Heap)</code>), as well as boxed closures (like <code>Box&lt;dyn FnMut(usize, &amp;mut Heap) -&gt; usize&gt;</code>), as well as a boxed pointer version with a lifetime argument (like <code>Box&lt;dyn FnMut(usize, &amp;mut Heap) -&gt; usize + 'a&gt;</code>) but I always seem to run into some issue with the borrow checker.</p>
  
  <p>Here is a simplified version of my code:</p>
  
  <pre><code>enum Val {
      Int(i32),
      Bool(bool),
      Lambda(Box&lt;dyn FnMut(usize, &amp;mut Heap) -&gt; usize&gt;),
  }
  
  struct Heap {
      mem: Vec&lt;Val&gt;,
  }
  
  impl Heap {
      fn alloc(&amp;mut self, v: Val) -&gt; usize {
          self.mem.push(v);
          self.mem.len() - 1
      }
  
      fn get(&amp;self, i: usize) -&gt; &amp;Val {
          &amp;self.mem[i]
      }
  }
  
  fn apply(func: usize, arg: usize, heap: &amp;mut Heap) -&gt; usize {
      let closure = match heap.get(func) {
          Val::Lambda(x) =&gt; x,
          _ =&gt; panic!(),
      };
      closure(arg, heap)
  }
  
  fn main() {
      let mut h = Heap { mem: vec![] };
  
      // creating a closure
      let foo = Val::Lambda(Box::new(|a: usize, mut heap: &amp;mut Heap| -&gt; usize {
          let a_val = match heap.get(a) {
              Val::Int(x) =&gt; *x,
              _ =&gt; panic!(),
          };
          heap.alloc(Val::Int(a_val * a_val))
      }));
      let f = h.alloc(foo);
  
      // using the closure
      let a = h.alloc(Val::Int(3));
      let b = apply(f, a, &amp;mut h);
      match h.get(b) {
          Val::Int(x) =&gt; println!("{}", x),
          _ =&gt; panic!(),
      };
  }
  </code></pre>
  
  <p><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=0caf1ebe71767409db0a9f30c27d6c1a" rel="nofollow noreferrer">Rust playground</a></p>
  
  <p>The above code should output 9, but instead there is a borrow-checker error:</p>
  
  <pre class="lang-none prettyprint-override"><code>error[E0596]: cannot borrow `**closure` as mutable, as it is behind a `&amp;` reference
    --&gt; src/main.rs:27:5
     |
  23 |     let closure = match heap.get(func) {
     |         ------- help: consider changing this to be a mutable reference: `&amp;mut std::boxed::Box&lt;dyn for&lt;'r&gt; std::ops::FnMut(usize, &amp;'r mut Heap) -&gt; usize&gt;`
  ...
  27 |     closure(arg, heap)
     |     ^^^^^^^ `closure` is a `&amp;` reference, so the data it refers to cannot be borrowed as mutable
  
  error[E0502]: cannot borrow `*heap` as mutable because it is also borrowed as immutable
    --&gt; src/main.rs:27:5
     |
  23 |     let closure = match heap.get(func) {
     |                         ---- immutable borrow occurs here
  ...
  27 |     closure(arg, heap)
     |     -------^^^^^^^^^^^
     |     |
     |     mutable borrow occurs here
     |     immutable borrow later used by call
  
  warning: variable does not need to be mutable
    --&gt; src/main.rs:34:47
     |
  34 |     let foo = Val::Lambda(Box::new(|a: usize, mut heap: &amp;mut Heap| -&gt; usize {
     |                                               ----^^^^
     |                                               |
     |                                               help: remove this `mut`
     |
     = note: #[warn(unused_mut)] on by default
  </code></pre>
  
  <p>Is it possible to clone my closures / enum to mitigate this borrowing issue? I am not sure if this is possible due to the restrictions on <a href="https://doc.rust-lang.org/std/clone/trait.Clone.html" rel="nofollow noreferrer"><code>Clone</code></a> listed by the Rust documentation:</p>
  
  <blockquote>
    <p>"Closure types, if they capture no value from the environment or if all such captured values implement <code>Clone</code> themselves. Note that variables captured by shared reference always implement <code>Clone</code> (even if the referent doesn't), while variables captured by mutable reference never implement <code>Clone</code>."</p>
  </blockquote>