Well, while what you say is technically correct, it sounds like you're still confused, so let me explain:
First of all, you should stop thinking about moving and copying as two different things. I mean, yeah, when you talk about "moving vs copying" (like in this section of the book), then those are two opposite things, but when it comes to "& vs &mut vs move/copy" they're essentially the same, the only difference being whether the original value stays accesible after the move (for Copy types) or it doesn't (for non-Copy types). In most cases, the language treats them the same -- they even share the same syntax (this was not always the case -- it was deliberately added into the language).
With that out of the way, let's look at the closures again. There are two factors:
- Rust infers whether the closure needs to borrow an object immutably, borrow it mutably or move/copy it depending on what the closure does with it. This includes things like passing the object (or a reference to it) as an argument to some function, calling a method on it (because methods are just syntactic sugar for UFCS) or passing it to the future caller (i.e. returning it). This corresponds to your points 1)-3), but these are not separate rules! Rust looks at how the closure uses it and infers how to capture it, that's all. Oh and yeah, if it decides to move/copy it, then whether it'll be copied or moved (that is, whether the original value stays accessible) depends on its type, just like move/copy works in any every place -- but that's not specific to closures and captures.
- It does all of that unless you specify the
movekeyword, which always forces move/copy, no matter how the closure uses the object.
The original binding does play a part, but not in a way you might expect. If, say, in the original binding obj is not an Object itself, but just an &Object reference, then what I described above applies to the obj, not the *obj. It can decide to borrow or move/copy obj, but not the *obj. That's okay, because you "cannot move out of borrowed content" anyway.
Yes, most of the time Rust does the right thing by default. The only reason to override it is when it is enough for the closure to take a reference (either mutable or immutable), but you don't want the closure to take any references (because you need it to be 'static), so you explicitly tell Rust to move/copy everything by using the move keyword -- but again, this is a rare case.
(In fact, there is a super-rare case where you want to force some of the environment to be moved/copied, but leave the rest borrowed -- and as far as I know, this is impossible to achieve in Rust. This need can arise, for example, with so-called scoped threads; I've cooked up an example here: Rust Playground)