From 02553d4dc55b874e9c94866a7d557ffe6aaf7414 Mon Sep 17 00:00:00 2001 From: Stuart Pernsteiner Date: Thu, 18 May 2023 14:36:46 -0700 Subject: [PATCH] analyze: rewrite::expr: add examples to unlower and distribute doc comments --- c2rust-analyze/src/rewrite/expr/distribute.rs | 16 ++++++ c2rust-analyze/src/rewrite/expr/unlower.rs | 51 +++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/c2rust-analyze/src/rewrite/expr/distribute.rs b/c2rust-analyze/src/rewrite/expr/distribute.rs index c2f7e0f08c..76304ec2f3 100644 --- a/c2rust-analyze/src/rewrite/expr/distribute.rs +++ b/c2rust-analyze/src/rewrite/expr/distribute.rs @@ -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::*; diff --git a/c2rust-analyze/src/rewrite/expr/unlower.rs b/c2rust-analyze/src/rewrite/expr/unlower.rs index 696654cdde..a6447a9568 100644 --- a/c2rust-analyze/src/rewrite/expr/unlower.rs +++ b/c2rust-analyze/src/rewrite/expr/unlower.rs @@ -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;