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:
Matthias Krüger 2023-06-27 17:48:47 +02:00 committed by GitHub
commit 4571be358b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 32 additions and 9 deletions

View File

@ -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,

View File

@ -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]);

View File

@ -549,6 +549,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
| ExprKind::Break { .. }
| ExprKind::Continue { .. }
| ExprKind::Return { .. }
| ExprKind::Become { .. }
| ExprKind::Literal { .. }
| ExprKind::NamedConst { .. }
| ExprKind::NonHirLiteral { .. }

View File

@ -532,6 +532,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
| ExprKind::Break { .. }
| ExprKind::Continue { .. }
| ExprKind::Return { .. }
| ExprKind::Become { .. }
| ExprKind::InlineAsm { .. }
| ExprKind::PlaceTypeAscription { .. }
| ExprKind::ValueTypeAscription { .. } => {

View File

@ -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"
{

View File

@ -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()

View File

@ -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(),

View File

@ -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 { .. }

View File

@ -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 },

View File

@ -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);

View File

@ -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(_)