This article says that the borrow checker doesn't look past functions signatures because of compiler performance. I strongly disagree. The reason is to avoid coupling. If it did, you couldn't swap 2 functions with the same signature because their implementation would have a different borrowing pattern. Very bad.
(Although we're a bit there with functions returning an impl)
It's a bit of both IIRC. You're right that limiting checks to the function signature avoids accidentally leaking implementation details, but it also means that checking functions can be done entirely locally. Not having to recursively inspect called function implementations to determine whether there is a type/borrow checking error scales much worse than only needing to look at function signatures.
(Although we're a bit there with functions returning an impl)