Created
December 4, 2017 19:47
-
-
Save nikomatsakis/ed89304174dd607d887bc10a35e30ab7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn main() { | |
let mut x = 22; | |
let p = &x; | |
x += 1; | |
println!("{:?}", p); | |
println!("{:?}", x); | |
} | |
// error[E0506]: cannot assign to `x` because it is borrowed | |
// --> /home/nmatsakis/tmp/spastorino1.rs:4:5 | |
// | | |
// 3 | let p = &R x; | |
// | -- borrow of `x` occurs here | |
// 4 | x += 1; // <-- point Q where error occurs is a member of R | |
// | ^^^^^^ assignment to borrowed `x` occurs here | |
// 5 | println!("{:?}", p); // <-- point R | |
// | - borrow of `x` later used here | |
// | |
// error: aborting due to previous error | |
// In the borrow checker, we go to report an error. We know the following | |
// information: | |
// | |
// - the borrow that is in scope (in this case: &x on line 3) | |
// - the region of that borrow (R) | |
// - the point where the illegal action occurred (Q) | |
// | |
// We need to know: | |
// | |
// - some other point that tells the user why the borrow is live at Q | |
// | |
// To find that out, we can use the cause information to learn why Q is a member | |
// or R. It will give us a chain of `Cause::Outlives` that terminates in a | |
// `Cause::LiveVar(p, Q)`, thus indicating that Q is a member of R because | |
// `p` is live at `Q`. | |
// | |
// That's not quite enough to show the user what we want. We then need to find | |
// out why `p` is live at Q. We can do that with a depth-first search, looking | |
// for a use of `p` *before* we reach an assignment to `p`. This will tell us that | |
// `p` is used at R. | |
// | |
// Now we can put the label on the span of R and say "borrow of `x` later used here". | |
// Once that works, we can add more fun: | |
// | |
// fn main() { | |
// let mut x = 22; | |
// let p = &x; | |
// let p2 = p; | |
// x += 1; | |
// println!("{:?}", p2); | |
// println!("{:?}", x); | |
// } | |
// | |
// probably wants to print something like | |
// | |
// error[E0506]: cannot assign to `x` because it is borrowed | |
// --> /home/nmatsakis/tmp/spastorino1.rs:4:5 | |
// | | |
// 3 | let p = &R x; | |
// | -- borrow of `x` occurs here | |
// 4 | let p2 = p; | |
// 5 | x += 1; // <-- point Q where error occurs is a member of R | |
// | ^^^^^^ assignment to borrowed `x` occurs here | |
// 6 | println!("{:?}", p2); // <-- point R | |
// | -- borrow of `x` later used here |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment