The problem with having the compiler figure it out is that the signature now becomes dependent on implementation details that can't be seen from the signature, and could be accidentally changed. This information must be an explicit part of the signature, so that it's properly visible and spells out what the function can do without having to read the body.
That said, I think putting it in the argument list like that is a terrible idea. It would add far too much clutter. What if it was put into the where section, sort of like this:
impl Foo {
fn bar(&mut self, other_param: &Data)
where self: borrows{ a, b, .. },
other_param: borrows{ a, b, ..},
{
// Function body
}
}
In one sense, it sort of fits because it's providing a "bounds" of sorts on how the reference can be used, similar to the way a trait bound would for a type. If no reference binding is provided it would default to borrowing all the fields, which is the current behaviour.