I am starting to learn Rust, and while experimenting, I have found a difference in how ownership is applied to tuples and arrays I do not understand. Basically, the following code shows the difference:
#![allow(unused_variables)]
struct Inner {
in_a: u8,
in_b: u8
}
struct Outer1 {
a: [Inner; 2]
}
struct Outer2 {
a: (Inner, Inner)
}
fn test_ownership(num: &mut u8, inner: &Inner) {
}
fn main() {
let mut out1 = Outer1 {
a: [Inner {in_a: 1, in_b: 2}, Inner {in_a: 3, in_b: 4}]
};
let mut out2 = Outer2 {
a: (Inner {in_a: 1, in_b: 2}, Inner {in_a: 3, in_b: 4})
};
// This fails to compile
test_ownership(&mut out1.a[0].in_a, &out1.a[1]);
// But this works!
test_ownership(&mut out2.a.0.in_a, &out2.a.1);
}
The first invocation of test_ownership() does not compile, as expected Rust emits an error complaining about taking both a mutable and immutable reference to out1.a[_].
error[E0502]: cannot borrow `out1.a[_]` as immutable because it is also borrowed as mutable
--> src/main.rs:27:41
|
27 | test_ownership(&mut out1.a[0].in_a, &out1.a[1]);
| -------------- ------------------- ^^^^^^^^^^ immutable borrow occurs here
| | |
| | mutable borrow occurs here
| mutable borrow later used by call
But the thing I do not understand, is why the second invocation of test_ownership() does not make the borrow checker go nuts? It seems as if arrays are considered as a whole independently of the indexes being accessed, but tuples allow multiple mutable references to their different indexes.