Function rustc_typeck::check::upvar::determine_capture_info[][src]

fn determine_capture_info<'tcx>(
    capture_info_a: CaptureInfo<'tcx>,
    capture_info_b: CaptureInfo<'tcx>
) -> CaptureInfo<'tcx>
Expand description

Helper function to determine if we need to escalate CaptureKind from CaptureInfo A to B and returns the escalated CaptureInfo. (Note: CaptureInfo contains CaptureKind and an expression that led to capture it in that way)

If both CaptureKinds are considered equivalent, then the CaptureInfo is selected based on the CaptureInfo containing an associated capture_kind_expr_id.

It is the caller’s duty to figure out which path_expr_id to use.

If both the CaptureKind and Expression are considered to be equivalent, then CaptureInfo A is preferred. This can be useful in cases where we want to priortize expressions reported back to the user as part of diagnostics based on which appears earlier in the closure. This can be achieved simply by calling determine_capture_info(existing_info, current_info). This works out because the expressions that occur earlier in the closure body than the current expression are processed before. Consider the following example

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

let c = || {
    p.x     += 10;
// ^ E1 ^
    // ...
    // More code
    // ...
    p.x += 10; // E2
// ^ E2 ^
};

CaptureKind associated with both E1 and E2 will be ByRef(MutBorrow), and both have an expression associated, however for diagnostics we prefer reporting E1 since it appears earlier in the closure body. When E2 is being processed we would’ve already handled E1, and have an existing capture_information for it. Calling determine_capture_info(existing_info_e1, current_info_e2) will return existing_info_e1 in this case, allowing us to point to E1 in case of diagnostics.