Is there some more general rule here? I thing Result is probably the same: Return Result<&T, &E> instead of &Result<T, E> right? But for most types I think I'm supposed to a simple reference like &self.field. I'm unsure when to use that default rule, and when to use some more specialized rule.
Well, I'd say that if you really need to return a result with references, then I'd return a Result<&T, E> instead because there is no reason to keep a reference to the error, as at some point it would either be dropped (In case of execution change) or cause a panic (At which point dropping a String or a small error struct doesn't really matter)
lets you modify the option itself, so you can call take() on it, leaving None in the field, and the next call to option1_mut() will return None.
In contrast, option2_mut() only lets you modify the value inside the option, so every consecutive call to option2_mut() will return the same Option containing whatever value you set previously (or the original one, if you didn't actually modify it).
Choose wisely the option (unintentional pun) than makes sense for this particular field and this particular data structure that you're writing. For example, it makes sense to return a mutable reference to the option itself, if it's an optional configuration parameter that can be changed or "removed" any time. But it wouldn't in case of Vec::last_mut(), because that would mean that you could remove an element from a vector by calling last_mut(), which sounds crazy. Side note: it's actually slice::last_mut(), but you can call it on a Vec thanks to deref coercion.
I have to concur that Option<&T> is always better than &Option<T>.
For one thing, it's a bit more efficient. The &Option<T> gets represented as a pointer to the tagged union, while the Option<&T> gets optimized to a nullable pointer. Checking &Option<T> for None requires a deference, while checking Option<&T> for None can be done with just the comparison, and digging out the Some value is reduced from a pointer deference with an offset to just a deference with no offset.
For another thing, it's always possible to convert an &Option<T> into an Option<&T>, while it's impossible to go the other way. This means most other libraries expect Option<&T>, because they know it's the most flexible. This includes most of the built-in Option combinators.
And for cases where the type in the option also wants something other then &T (such as String)r is this the simplest way to make that conversion? Seems a bit long to me, but I couldn't find a better way that compiler liked.
The difference between &Option<T> and Option<&T> can be somewhat likened to the difference between &String and &str: the former can be turned into the latter, so if you want to give the caller maximum flexibility, your APIs should accept the latter and return the former (unless doing so would be impossible or inefficient, say because it would require an allocation).
Except that returning the former might be not possible in many cases, since there's no external Option<T> to start with. Did you mean that API should return owned value (such as String or Option<T>)?
Right, you should accept a String if you really need to mutate it, and you should return a &str if you don't have a String to return in the first place. My point is just that you shouldn't weaken those guarantees for no reason.
There's another reason, which is to enable changes in the underlying implementation. Maybe you'll find you want to change it to an Option<Rc<str>> or something.
It's hard for me to think of cases where returning &String or &Option<String> makes sense. The advantages of these types over &str and Option<&str> are so vanishingly small they might as well not exist! If you're willing to expose that much information, you might as well make the field public.