rust-lang/project-rfc-2229

Improve diagnostics for Precise Capture

Closed this issue · 0 comments

Currently, we store and report back only one expression for why a particular path is captured and how the path is captured. We prioritize how the path is captured (i.e on the CaptureKind -- ByValue/ByRef). This works today since the root variable is captured in entirety, however won't result in good diagnostics once the feature is complete.

Consider the following example

let p = Point { x: 10, y: 10 };

let c = || {
    p.x      += 10;
//  ^ E1 ^
    println!("{:?}",  p);
//                  ^ E2 ^
};

Here the result of the capture analysis is p is borrowed by a MutBorrow. This is because E1 force the MutBorrow and E2 forces the path p.

By storing only one piece of information currently E1 (since we prioritize the capture kind) in diagnostics can't express all the information a user might need to fix their code.

We need to update CaptureInformation (rustc_middle/src/ty/mod.rs) to contain two expression ids (capture_kind_expr_id, path_expr_id). We then use this to emit two notes.

let mut p = Point { x: 10, y: 10 };

let c = || {
    p.x      += 10;
//  ^ mutable borrow of `p` happens here
    println!("{:?}",  p);
//                    ^ `p` is captured since it's used here.
};

In case both the capture_kind_expr_id and path_expr_id are the same we only emit one-note similar to how we do it today.

let mut p = Point { x: 10, y: 10 };

let c = || {
    p  = Point { ... } ;
//  ^ mutable borrow of `p` happens here
};