提交 c60fb12a 编写于 作者: M Maybe Waffle

`thir`: Add `Become` expression kind

上级 b5e51db1
......@@ -410,6 +410,10 @@ pub enum ExprKind<'tcx> {
Return {
value: Option<ExprId>,
},
/// A `become` expression.
Become {
value: ExprId,
},
/// An inline `const` block, e.g. `const {}`.
ConstBlock {
did: DefId,
......
......@@ -100,6 +100,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
visitor.visit_expr(&visitor.thir()[value])
}
}
Become { value } => visitor.visit_expr(&visitor.thir()[value]),
ConstBlock { did: _, substs: _ } => {}
Repeat { value, count: _ } => {
visitor.visit_expr(&visitor.thir()[value]);
......
......@@ -549,6 +549,7 @@ fn expr_as_place(
| ExprKind::Break { .. }
| ExprKind::Continue { .. }
| ExprKind::Return { .. }
| ExprKind::Become { .. }
| ExprKind::Literal { .. }
| ExprKind::NamedConst { .. }
| ExprKind::NonHirLiteral { .. }
......
......@@ -532,6 +532,7 @@ pub(crate) fn as_rvalue(
| ExprKind::Break { .. }
| ExprKind::Continue { .. }
| ExprKind::Return { .. }
| ExprKind::Become { .. }
| ExprKind::InlineAsm { .. }
| ExprKind::PlaceTypeAscription { .. }
| ExprKind::ValueTypeAscription { .. } => {
......
......@@ -82,7 +82,8 @@ pub(crate) fn of(ek: &ExprKind<'_>) -> Option<Category> {
| ExprKind::Block { .. }
| ExprKind::Break { .. }
| ExprKind::Continue { .. }
| ExprKind::Return { .. } =>
| ExprKind::Return { .. }
| ExprKind::Become { .. } =>
// FIXME(#27840) these probably want their own
// category, like "nonterminating"
{
......
......@@ -493,7 +493,10 @@ pub(crate) fn expr_into_dest(
block.unit()
}
ExprKind::Continue { .. } | ExprKind::Break { .. } | ExprKind::Return { .. } => {
ExprKind::Continue { .. }
| ExprKind::Break { .. }
| ExprKind::Return { .. }
| ExprKind::Become { .. } => {
unpack!(block = this.stmt_expr(block, expr, None));
// No assign, as these have type `!`.
block.unit()
......
......@@ -99,6 +99,13 @@ pub(crate) fn stmt_expr(
BreakableTarget::Return,
source_info,
),
// FIXME(explicit_tail_calls): properly lower tail calls here
ExprKind::Become { value } => this.break_scope(
block,
Some(&this.thir[value]),
BreakableTarget::Return,
source_info,
),
_ => {
assert!(
statement_scope.is_some(),
......
......@@ -316,6 +316,7 @@ fn visit_expr(&mut self, expr: &Expr<'tcx>) {
| ExprKind::Closure { .. }
| ExprKind::Continue { .. }
| ExprKind::Return { .. }
| ExprKind::Become { .. }
| ExprKind::Yield { .. }
| ExprKind::Loop { .. }
| ExprKind::Let { .. }
......
......@@ -694,12 +694,8 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx>
ExprKind::Repeat { value: self.mirror_expr(v), count: *count }
}
hir::ExprKind::Ret(ref v) => ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) },
hir::ExprKind::Become(call) => {
// FIXME(explicit_tail_calls): use `ExprKind::Become` once we implemented it
// Temporary transform `become` into a `return`, so we can write tests for code before this stage
ExprKind::Return { value: Some(self.mirror_expr(call)) }
}
hir::ExprKind::Ret(v) => ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) },
hir::ExprKind::Become(call) => ExprKind::Become { value: self.mirror_expr(call) },
hir::ExprKind::Break(dest, ref value) => match dest.target_id {
Ok(target_id) => ExprKind::Break {
label: region::Scope { id: target_id.local_id, data: region::ScopeData::Node },
......
......@@ -421,6 +421,12 @@ fn print_expr_kind(&mut self, expr_kind: &ExprKind<'tcx>, depth_lvl: usize) {
print_indented!(self, "}", depth_lvl);
}
Become { value } => {
print_indented!(self, "Become {", depth_lvl);
print_indented!(self, "value:", depth_lvl + 1);
self.print_expr(*value, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
ConstBlock { did, substs } => {
print_indented!(self, "ConstBlock {", depth_lvl);
print_indented!(self, format!("did: {:?}", did), depth_lvl + 1);
......
......@@ -241,7 +241,8 @@ fn recurse_build<'tcx>(
ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
error(GenericConstantTooComplexSub::AssignNotSupported(node.span))?
}
ExprKind::Closure { .. } | ExprKind::Return { .. } => {
// FIXME(explicit_tail_calls): maybe get `become` a new error
ExprKind::Closure { .. } | ExprKind::Return { .. } | ExprKind::Become { .. } => {
error(GenericConstantTooComplexSub::ClosureAndReturnNotSupported(node.span))?
}
// let expressions imply control flow
......@@ -337,6 +338,7 @@ fn expr_is_poly(&mut self, expr: &thir::Expr<'tcx>) -> bool {
| thir::ExprKind::Break { .. }
| thir::ExprKind::Continue { .. }
| thir::ExprKind::Return { .. }
| thir::ExprKind::Become { .. }
| thir::ExprKind::Array { .. }
| thir::ExprKind::Tuple { .. }
| thir::ExprKind::Adt(_)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册