I'm trying to build a language interpreter. There is a requirement to maintain a symbol table of commands as part of the machine state. Commands themselves need to be able to add new commands to the symbol table.
What I have so far is as follows:
struct Machine<'a> {
    dict: HashMap<&'a str, Box<dyn Fn(&mut Machine) -> ()>>,
}
For the interpreter function to execute a command from the symbol table, I have (simplified):
fn exec(m: &mut Machine, instr: &str) {
    let f = m.dict.get(instr).unwrap();
    f(m);
}
This gives me a compiler error:
error[E0502]: cannot borrow `*m` as mutable because it is also borrowed as immutable
 --> src/mre.rs:9:5
  |
8 |     let f = m.dict.get(instr).unwrap();
  |             ----------------- immutable borrow occurs here
9 |     f(m);
  |     -^^^
  |     |
  |     mutable borrow occurs here
  |     immutable borrow later used by call
I'm aware why this is unsafe; after all the command is allowed to remove its
own entry from the symbol table. I think the correct way forward is to somehow
clone f before I use it, so that the borrow of m.dict can end before the
call to f.
Naively trying gives me:
fn exec(m: &mut Machine, instr: &str) {
    let f = (*m.dict.get(instr).unwrap()).clone();
    f(m);
}
error[E0599]: the method `clone` exists for struct `Box<dyn for<'r, 's> Fn(&'r mut Machine<'s>)>`, but its trait bounds were not satisfied
   --> src/mre.rs:8:43
    |
8   |       let f = (*m.dict.get(instr).unwrap()).clone();
    |               ----------------------------- ^^^^^
    |               |
    |               this is a function, perhaps you wish to call it
    |
   ::: /home/ari/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:74:1
    |
74  |   pub trait Fn<Args>: FnMut<Args> {
    |   -------------------------------
    |   |
    |   doesn't satisfy `dyn for<'r, 's> Fn(&'r mut Machine<'s>): Clone`
    |   doesn't satisfy `dyn for<'r, 's> Fn(&'r mut Machine<'s>): Sized`
    |
   ::: /home/ari/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:194:1
    |
194 | / pub struct Box<
195 | |     T: ?Sized,
196 | |     #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
197 | | >(Unique<T>, A);
    | |_- doesn't satisfy `_: Clone`
    |
    = note: the following trait bounds were not satisfied:
            `dyn for<'r, 's> Fn(&'r mut Machine<'s>): Sized`
            which is required by `Box<dyn for<'r, 's> Fn(&'r mut Machine<'s>)>: Clone`
            `dyn for<'r, 's> Fn(&'r mut Machine<'s>): Clone`
            which is required by `Box<dyn for<'r, 's> Fn(&'r mut Machine<'s>)>: Clone`
Box<T> implements Clone when T does.Closures are Clone when certain conditions are met, so this seems like a way forward, but I'm not sure exactly how.
What's the correct way to do this?
 
    