]> git.proxmox.com Git - rustc.git/blame - src/librustc_mir/build/expr/mod.rs
Imported Upstream version 1.4.0+dfsg1
[rustc.git] / src / librustc_mir / build / expr / mod.rs
CommitLineData
e9174d1e
SL
1// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11//! Translates expressions into MIR. As a caller into this module, you
12//! have many options, but the first thing you have to decide is
13//! whether you are evaluating this expression for its *value*, its
14//! *location*, or as a *constant*.
15//!
16//! Typically, you want the value: e.g., if you are doing `expr_a +
17//! expr_b`, you want the values of those expressions. In that case,
18//! you want one of the following functions. Note that if the expr has
19//! a type that is not `Copy`, then using any of these functions will
20//! "move" the value out of its current home (if any).
21//!
22//! - `into` -- writes the value into a specific location, which
23//! should be uninitialized
24//! - `as_operand` -- evaluates the value and yields an `Operand`,
25//! suitable for use as an argument to an `Rvalue`
26//! - `as_temp` -- evaluates into a temporary; this is similar to `as_operand`
27//! except it always returns a fresh lvalue, even for constants
28//! - `as_rvalue` -- yields an `Rvalue`, suitable for use in an assignment;
29//! as of this writing, never needed outside of the `expr` module itself
30//!
31//! Sometimes though want the expression's *location*. An example
32//! would be during a match statement, or the operand of the `&`
33//! operator. In that case, you want `as_lvalue`. This will create a
34//! temporary if necessary.
35//!
36//! Finally, if it's a constant you seek, then call
37//! `as_constant`. This creates a `Constant<H>`, but naturally it can
38//! only be used on constant expressions and hence is needed only in
39//! very limited contexts.
40//!
41//! ### Implementation notes
42//!
43//! For any given kind of expression, there is generally one way that
44//! can be translated most naturally. This is specified by the
45//! `Category::of` function in the `category` module. For example, a
46//! struct expression (or other expression that creates a new value)
47//! is typically easiest to write in terms of `as_rvalue` or `into`,
48//! whereas a reference to a field is easiest to write in terms of
49//! `as_lvalue`. (The exception to this is scope and paren
50//! expressions, which have no category.)
51//!
52//! Therefore, the various functions above make use of one another in
53//! a descending fashion. For any given expression, you should pick
54//! the most suitable spot to implement it, and then just let the
55//! other fns cycle around. The handoff works like this:
56//!
57//! - `into(lv)` -> fallback is to create a rvalue with `as_rvalue` and assign it to `lv`
58//! - `as_rvalue` -> fallback is to create an Operand with `as_operand` and use `Rvalue::use`
59//! - `as_operand` -> either invokes `as_constant` or `as_temp`
60//! - `as_constant` -> (no fallback)
61//! - `as_temp` -> creates a temporary and either calls `as_lvalue` or `into`
62//! - `as_lvalue` -> for rvalues, falls back to `as_temp` and returns that
63//!
64//! As you can see, there is a cycle where `into` can (in theory) fallback to `as_temp`
65//! which can fallback to `into`. So if one of the `ExprKind` variants is not, in fact,
66//! implemented in the category where it is supposed to be, there will be a problem.
67//!
68//! Of those fallbacks, the most interesting one is `as_temp`, because
69//! it discriminates based on the category of the expression. This is
70//! basically the point where the "by value" operations are bridged
71//! over to the "by reference" mode (`as_lvalue`).
72
73mod as_constant;
74mod as_lvalue;
75mod as_rvalue;
76mod as_operand;
77mod as_temp;
78mod category;
79mod into;