Rollup merge of #113093 - WaffleLapkin:become_unuwuable_in_thir, r=Nilstrieb
`thir`: Add `Become` expression kind This PR is pretty small and just adds `thir::ExprKind::Become`. I didn't include the checks that will be done on thir, since they are much more complicated and can be done in parallel with with MIR (or, well, at least I believe they can). r? `@Nilstrieb`
This commit is contained in:
commit
4571be358b
@ -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 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
| ExprKind::Break { .. }
|
||||
| ExprKind::Continue { .. }
|
||||
| ExprKind::Return { .. }
|
||||
| ExprKind::Become { .. }
|
||||
| ExprKind::Literal { .. }
|
||||
| ExprKind::NamedConst { .. }
|
||||
| ExprKind::NonHirLiteral { .. }
|
||||
|
@ -532,6 +532,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
| ExprKind::Break { .. }
|
||||
| ExprKind::Continue { .. }
|
||||
| ExprKind::Return { .. }
|
||||
| ExprKind::Become { .. }
|
||||
| ExprKind::InlineAsm { .. }
|
||||
| ExprKind::PlaceTypeAscription { .. }
|
||||
| ExprKind::ValueTypeAscription { .. } => {
|
||||
|
@ -82,7 +82,8 @@ impl 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 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
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 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
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 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||
| ExprKind::Closure { .. }
|
||||
| ExprKind::Continue { .. }
|
||||
| ExprKind::Return { .. }
|
||||
| ExprKind::Become { .. }
|
||||
| ExprKind::Yield { .. }
|
||||
| ExprKind::Loop { .. }
|
||||
| ExprKind::Let { .. }
|
||||
|
@ -694,12 +694,8 @@ impl<'tcx> Cx<'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 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
|
||||
|
||||
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 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> {
|
||||
| thir::ExprKind::Break { .. }
|
||||
| thir::ExprKind::Continue { .. }
|
||||
| thir::ExprKind::Return { .. }
|
||||
| thir::ExprKind::Become { .. }
|
||||
| thir::ExprKind::Array { .. }
|
||||
| thir::ExprKind::Tuple { .. }
|
||||
| thir::ExprKind::Adt(_)
|
||||
|
Loading…
x
Reference in New Issue
Block a user