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 {
|
Return {
|
||||||
value: Option<ExprId>,
|
value: Option<ExprId>,
|
||||||
},
|
},
|
||||||
|
/// A `become` expression.
|
||||||
|
Become {
|
||||||
|
value: ExprId,
|
||||||
|
},
|
||||||
/// An inline `const` block, e.g. `const {}`.
|
/// An inline `const` block, e.g. `const {}`.
|
||||||
ConstBlock {
|
ConstBlock {
|
||||||
did: DefId,
|
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])
|
visitor.visit_expr(&visitor.thir()[value])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Become { value } => visitor.visit_expr(&visitor.thir()[value]),
|
||||||
ConstBlock { did: _, substs: _ } => {}
|
ConstBlock { did: _, substs: _ } => {}
|
||||||
Repeat { value, count: _ } => {
|
Repeat { value, count: _ } => {
|
||||||
visitor.visit_expr(&visitor.thir()[value]);
|
visitor.visit_expr(&visitor.thir()[value]);
|
||||||
|
@ -549,6 +549,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
| ExprKind::Break { .. }
|
| ExprKind::Break { .. }
|
||||||
| ExprKind::Continue { .. }
|
| ExprKind::Continue { .. }
|
||||||
| ExprKind::Return { .. }
|
| ExprKind::Return { .. }
|
||||||
|
| ExprKind::Become { .. }
|
||||||
| ExprKind::Literal { .. }
|
| ExprKind::Literal { .. }
|
||||||
| ExprKind::NamedConst { .. }
|
| ExprKind::NamedConst { .. }
|
||||||
| ExprKind::NonHirLiteral { .. }
|
| ExprKind::NonHirLiteral { .. }
|
||||||
|
@ -532,6 +532,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
| ExprKind::Break { .. }
|
| ExprKind::Break { .. }
|
||||||
| ExprKind::Continue { .. }
|
| ExprKind::Continue { .. }
|
||||||
| ExprKind::Return { .. }
|
| ExprKind::Return { .. }
|
||||||
|
| ExprKind::Become { .. }
|
||||||
| ExprKind::InlineAsm { .. }
|
| ExprKind::InlineAsm { .. }
|
||||||
| ExprKind::PlaceTypeAscription { .. }
|
| ExprKind::PlaceTypeAscription { .. }
|
||||||
| ExprKind::ValueTypeAscription { .. } => {
|
| ExprKind::ValueTypeAscription { .. } => {
|
||||||
|
@ -82,7 +82,8 @@ impl Category {
|
|||||||
| ExprKind::Block { .. }
|
| ExprKind::Block { .. }
|
||||||
| ExprKind::Break { .. }
|
| ExprKind::Break { .. }
|
||||||
| ExprKind::Continue { .. }
|
| ExprKind::Continue { .. }
|
||||||
| ExprKind::Return { .. } =>
|
| ExprKind::Return { .. }
|
||||||
|
| ExprKind::Become { .. } =>
|
||||||
// FIXME(#27840) these probably want their own
|
// FIXME(#27840) these probably want their own
|
||||||
// category, like "nonterminating"
|
// category, like "nonterminating"
|
||||||
{
|
{
|
||||||
|
@ -493,7 +493,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
block.unit()
|
block.unit()
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprKind::Continue { .. } | ExprKind::Break { .. } | ExprKind::Return { .. } => {
|
ExprKind::Continue { .. }
|
||||||
|
| ExprKind::Break { .. }
|
||||||
|
| ExprKind::Return { .. }
|
||||||
|
| ExprKind::Become { .. } => {
|
||||||
unpack!(block = this.stmt_expr(block, expr, None));
|
unpack!(block = this.stmt_expr(block, expr, None));
|
||||||
// No assign, as these have type `!`.
|
// No assign, as these have type `!`.
|
||||||
block.unit()
|
block.unit()
|
||||||
|
@ -99,6 +99,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
BreakableTarget::Return,
|
BreakableTarget::Return,
|
||||||
source_info,
|
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!(
|
assert!(
|
||||||
statement_scope.is_some(),
|
statement_scope.is_some(),
|
||||||
|
@ -316,6 +316,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||||||
| ExprKind::Closure { .. }
|
| ExprKind::Closure { .. }
|
||||||
| ExprKind::Continue { .. }
|
| ExprKind::Continue { .. }
|
||||||
| ExprKind::Return { .. }
|
| ExprKind::Return { .. }
|
||||||
|
| ExprKind::Become { .. }
|
||||||
| ExprKind::Yield { .. }
|
| ExprKind::Yield { .. }
|
||||||
| ExprKind::Loop { .. }
|
| ExprKind::Loop { .. }
|
||||||
| ExprKind::Let { .. }
|
| ExprKind::Let { .. }
|
||||||
|
@ -694,12 +694,8 @@ impl<'tcx> Cx<'tcx> {
|
|||||||
|
|
||||||
ExprKind::Repeat { value: self.mirror_expr(v), count: *count }
|
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::Ret(v) => ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) },
|
||||||
hir::ExprKind::Become(call) => {
|
hir::ExprKind::Become(call) => ExprKind::Become { value: self.mirror_expr(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::Break(dest, ref value) => match dest.target_id {
|
hir::ExprKind::Break(dest, ref value) => match dest.target_id {
|
||||||
Ok(target_id) => ExprKind::Break {
|
Ok(target_id) => ExprKind::Break {
|
||||||
label: region::Scope { id: target_id.local_id, data: region::ScopeData::Node },
|
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);
|
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 } => {
|
ConstBlock { did, substs } => {
|
||||||
print_indented!(self, "ConstBlock {", depth_lvl);
|
print_indented!(self, "ConstBlock {", depth_lvl);
|
||||||
print_indented!(self, format!("did: {:?}", did), depth_lvl + 1);
|
print_indented!(self, format!("did: {:?}", did), depth_lvl + 1);
|
||||||
|
@ -241,7 +241,8 @@ fn recurse_build<'tcx>(
|
|||||||
ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
|
ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
|
||||||
error(GenericConstantTooComplexSub::AssignNotSupported(node.span))?
|
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))?
|
error(GenericConstantTooComplexSub::ClosureAndReturnNotSupported(node.span))?
|
||||||
}
|
}
|
||||||
// let expressions imply control flow
|
// let expressions imply control flow
|
||||||
@ -337,6 +338,7 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> {
|
|||||||
| thir::ExprKind::Break { .. }
|
| thir::ExprKind::Break { .. }
|
||||||
| thir::ExprKind::Continue { .. }
|
| thir::ExprKind::Continue { .. }
|
||||||
| thir::ExprKind::Return { .. }
|
| thir::ExprKind::Return { .. }
|
||||||
|
| thir::ExprKind::Become { .. }
|
||||||
| thir::ExprKind::Array { .. }
|
| thir::ExprKind::Array { .. }
|
||||||
| thir::ExprKind::Tuple { .. }
|
| thir::ExprKind::Tuple { .. }
|
||||||
| thir::ExprKind::Adt(_)
|
| thir::ExprKind::Adt(_)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user