Skip to content

Commit

Permalink
analyze: rewrite::expr: add examples to unlower and distribute doc co…
Browse files Browse the repository at this point in the history
…mments
  • Loading branch information
spernsteiner committed May 18, 2023
1 parent e6a19e6 commit 02553d4
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
16 changes: 16 additions & 0 deletions c2rust-analyze/src/rewrite/expr/distribute.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
//! Distributes MIR rewrites to HIR nodes. This takes a list of MIR rewrites (from `mir_op`) and a
//! map from MIR location to `HirId` (from `unlower`) and produces a map from `HirId` to a list of
//! MIR rewrites.
//!
//! Using the example from `unlower`:
//!
//! ```
//! bb0[5]: Terminator { source_info: ..., kind: _4 = f(move _5) -> [return: bb1, unwind: bb2] }
//! []: StoreIntoLocal, `f(y)`
//! [Rvalue]: Expr, `f(y)`
//! [Rvalue, CallArg(0)]: Expr, `y`
//! ```
//!
//! A MIR rewrite on `bb0[5]` `[Rvalue, CallArg(0)]` would be attached to the MIR
//! `Expr` `y`, and a rewrite on `bb0[5]` `[Rvalue`] would be attached to `f(y)`.
//! A MIR rewrite on `bb0[5]` `[]` (i.e. on the call terminator itself) would
//! result in an error, since there is no good place in the HIR to attach such a
//! rewrite.

use crate::rewrite::expr::mir_op::{self, MirRewrite, SubLoc};
use crate::rewrite::expr::unlower::{MirOrigin, MirOriginDesc};
use log::*;
Expand Down
51 changes: 51 additions & 0 deletions c2rust-analyze/src/rewrite/expr/unlower.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,56 @@
//! Builds the *unlowering map*, which maps each piece of the MIR to the HIR `Expr` that was
//! lowered to produce it.
//!
//! For example:
//!
//! ```Rust
//! fn f(a: i32) -> i32 {
//! a + 1
//! }
//!
//! fn g(x: i32, y: i32) -> i32 {
//! x + f(y)
//! }
//! ```
//!
//! For `f`, the unlowering map annotates the MIR as follows:
//!
//! ```
//! block bb0:
//! bb0[0]: StorageLive(_2)
//! bb0[1]: _2 = _1
//! []: StoreIntoLocal, `a`
//! [Rvalue]: Expr, `a`
//! bb0[2]: _0 = Add(move _2, const 1_i32)
//! []: StoreIntoLocal, `a + 1`
//! [Rvalue]: Expr, `a + 1`
//! bb0[3]: StorageDead(_2)
//! bb0[4]: Terminator { source_info: ..., kind: return }
//! ```
//!
//! The statement `_2 = _1` is associated with the expression `a`; the statement
//! as a whole is storing the result of evaluating `a` into a MIR local, and the
//! statement's rvalue `_1` represents the expression `a` itself. Similarly, `_0 =
//! Add(move _2, const 1)` stores the result of `a + 1` into a local. If needed,
//! we could extend the `unlower` pass to also record that `move _2` (a.k.a. `bb0[2]`
//! `[Rvalue, RvalueOperand(0)]`) is lowered from the `Expr` `a`.
//!
//! On `g`, the unlowering map includes the following (among other entries):
//!
//! ```
//! bb0[5]: Terminator { source_info: ..., kind: _4 = f(move _5) -> [return: bb1, unwind: bb2] }
//! []: StoreIntoLocal, `f(y)`
//! [Rvalue]: Expr, `f(y)`
//! [Rvalue, CallArg(0)]: Expr, `y`
//! bb1[1]: _0 = Add(move _3, move _4)
//! []: StoreIntoLocal, `x + f(y)`
//! [Rvalue]: Expr, `x + f(y)`
//! ```
//!
//! The call terminator `_4 = f(move _5)` computes `f(y)` and stores the result
//! into a local; its rvalue is `f(y)` itself, and the first argument of the rvalue
//! is `y`.

use crate::rewrite::build_span_index;
use crate::rewrite::expr::mir_op::SubLoc;
use crate::rewrite::span_index::SpanIndex;
Expand Down

0 comments on commit 02553d4

Please sign in to comment.