5 ms·
> For (2), Rust enforces this invariant via the borrow checker by disallowing (at compile-time) a shared slice reference that points to an overlapping mutable s
by loeg 10mo ago
> For (2), Rust enforces this invariant via the borrow checker by disallowing (at compile-time) a shared slice reference that points to an overlapping mutable slice reference.
At least the last time I cared about this, the borrow checker wouldn't allow mutable and immutable borrows from the same underlying object, even if they did not overlap. (Which is more restrictive, in an obnoxious way.)
- Cyph0n 10mo agoDo you mean borrows for different fields of a struct? If so, that’s handled today - it’s sometimes called “splitting borrows”: https://doc.rust-lang.org/nomicon/borrow-splitting.html https://doc.rust-lang.org/nomicon/borrow-splitting.html
- loeg 10mo agoNot exactly -- independent subranges of the same range (as would be relevant to something like memcpy/memmove/strcpy). E.g., https://godbolt.org/z/YhGajnhEG https://godbolt.org/z/YhGajnhEG It's mentioned later in the same article you shared above.
- Cyph0n 10mo agoGotcha. There is a split_at_mut method that splits a mutable slice reference into two. That doesn’t address the problem you had, but I think that’s best you can do with safe Rust.
- loeg 10mo agoYeah. It just isn't something the borrow checker natively understands.
- oneshtein 10mo agofn f() { let mut v = vec![1, 2, 3, 4, 5]; let (header, tail) = v.split_at_mut(1); b(&header[0], &mut tail[0]); }
- loeg 10mo agosplit_at_mut is just unsafe code (and sibling comment mentioned it hours before you did). The borrow checker doesn't natively understand that.
- Cyph0n 10mo agoIt is safe btw. The difference is that it returns two mutable references vs. one shared ref and one mutable ref. But as they noted, a mutable ref can always be “downgraded” into a shared ref.
- loeg 10mo agoThe implementation is unsafe, as I said: > split_at_mut is just unsafe code (and sibling comment mentioned it hours before you did). The borrow checker doesn't natively understand that. https://doc.rust-lang.org/src/core/slice/mod.rs.html#2086 https://doc.rust-lang.org/src/core/slice/mod.rs.html#2086
- Cyph0n 10mo agoNo, that’s the unchecked version. Two people are telling you that this method exists and is safe, so I am not sure why you’re still doubting this lol.
- bmandale 10mo agoThe checked variant just calls the unchecked, and the panicking variant calls the checked variant. They all need to call unsafe code. See here for details: https://doc.rust-lang.org/nomicon/borrow-splitting.html https://doc.rust-lang.org/nomicon/borrow-splitting.html
- Cyph0n 10mo agoThen you misunderstand what unsafe means in Rust. Every single Rust binary needs to eventually call unsafe code at some layer of the callstack. Is creating a TCP socket using stdlib functions unsafe? How about writing to a file? Or acquiring a mutex? I would suggest doing some more reading before chiming in here :)