Well, the equivalent of locked.deref_mut() would be &mut *locked, not &*locked (and you should use that one instead since it’s more idiomatic not to call the deref_mut() method manually).
As to why mutable access works here and immutable one doesn’t: Your type Bar doesn’t implement Sync. So &Bar cannot be sent between threads, but &mut Bar still can. The former requires Bar: Sync, the latter only Bar: Send in order to be safe to be sent between threads.
Now, why does this even matter, who could send &Bar between threads? It’s because at .await points, the process function may be sent to another thread by the async runtime of tokio, so all values of local variables or temporary variables that exist at that point must implement Send. This includes the &Foo or &mut Foo reference that you were matching on, and that is held in a temporary variable until the end of the match statement. In this case, arguably the compiler analysis on this matter is still overly cautions. After all, all that’s really being held onto is tx which only references the Sender<i32> which isSync, but as the Rust compiler follows the principle of better being too cautious than allowing safety to be circumvented in corner cases, we’ll have to live with the more cautions analysis of the compiler here and we can only hope for future improvements.