title: return a closure that mutates its environment
body: <p>I'm writing a simple program that walks a directory, reading its entries and producing a JSON structure. I ran into trouble when I tried to return a closure that mutates a captured <code>&amp;mut Vec</code> parameter:</p>
  
  <pre><code>use std::io;
  use std::fs::{self, DirEntry,};
  use std::path::Path;
  
  extern crate rustc_serialize;
  use rustc_serialize::json;
  
  
  // json encoding: 
  #[derive(Debug, RustcEncodable)]
  struct Doc {
      path: String,
      filename: String,
  }
  
  
  fn main() {
      let target_path = Path::new("/Users/interaction/workspace/temp/testeddocs");
      let mut docs: Vec&lt;Doc&gt; = Vec::new();
  
      fn create_handler(docs: &amp;mut Vec&lt;Doc&gt;) -&gt; &amp;FnMut(&amp;DirEntry) {
          let handler = |entry: &amp;DirEntry| -&gt; () {
              let doc = Doc {
                  path: entry.path().to_str().unwrap().to_string(),
                  filename: entry.file_name().into_string().unwrap(),
              };
              docs.push(doc);
          };
  
          &amp;handler
      }
      {
          let handler = create_handler(&amp;mut docs);
          visit_dirs(&amp;target_path, &amp; |entry: &amp;DirEntry|{
              handler(entry);
          });
      }
      println!("result json is: {}", json::encode(&amp;docs).unwrap());
  }
  
  // one possible implementation of walking a directory only visiting files
  fn visit_dirs(dir: &amp;Path, cb: &amp;Fn(&amp;DirEntry)) -&gt; io::Result&lt;()&gt; {
      if try!(fs::metadata(dir)).is_dir() {
          for entry in try!(fs::read_dir(dir)) {
              let entry = try!(entry);
              if try!(fs::metadata(entry.path())).is_dir() {
                  try!(visit_dirs(&amp;entry.path(), cb));
              } else {
                  cb(&amp;entry);
              }
          }
      }
      Ok(())
  }
  </code></pre>
  
  <p>here's the compiler error it gives:</p>
  
  <pre class="lang-none prettyprint-override"><code>error: cannot borrow immutable borrowed content `***handler` as mutable
  --&gt; src/main.rs:36:13
     |
  36 |             handler(entry);
     |             ^^^^^^^
  
  error[E0373]: closure may outlive the current function, but it borrows `docs`, which is owned by the current function
  --&gt; src/main.rs:23:23
     |
  23 |         let handler = |entry: &amp;DirEntry| -&gt; () {
     |                       ^^^^^^^^^^^^^^^^^^^^^^^^ may outlive borrowed value `docs`
  ...
  28 |             docs.push(doc);
     |             ---- `docs` is borrowed here
     |
  help: to force the closure to take ownership of `docs` (and any other referenced variables), use the `move` keyword, as shown:
  |         let handler = move |entry: &amp;DirEntry| -&gt; () {
  
  error: `handler` does not live long enough
  --&gt; src/main.rs:31:10
     |
  31 |         &amp;handler
     |          ^^^^^^^ does not live long enough
  32 |     }
     |     - borrowed value only lives until here
     |
  note: borrowed value must be valid for the anonymous lifetime #1 defined on the block at 22:64...
  --&gt; src/main.rs:22:65
     |
  22 |     fn create_handler(docs: &amp;mut Vec&lt;Doc&gt;) -&gt; &amp;FnMut(&amp;DirEntry) {
     |
  </code></pre>