Skip to content

Polonius

Sewen Thy edited this page Oct 23, 2022 · 2 revisions

Non-lexical lifetimes (NLL)

More details.

Scope refers to the lifetime of a value, corresponding to the span of time before that value gets freed (or, put another way, before the destructor for the value runs). This describes how long a value is valid. Lifetime refers to the lifetime of a reference, corresponding to the span of time in which that reference is used.

Polonius

The output from nll-facts are the details resulting from analyzing the control flow-graph generated by the MIR. Polonius considers NLL facts and determine a named lifetime 'a as a set of loans that are active rather than the points representation in the NLL analysis. Specifically:

  • Instead of interpreting the 'a notation as the lifetime of a reference (i.e., a set of points), we interpret 'a as a set of loans. We refer to 'a as a "region" in order to emphasize this distinction.
  • We call 'a: 'b a subset relation; it means that the loans in 'a must be a subset of the loans in 'b. We track the required subset relations at each point in the program. (source)

With this then there are currently 2 main errors, region errors, and subset errors.

Region Errors

This is how polonius calculate region subset error (more details):

.decl subset_error(R1: region, R2: region, P:point)

subset_error(R1, R2, P) :-
  subset_placeholder(R1, R2, P), // `R1: R2` required at `P`
  placeholder_region(R2), // `R2` is also a placeholder
  !known_subset(R1, R2).  // `R1: R2` is not a "known subset" relation.

Informal repair solution: So when i get a subset, I need to propagate the R1: R2 constraints through the points within the CFG and then annotate the borrow point for loan region R1 with a named lifetime 'a and the other borrow point for loan region R2 with lifetime 'b.

Liftime problems that are detected before borrow checking

Output reference lifetime

Unfortunately, there are extraction errors such as this toy example on different in/out lifetimes where the extracted method does not have an output annotation. This means the compiler will simply throw an error [E0106] and not dump the nll-facts. For these I currently have no way to analyze except to simply copy-paste the help section.

$ [[rustc -Znll-facts in_out_lifetimes.rs 
error[E0106]: missing lifetime specifier
  --> in_out_lifetimes.rs:33:52
   |
33 | fn bar_extracted(x_ref: &i32, z: &i32, y: &i32) -> &i32 {
   |                         ----     ----     ----     ^ expected named lifetime parameter
   |
   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x_ref`, `z`, or `y`
help: consider introducing a named lifetime parameter
   |
33 | fn bar_extracted<'a>(x_ref: &'a i32, z: &'a i32, y: &'a i32) -> &'a i32 {
   |                 ++++         ++          ++          ++          ++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0106`.

Clone this wiki locally