]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_mir_build/src/build/expr/category.rs
change thir to lazily create constants
[rust.git] / compiler / rustc_mir_build / src / build / expr / category.rs
1 use rustc_middle::thir::*;
2
3 #[derive(Debug, PartialEq)]
4 crate enum Category {
5     // An assignable memory location like `x`, `x.f`, `foo()[3]`, that
6     // sort of thing. Something that could appear on the LHS of an `=`
7     // sign.
8     Place,
9
10     // A literal like `23` or `"foo"`. Does not include constant
11     // expressions like `3 + 5`.
12     Constant,
13
14     // Something that generates a new value at runtime, like `x + y`
15     // or `foo()`.
16     Rvalue(RvalueFunc),
17 }
18
19 // Rvalues fall into different "styles" that will determine which fn
20 // is best suited to generate them.
21 #[derive(Debug, PartialEq)]
22 crate enum RvalueFunc {
23     // Best generated by `into`. This is generally exprs that
24     // cause branching, like `match`, but also includes calls.
25     Into,
26
27     // Best generated by `as_rvalue`. This is usually the case.
28     AsRvalue,
29 }
30
31 /// Determines the category for a given expression. Note that scope
32 /// and paren expressions have no category.
33 impl Category {
34     crate fn of(ek: &ExprKind<'_>) -> Option<Category> {
35         match *ek {
36             ExprKind::Scope { .. } => None,
37
38             ExprKind::Field { .. }
39             | ExprKind::Deref { .. }
40             | ExprKind::Index { .. }
41             | ExprKind::UpvarRef { .. }
42             | ExprKind::VarRef { .. }
43             | ExprKind::PlaceTypeAscription { .. }
44             | ExprKind::ValueTypeAscription { .. } => Some(Category::Place),
45
46             ExprKind::LogicalOp { .. }
47             | ExprKind::Match { .. }
48             | ExprKind::If { .. }
49             | ExprKind::Let { .. }
50             | ExprKind::NeverToAny { .. }
51             | ExprKind::Use { .. }
52             | ExprKind::Adt { .. }
53             | ExprKind::Borrow { .. }
54             | ExprKind::AddressOf { .. }
55             | ExprKind::Yield { .. }
56             | ExprKind::Call { .. }
57             | ExprKind::InlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::Into)),
58
59             ExprKind::Array { .. }
60             | ExprKind::Tuple { .. }
61             | ExprKind::Closure { .. }
62             | ExprKind::Unary { .. }
63             | ExprKind::Binary { .. }
64             | ExprKind::Box { .. }
65             | ExprKind::Cast { .. }
66             | ExprKind::Pointer { .. }
67             | ExprKind::Repeat { .. }
68             | ExprKind::Assign { .. }
69             | ExprKind::AssignOp { .. }
70             | ExprKind::ThreadLocalRef(_) => Some(Category::Rvalue(RvalueFunc::AsRvalue)),
71
72             ExprKind::ConstBlock { .. }
73             | ExprKind::Literal { .. }
74             | ExprKind::ScalarLiteral { .. }
75             | ExprKind::ConstParam { .. }
76             | ExprKind::StaticRef { .. }
77             | ExprKind::NamedConst { .. } => Some(Category::Constant),
78
79             ExprKind::Loop { .. }
80             | ExprKind::Block { .. }
81             | ExprKind::Break { .. }
82             | ExprKind::Continue { .. }
83             | ExprKind::Return { .. } =>
84             // FIXME(#27840) these probably want their own
85             // category, like "nonterminating"
86             {
87                 Some(Category::Rvalue(RvalueFunc::Into))
88             }
89         }
90     }
91 }