Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.



> There are some APIs like this but last time I checked they didn’t cover all usecases.

This refers to[1]

    <&mut [T]>::split_at_mut(usize) -> (&mut [T], &mut [T])`
used as

    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)) }

[1]: https://doc.rust-lang.org/std/primitive.slice.html#method.sp...

[2]: https://doc.rust-lang.org/src/core/slice/mod.rs.html#1641-16...


Yes, exactly. I was using this for zero-copy serialization into a buffer. At the time, I don’t believe that API had been stabilized yet.


That method has been around since 1.0 (as documented in the source code). Were you using Rust before 2015? If so, a lot has changed :)


No, post-1.0. I don't remember exactly why I had to roll my own with unsafe, but it was essentially the same thing.


For someone looking for an example of this, here's a SO post: https://stackoverflow.com/questions/74592882/extend-a-string...

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.


Isn't the latter just a mutable slice?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: