]>
Commit | Line | Data |
---|---|---|
94b46f34 | 1 | //! Builds MIR from expressions. As a caller into this module, you |
e9174d1e SL |
2 | //! have many options, but the first thing you have to decide is |
3 | //! whether you are evaluating this expression for its *value*, its | |
4 | //! *location*, or as a *constant*. | |
5 | //! | |
6 | //! Typically, you want the value: e.g., if you are doing `expr_a + | |
7 | //! expr_b`, you want the values of those expressions. In that case, | |
8 | //! you want one of the following functions. Note that if the expr has | |
9 | //! a type that is not `Copy`, then using any of these functions will | |
10 | //! "move" the value out of its current home (if any). | |
11 | //! | |
6a06907d | 12 | //! - `expr_into_dest` -- writes the value into a specific location, which |
e9174d1e SL |
13 | //! should be uninitialized |
14 | //! - `as_operand` -- evaluates the value and yields an `Operand`, | |
15 | //! suitable for use as an argument to an `Rvalue` | |
16 | //! - `as_temp` -- evaluates into a temporary; this is similar to `as_operand` | |
ff7c6d11 | 17 | //! except it always returns a fresh place, even for constants |
e9174d1e SL |
18 | //! - `as_rvalue` -- yields an `Rvalue`, suitable for use in an assignment; |
19 | //! as of this writing, never needed outside of the `expr` module itself | |
20 | //! | |
21 | //! Sometimes though want the expression's *location*. An example | |
22 | //! would be during a match statement, or the operand of the `&` | |
ff7c6d11 | 23 | //! operator. In that case, you want `as_place`. This will create a |
e9174d1e SL |
24 | //! temporary if necessary. |
25 | //! | |
26 | //! Finally, if it's a constant you seek, then call | |
27 | //! `as_constant`. This creates a `Constant<H>`, but naturally it can | |
28 | //! only be used on constant expressions and hence is needed only in | |
29 | //! very limited contexts. | |
30 | //! | |
31 | //! ### Implementation notes | |
32 | //! | |
33 | //! For any given kind of expression, there is generally one way that | |
94b46f34 | 34 | //! can be lowered most naturally. This is specified by the |
e9174d1e SL |
35 | //! `Category::of` function in the `category` module. For example, a |
36 | //! struct expression (or other expression that creates a new value) | |
37 | //! is typically easiest to write in terms of `as_rvalue` or `into`, | |
38 | //! whereas a reference to a field is easiest to write in terms of | |
ff7c6d11 | 39 | //! `as_place`. (The exception to this is scope and paren |
e9174d1e SL |
40 | //! expressions, which have no category.) |
41 | //! | |
42 | //! Therefore, the various functions above make use of one another in | |
43 | //! a descending fashion. For any given expression, you should pick | |
44 | //! the most suitable spot to implement it, and then just let the | |
45 | //! other fns cycle around. The handoff works like this: | |
46 | //! | |
ff7c6d11 | 47 | //! - `into(place)` -> fallback is to create a rvalue with `as_rvalue` and assign it to `place` |
e9174d1e SL |
48 | //! - `as_rvalue` -> fallback is to create an Operand with `as_operand` and use `Rvalue::use` |
49 | //! - `as_operand` -> either invokes `as_constant` or `as_temp` | |
50 | //! - `as_constant` -> (no fallback) | |
ff7c6d11 XL |
51 | //! - `as_temp` -> creates a temporary and either calls `as_place` or `into` |
52 | //! - `as_place` -> for rvalues, falls back to `as_temp` and returns that | |
e9174d1e SL |
53 | //! |
54 | //! As you can see, there is a cycle where `into` can (in theory) fallback to `as_temp` | |
55 | //! which can fallback to `into`. So if one of the `ExprKind` variants is not, in fact, | |
56 | //! implemented in the category where it is supposed to be, there will be a problem. | |
57 | //! | |
8faf50e0 | 58 | //! Of those fallbacks, the most interesting one is `into`, because |
e9174d1e SL |
59 | //! it discriminates based on the category of the expression. This is |
60 | //! basically the point where the "by value" operations are bridged | |
ff7c6d11 | 61 | //! over to the "by reference" mode (`as_place`). |
e9174d1e SL |
62 | |
63 | mod as_constant; | |
b7449926 | 64 | mod as_operand; |
6a06907d | 65 | pub mod as_place; |
e9174d1e | 66 | mod as_rvalue; |
e9174d1e SL |
67 | mod as_temp; |
68 | mod category; | |
69 | mod into; | |
a7813a04 | 70 | mod stmt; |