Skip to content
This repository was archived by the owner on Apr 5, 2024. It is now read-only.
This repository was archived by the owner on Apr 5, 2024. It is now read-only.

Improve logging of capture analysis #19

Closed
rust-lang/rust
#78801
@arora-aman

Description

@arora-aman

Discussion happened here:

Capture analysis happens in two passes:

  1. Collecting information about each place, i.e. the CaptureKind (ByValue/ByRef) and the expression that led to such capture.
  2. Minimum capture analysis, where we find the set of the smallest set of Places (and associated CatureKind) that need to be captured to meet the same requirements as collected by 1.

If we take an example

let s: String;  // hir_id_s
let mut p: Point; // his_id_p  
let c = || {
       println!("{}, s");  // L1
       p.x += 10;  // L2
       println!("{}" , p.y) // L3
       println!("{}, p) // L4
       drop(s);   // L5
};

After 1. the structure we will have is:

{
      Place(base: hir_id_s, projections: [], ....) -> (L5, ByValue),
      Place(base: hir_id_p, projections: [Field(0, 0)], ...) -> (L2, ByRef(MutBorrow))
      Place(base: hir_id_p, projections: [Field(1, 0)], ...) -> (L3, ByRef(ImmutBorrow))
      Place(base: hir_id_p, projections: [], ...) -> (L4, ByRef(ImmutBorrow))

After 2

{
      hir_id_s -> [
           Place(base: hir_id_s, projections: [], ....) -> (L4, ByValue)
      ],
      hir_id_p -> [
           Place(base: hir_id_p, projections: [], ...) -> (L2, ByRef(MutBorrow)),
       ]

The structures in reality look a bit more complex. We want to print them out to stderr in a nicer fashion.

What should the output look like

The Place can be printed as <variable_name>[<projecitons>], where projections is a comma-separated list of pretty printed projection kinds.

Deref -> Deref
Field(u32, VariantIndex) -> (x.y); where x corresponds to u32, y corresponds to VariantIndex
Index -> Index
Subsclice -> Subsclice

For each capture, we want to throw an error at the expression that resulted in the capture along with the Place and the CaptureKind.

let s: String;
let mut p: Point;
let c = || {
       println!("{}, s");
       p.x += 10;
       // ^ ERROR: Capturing p[(0.0)] -> MutBorrow
       println!("{}" , p.y);
       // ^ ERROR: Capturing p[(1.0)] -> ImmBorrow
       println!("{}", p);
       // ^ ERROR: Capturing p[] -> ImmBorrow
       drop(s);
       // ^ ERROR: Capturing s[] -> ByValue
};

When this gets extended to min capture

let c = || {
       println!("{}, s");
       p.x += 10;
       // ^ ERROR: Capturing p[(0.0)] -> MutBorrow
       // ^ ERROR: MinCapture p[] -> MutBorrow
       println!("{}" , p.y);
       // ^ ERROR: Capturing p[(1.0)] -> ImmBorrow
       println!("{}", p);
       // ^ ERROR: Capturing p[] -> ImmBorrow
       drop(s);
       // ^ ERROR: Capturing s[] -> ByValue
       // ^ ERROR: MinCapture s[] -> ByValue
};

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions