You copied the Function<'a> out from behind the &'b Function<'a>.
fn get_function<'b>(&'b mut self, fun_name: &str) -> Result<Function<'a>, ()> { // line 1
self.program // &'b HashMap<&'a str, Function<'a>>
.get(fun_name) // Option<&'b Function<'a>>
.map(|f| *f) // Option<Function<'a>>
.ok_or(()) // Result<Function<'a>, ()>
}
The copy is the key. Here's a more fundamental demonstration:
fn copy_inner_shared_ref<'a: 'b, 'b, T: ?Sized>(r: &'b &'a T) -> &'a T {
*r
}
fn copy_inner_shared_ref_mut<'a: 'b, 'b, T: ?Sized>(r: &'b mut &'a T) -> &'a T {
*r
}
&mut on the other hand is not Copy. (Sometimes it seems like it, but you're really performing a reborrow, which is its own large topic.) Because of this, you can't move a &'long mut T from outside a &'short mut &'long mut T, unless you have something to replace the &'long mut T with.
In this case, your &'a mut self is a &'a mut Context<'a>. Anything inside a &mut -- here, Context<'a> -- is invariant. That means that the lifetimes within cannot be coerced to be shorter. The net result is that a &'a mut Context<'a> causes the Context<'a> to be mutably -- that is, exclusively -- borrowed for its entire remaining validity period. You can't use the Context<'a> ever again, except through something derived from that &'a mut -- like the return value of get_function. You can't move it, you can't borrow it again, and if you had a non-trivial destructor you wouldn't be able to call that either (meaning your code just wouldn't compile even without the second call attempt).
For this reason, &'a mut Thing<'a> is a red flag. It has extremely niche practical application and is pretty much never what you want.
You don't need the &'a mut to copy out a Function<'a>, and the problems with &'a mut Context<'a> are independent of that -- just creating &'a mut Context<'a> causes the difficulties, no matter what you do or don't do with it.
Bonus section!
&'a Context<'a> is covariant in Context<'a>, which is what you're probably more use to (even if you're not conscious of it) -- the lifetime can be coerced or reborrowed as a shorter lifetime. It's usually more forgiving because if Context<'a> is covariant in 'a (it is), then a &'long Context<'long> can generally be coerced to a &'short Context<'short>. However it is still technically over-restrictive and you should use &Context<'a>. And your example is actually a demonstration of when this can matter! Because you first go through a &mut Context<'a> -- even if it's not a &'a mut Context<'a> -- the 'a in Context<'a> is invariant. So subsequently calling a method requiring a &'a Context<'a> is only possible if you had started with a &'a mut Context<'a>, and this version of your example still does not compile.
Unfortunately there is no comprehensive lifetime documentation. Here's a recent thread on the topic and meta-topic.