1 use rustc_middle::thir::*;
3 #[derive(Debug, PartialEq)]
4 pub(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 `=`
10 // A literal like `23` or `"foo"`. Does not include constant
11 // expressions like `3 + 5`.
14 // Something that generates a new value at runtime, like `x + y`
19 // Rvalues fall into different "styles" that will determine which fn
20 // is best suited to generate them.
21 #[derive(Debug, PartialEq)]
22 pub(crate) enum RvalueFunc {
23 // Best generated by `into`. This is generally exprs that
24 // cause branching, like `match`, but also includes calls.
27 // Best generated by `as_rvalue`. This is usually the case.
31 /// Determines the category for a given expression. Note that scope
32 /// and paren expressions have no category.
34 pub(crate) fn of(ek: &ExprKind<'_>) -> Option<Category> {
36 ExprKind::Scope { .. } => None,
38 ExprKind::Field { .. }
39 | ExprKind::Deref { .. }
40 | ExprKind::Index { .. }
41 | ExprKind::UpvarRef { .. }
42 | ExprKind::VarRef { .. }
43 | ExprKind::PlaceTypeAscription { .. }
44 | ExprKind::ValueTypeAscription { .. } => Some(Category::Place),
46 ExprKind::LogicalOp { .. }
47 | ExprKind::Match { .. }
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)),
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)),
72 ExprKind::ConstBlock { .. }
73 | ExprKind::Literal { .. }
74 | ExprKind::NonHirLiteral { .. }
75 | ExprKind::ConstParam { .. }
76 | ExprKind::StaticRef { .. }
77 | ExprKind::NamedConst { .. } => Some(Category::Constant),
80 | ExprKind::Block { .. }
81 | ExprKind::Break { .. }
82 | ExprKind::Continue { .. }
83 | ExprKind::Return { .. } =>
84 // FIXME(#27840) these probably want their own
85 // category, like "nonterminating"
87 Some(Category::Rvalue(RvalueFunc::Into))