2

Let's say I want to swap the first and third items of a vector using a bit-twiddling hack:

fn main() {
    let mut v = vec![0, 1, 2, 3, 4, 5, 6, 7];

    {
        let first_item = &mut v[0];
        let third_item = &mut v[2];
        *first_item ^= *third_item;
        *third_item ^= *first_item;
        *first_item ^= *third_item;
    }

    println!("{:?}", v);
}

Rust doesn't like this:

   Compiling mcve v0.0.0 (/home/wizzwizz4/rust/mcve)
error[E0499]: cannot borrow `v` as mutable more than once at a time
 --> src/main.rs:6:31
  |
5 |         let first_item = &mut v[0];
  |                               - first mutable borrow occurs here
6 |         let third_item = &mut v[2];
  |                               ^ second mutable borrow occurs here
7 |         *first_item ^= *third_item;
  |         -------------------------- first borrow later used here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0499`.
error: Could not compile `mcve`.

To learn more, run the command again with --verbose.

That's fine, because I only really want to change v[0]:

fn main() {
    let mut v = vec![0, 1, 2, 3, 4, 5, 6, 7];

    {
        let first_item = &mut v[0];
        *first_item = v[2];
    }

    println!("{:?}", v);
}

I'm stuck again:

   Compiling mcve v0.0.1 (/home/wizzwizz4/rust/mcve)
error[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
 --> src/main.rs:6:23
  |
5 |         let first_item = &mut v[0];
  |                               - mutable borrow occurs here
6 |         *first_item = v[2];
  |         --------------^---
  |         |             |
  |         |             immutable borrow occurs here
  |         mutable borrow later used here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.
error: Could not compile `mcve`.

To learn more, run the command again with --verbose.

The thing is, I know that both of those borrows are from different parts of the vector. Specifically, I know that the first index is <= 1, and the second index is > 1.

How do I tell the Rust compiler this?

wizzwizz4
  • 6,140
  • 2
  • 26
  • 62
  • How am I _so bad at searching‽_ What is this, the third duplicate this week? – wizzwizz4 Jun 26 '19 at 13:04
  • Granted, the site's search engine isn't very good. If you're searching on SO directly, I would recommend trying another search engine (Duck Duck Go or Google). – E_net4 Jun 26 '19 at 13:07
  • *I want to swap the first and third items of a vector* — [`swap`](https://doc.rust-lang.org/std/primitive.slice.html#method.swap) – Shepmaster Jun 26 '19 at 13:08
  • @Shepmaster This was merely a MCVE. It's the first that occurred to me… and also to the writer of the duplicate question, unsurprisingly. – wizzwizz4 Jun 26 '19 at 13:09
  • I have `r foo` as a quick search in Firefox bound to `https://www.google.com/search?q=site:stackoverflow.com rust foo`. In [this case](https://www.google.com/search?q=site:stackoverflow.com%20rust%20How%20can%20I%20take%20two%20mutable%20borrows%20from%20different%20parts%20of%20a%20vector), your question is first (exact match and all that), The next results ([1](https://stackoverflow.com/q/48420218/155423); [2](https://stackoverflow.com/q/30073684/155423); [3](https://stackoverflow.com/q/26409316/155423); [4](https://stackoverflow.com/q/25531963/155423)) are all valid. – Shepmaster Jun 26 '19 at 13:18
  • @Shepmaster Same with DDG… Never mind; I'm just bad at searching. – wizzwizz4 Jun 26 '19 at 13:24

0 Answers0