3 ms·
I don’t know Rust, just wondering: why is it forbidden to know a length of vector to which you hold a mutable reference? What could go wrong?
by nlitened 4y ago
I don’t know Rust, just wondering: why is it forbidden to know a length of vector to which you hold a mutable reference? What could go wrong?
- scoutt 4y agoI imagine you can have one thread modifying the vector while trying to read its length from another thread.
- ArrayBoundCheck 4y agoNoone should imagine that. You definitely don't want two threads accessing the same vec or array at one time. Maybe if there's a lock
- nickitolas 4y agoIf it's read only, you can definitely want that, right? As long as the elements are Sync. And it should work (You might have a problem with the cleanup, but Arc or scoped threads should handle that). The problem is when one is a mutable reference, like in this case. AIUI you could have a single mutable reference to an element be used from another thread (For example, a scoped thread) if the elements of the Vec are Sync
- masklinn 4y agoThe problem is not “a length of a vector”, Rust is not that fine grained. As far as Rust is concerned, what can happen is that you acquire an immutable reference to an object while there’s a mutable (unique) reference outstanding, you can invalidate the immutable reference via the mutable one, and thus have a dangling reference, which is UB. Hell, even here one could imagine two scoped threads (so they can work with references), one thread keeps modifying the vector, and on some ISAs the other might get torn values for the length, or possibly worse (I don’t know if worse is an option but I wouldn’t be surprised).
- suremarc 4y agoOP is just holding a reference to a single entry in the vector. You could write whatever you want to that entry, but it's not going to change the length of the vector. In some sense the problem is that Rust is not "fine grained" enough to figure out that OP's access pattern is valid.
- nickitolas 4y agoIt's not just about that. What rust sees is you are calling two functions: the len() function with a shared reference, and the indexing operator implementation for the Vec's [] (Which is just a function) with a mutable reference, which returns a mutable reference. The compiler does not look at the actual implementation of these 2 functions to figure things out, it only looks at the signatures (If it did look at the implementations, it would probably be slower, and what's worse, the caller's code could stop compiling if you change the implementation! That would be specially bad across a library boundary). The implementations are irrelevant AIUI to the borrow checker, only the signatures matter.