The borrow checker works on "struct granularity", but it would be much more flexible and convenient if borrowing would work on memory location granularity (for instance passing a struct reference into a function "taints" the entire struct as borrowed, even if that function only accesses a single item in the borrowed struct - this 'coarse borrowing' restriction then may lead to all sorts of workarounds to appease the compiler, from 'restructuring' your structs into smaller pieces (which then however may fit one borrowing situation, but not another), or using 'semantic crutches' like Rc, Cell or Box.
There are also related restrictions about function call barriers. AFAIK the Rust compiler cannot "peek into" called function bodies to figure out what's actually going on inside those functions (and that information would be very valuable for fine-grained borrow checking), it can only work with the information in the function signature.
Again, disclaimer: take this with a grain of salt since I'm not a daily Rust user, but this is how I understood why Rust feels so restrictive.