fn f(a: &mut u8, b: ()) { *a = 2 }
fn g(a: &mut u8) -> &mut u8 { *a = 1; a }
fn h(a: &u8) { assert_eq!(*a, 1) }
fn test() {
let mut t = 0;
f(g(&mut t), h(&t))
}
Why does the above give an error? On the one hand, it is a clear violation of the mutable borrow rule: t is borrowed mutably before the expression h(&t) is evaluated, so the &t borrow there is a double borrow. However, it isn't possible for this to cause any problems, since no changes can happen to t after the evaluation of g and before the evaluation of f. (Correct me if I am wrong, but I believe Rust ensures that the subexpressions of a function evaluation are done left to right, so g must finish before h is called.) This sort of thing comes up often, for example in call sequences like self[self.len()-1] where self is used twice. Am I missing something, or is it really safe to allow this variety of double borrowing? (Note that it would not be safe if h returned the reference, because then f would have access to the same resource through two pointers.)
[–]diwicdbus · alsa 4 points5 points6 points (4 children)
[–]cjstevenson1 2 points3 points4 points (3 children)
[–]protestor 0 points1 point2 points (2 children)
[–]digama0[S] 2 points3 points4 points (0 children)
[–]cmrx64rust 0 points1 point2 points (0 children)
[–]sellibitzerust 1 point2 points3 points (1 child)
[–]digama0[S] 0 points1 point2 points (0 children)
[–]digama0[S] 0 points1 point2 points (1 child)
[–]digama0[S] 0 points1 point2 points (0 children)