I found a few things a little difficult. First, the compiler is not actually as smart / accepting of valid borrow patterns as should abstractly be possible. Things like borrowing different subfields of a struct in different and nonconflicting ways to different subroutines. This got a lot better in recent memory with non-lexical lifetimes but I think is still a problem.
Two: splitting mut borrows. It’s reasonable to take a mut borrow of some resource and divide it into two independent borrows of exclusive components. Think non-overlapping subarrays, or independent struct members. The language does not really provide this for you, but it is safe. (There are some APIs like this but last time I checked they didn’t cover all usecases.)
Structs containing a borrow are just weird and annoying to work with. Lifetime parameterization everywhere is verbose and it’s difficult to determine where you’ve made a mistake. The syntax for describing lifetime relationships is non-obvious to me.
let (first_42, rest) = mutable_slice.split_at_mut(42);
but you can see that the inner logic is just a bit of pointer twiddling[2]
let len = self.len();
let ptr = self.as_ptr();
// SAFETY: Caller has to check that `0 <= mid <= self.len()`
unsafe { (from_raw_parts(ptr, mid), from_raw_parts(ptr.add(mid), len - mid)) }
Tl;dr Rust can't distinguish between a `Vec` whose length is mutable (which might need to reallocate) and one whose elements are mutable (which can provide mutable references to its elements but will never have to move them), so it prevents mutation in a case where it would be safe.
Two: splitting mut borrows. It’s reasonable to take a mut borrow of some resource and divide it into two independent borrows of exclusive components. Think non-overlapping subarrays, or independent struct members. The language does not really provide this for you, but it is safe. (There are some APIs like this but last time I checked they didn’t cover all usecases.)
Structs containing a borrow are just weird and annoying to work with. Lifetime parameterization everywhere is verbose and it’s difficult to determine where you’ve made a mistake. The syntax for describing lifetime relationships is non-obvious to me.