In something_cannot_pass_compile, foo is a local variable.
Therefore, a reference to it cannot outlive the scope of the function.
But the bar function specifies that F: FnMut() + 'a. which means that the closure must live as 'a. But the f being passed in lives only as long as the scope of something_cannot_pass_compile. Hence this lifetime cannot be constrained.
Let's look at it from the perspective of the function writers, where the rest of the code is just some API they've been given. It will be more clear if we give better, non-overlapping names to the lifetimes.
struct Bar<'bar> {
phantom: PhantomData<&'bar ()>
}
// Note that everything called `'bar` here is the _same_ lifetime
impl<'bar> Bar<'bar> {
fn bar<F: FnMut() + 'bar>(&mut self, f: F) {}
}
fn scope<'scope, F: FnOnce(&mut Bar<'scope>)>(f: F) {}
fn something_cannot_pass_compile<'bar>(mut bar: Bar<'bar>) { /* ... */ }
In something_can_pass_compile, the writer of the function gets to choose the lifetime used. scope is declared in a way that says it can handle any lifetime 'scope that the caller chooses. The implication is that they will create a Bar with the lifetime the caller chooses, then call the closure with that Bar. As written, the author implicitly chooses some lifetime that cannot exceed the local lifetime, due to the use of the local variable foo. If you change the call to explicitly use scope::<'static>, it will fail.
In something_cannot_pass_compile, the writer of the function does not choose the lifetime 'bar. 'bar is a type parameter of the function, and by writing it as such, they have declared they can handle any lifetime 'bar handed to them by the caller, in the form of a Bar<'bar>. But this is not true as written -- the use of Bar<'bar>::bar requires a FnMut() + 'bar, yet as before foo cannot outlive the local lifetime. That is,
scope can handle any 'scope, but Bar<'bar>::bar can only handle a specific 'bar
'bar is not a type parameter on the method bar
can_pass gets to choose the lifetime, but cannot_pass is handled a pre-determined lifetime
If I hand you a Bar<'static>, it must fail just like scope::<'static> must fail. Since you said you could handle any lifetime, the fact that you can't handle 'static is an error.
With @RedDocMD's patch, Bar<'bar>::bar can handle any lifetime, similar to scope. The closure is no longer limited to 'bar. cannot_pass is still handed a pre-determined lifetime in the form of Bar<'bar>, but it doesn't matter when calling Bar<'bar>::bar locally any more -- they can call Bar<'bar>::bar with a closure that has any lifetime at all.