]>
Commit | Line | Data |
---|---|---|
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 | use hair::*; | |
12 | ||
13 | #[derive(Debug, PartialEq)] | |
14 | pub enum Category { | |
15 | // An assignable memory location like `x`, `x.f`, `foo()[3]`, that | |
16 | // sort of thing. Something that could appear on the LHS of an `=` | |
17 | // sign. | |
ff7c6d11 | 18 | Place, |
e9174d1e SL |
19 | |
20 | // A literal like `23` or `"foo"`. Does not include constant | |
21 | // expressions like `3 + 5`. | |
22 | Constant, | |
23 | ||
24 | // Something that generates a new value at runtime, like `x + y` | |
25 | // or `foo()`. | |
26 | Rvalue(RvalueFunc), | |
27 | } | |
28 | ||
29 | // Rvalues fall into different "styles" that will determine which fn | |
30 | // is best suited to generate them. | |
31 | #[derive(Debug, PartialEq)] | |
32 | pub enum RvalueFunc { | |
33 | // Best generated by `into`. This is generally exprs that | |
34 | // cause branching, like `match`, but also includes calls. | |
35 | Into, | |
36 | ||
37 | // Best generated by `as_rvalue`. This is usually the case. | |
38 | AsRvalue, | |
39 | } | |
40 | ||
41 | /// Determines the category for a given expression. Note that scope | |
42 | /// and paren expressions have no category. | |
43 | impl Category { | |
b039eaaf | 44 | pub fn of<'tcx>(ek: &ExprKind<'tcx>) -> Option<Category> { |
e9174d1e | 45 | match *ek { |
b039eaaf | 46 | ExprKind::Scope { .. } => None, |
e9174d1e | 47 | |
b7449926 XL |
48 | ExprKind::Field { .. } |
49 | | ExprKind::Deref { .. } | |
50 | | ExprKind::Index { .. } | |
51 | | ExprKind::SelfRef | |
52 | | ExprKind::VarRef { .. } | |
0bf4aa26 XL |
53 | | ExprKind::StaticRef { .. } |
54 | | ExprKind::PlaceTypeAscription { .. } | |
55 | | ExprKind::ValueTypeAscription { .. } => Some(Category::Place), | |
e9174d1e | 56 | |
b7449926 XL |
57 | ExprKind::LogicalOp { .. } |
58 | | ExprKind::If { .. } | |
59 | | ExprKind::Match { .. } | |
60 | | ExprKind::NeverToAny { .. } | |
61 | | ExprKind::Call { .. } => Some(Category::Rvalue(RvalueFunc::Into)), | |
e9174d1e | 62 | |
b7449926 XL |
63 | ExprKind::Array { .. } |
64 | | ExprKind::Tuple { .. } | |
65 | | ExprKind::Adt { .. } | |
66 | | ExprKind::Closure { .. } | |
67 | | ExprKind::Unary { .. } | |
68 | | ExprKind::Binary { .. } | |
69 | | ExprKind::Box { .. } | |
70 | | ExprKind::Cast { .. } | |
71 | | ExprKind::Use { .. } | |
72 | | ExprKind::ReifyFnPointer { .. } | |
73 | | ExprKind::ClosureFnPointer { .. } | |
74 | | ExprKind::UnsafeFnPointer { .. } | |
75 | | ExprKind::Unsize { .. } | |
76 | | ExprKind::Repeat { .. } | |
77 | | ExprKind::Borrow { .. } | |
78 | | ExprKind::Assign { .. } | |
79 | | ExprKind::AssignOp { .. } | |
80 | | ExprKind::Yield { .. } | |
81 | | ExprKind::InlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)), | |
e9174d1e | 82 | |
b7449926 | 83 | ExprKind::Literal { .. } => Some(Category::Constant), |
e9174d1e | 84 | |
b7449926 XL |
85 | ExprKind::Loop { .. } |
86 | | ExprKind::Block { .. } | |
87 | | ExprKind::Break { .. } | |
88 | | ExprKind::Continue { .. } | |
89 | | ExprKind::Return { .. } => | |
90 | // FIXME(#27840) these probably want their own | |
91 | // category, like "nonterminating" | |
92 | { | |
93 | Some(Category::Rvalue(RvalueFunc::Into)) | |
94 | } | |
e9174d1e SL |
95 | } |
96 | } | |
97 | } |