A way to think of it is that since option is a mutable referense, as long as it is in scope, you have the ability to mutate self.info through it. For real code, I recommend the way @vitalyd mentions. But for playing around, you can try to limit the scope of it. Maybe a bit ugly like this:
fn define(&mut self, ability: &'a str, role: &'a str) {
{
let option = self.info.get_mut(ability);
if option.is_some() {
let roles = option.unwrap();
roles.push(role)
return;
}
} // this ends the block containing option
// So this should work:
self.info.insert(ability, vec![role]);
}
What's nice about the Entry API is that not only does it sidestep the lexical lifetime issue, it's also a nice ergonomic one-liner. So from an educational perspective, it's good to understand the issue (or current limitation, really), but otherwise just use the Entry.