fn test1(_: &mut String) {
}
fn test2<T>(_: T) {
}
// OK Pattern1
let mut a = "hoge".to_string();
let mut b = &mut a;
test1(b);
println!("{}", b);
// OK Pattern2
let mut a = "hoge".to_string();
let mut b = &mut a;
test2::<&mut String>(b);
println!("{}", b);
// NG Pattern
let mut a = "hoge".to_string();
let mut b = &mut a;
test2(b); // 'b' moved here
println!("{}", b); // "Error" because `b` after moved
Why does 'b' lose its ownership in NG Pattern?
In test2(), the compiler seems to infer T as '&mut String', so I thought test2() was borrowing 'b'.
In test1(), the compiler sees a &mut and inserts a reborrow on the call, as an exception to the normal rule, since that is usually what is meant when a function takes a &mut reference. That doesn't apply when you have a generic, since it could be called with something that isn't &mut and the special case there would create an inconsistency with what happens in other instantiations of the generic, so test2() always takes ownership. Since &mut is not Copy, that means b can't be used afterwards. The solution would be to insert an explicit extra borrow or reborrow of b on the call of test2().
It is borrowing a. The error message isn't about moving a, it's about moving b, which does indeed happen. The mutable rererence itself is being moved to test2.