blob: ac5cf187aa01bced7ceaf74bc114a1f4d72798bd [file] [log] [blame]
use crate::thir::*;
#[derive(Debug, PartialEq)]
crate enum Category {
// An assignable memory location like `x`, `x.f`, `foo()[3]`, that
// sort of thing. Something that could appear on the LHS of an `=`
// sign.
Place,
// A literal like `23` or `"foo"`. Does not include constant
// expressions like `3 + 5`.
Constant,
// Something that generates a new value at runtime, like `x + y`
// or `foo()`.
Rvalue(RvalueFunc),
}
// Rvalues fall into different "styles" that will determine which fn
// is best suited to generate them.
#[derive(Debug, PartialEq)]
crate enum RvalueFunc {
// Best generated by `into`. This is generally exprs that
// cause branching, like `match`, but also includes calls.
Into,
// Best generated by `as_rvalue`. This is usually the case.
AsRvalue,
}
/// Determines the category for a given expression. Note that scope
/// and paren expressions have no category.
impl Category {
crate fn of(ek: &ExprKind<'_>) -> Option<Category> {
match *ek {
ExprKind::Scope { .. } => None,
ExprKind::Field { .. }
| ExprKind::Deref { .. }
| ExprKind::Index { .. }
| ExprKind::SelfRef
| ExprKind::VarRef { .. }
| ExprKind::PlaceTypeAscription { .. }
| ExprKind::ValueTypeAscription { .. } => Some(Category::Place),
ExprKind::LogicalOp { .. }
| ExprKind::Match { .. }
| ExprKind::NeverToAny { .. }
| ExprKind::Use { .. }
| ExprKind::Adt { .. }
| ExprKind::Borrow { .. }
| ExprKind::AddressOf { .. }
| ExprKind::Yield { .. }
| ExprKind::Call { .. }
| ExprKind::InlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::Into)),
ExprKind::Array { .. }
| ExprKind::Tuple { .. }
| ExprKind::Closure { .. }
| ExprKind::Unary { .. }
| ExprKind::Binary { .. }
| ExprKind::Box { .. }
| ExprKind::Cast { .. }
| ExprKind::Pointer { .. }
| ExprKind::Repeat { .. }
| ExprKind::Assign { .. }
| ExprKind::AssignOp { .. }
| ExprKind::ThreadLocalRef(_)
| ExprKind::LlvmInlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)),
ExprKind::ConstBlock { .. } | ExprKind::Literal { .. } | ExprKind::StaticRef { .. } => {
Some(Category::Constant)
}
ExprKind::Loop { .. }
| ExprKind::Block { .. }
| ExprKind::Break { .. }
| ExprKind::Continue { .. }
| ExprKind::Return { .. } =>
// FIXME(#27840) these probably want their own
// category, like "nonterminating"
{
Some(Category::Rvalue(RvalueFunc::Into))
}
}
}
}