Skip to content

Commit cffd2df

Browse files
committed
thir: Add Become expression kind
Note that this doesn't implement `become` correctly, there is still no early drop or tail calls involved. Moreother, it seems like MIR simply can not represent tail calls in its current form so I'll probably need to add new statement kinds or smh. to it in order to represent them...
1 parent 47ab1e5 commit cffd2df

File tree

12 files changed

+36
-7
lines changed

12 files changed

+36
-7
lines changed

compiler/rustc_middle/src/thir.rs

+4
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,10 @@ pub enum ExprKind<'tcx> {
410410
Return {
411411
value: Option<ExprId>,
412412
},
413+
/// A `become` expression.
414+
Become {
415+
value: ExprId,
416+
},
413417
/// An inline `const` block, e.g. `const {}`.
414418
ConstBlock {
415419
did: DefId,

compiler/rustc_middle/src/thir/visit.rs

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
100100
visitor.visit_expr(&visitor.thir()[value])
101101
}
102102
}
103+
Become { value } => visitor.visit_expr(&visitor.thir()[value]),
103104
ConstBlock { did: _, substs: _ } => {}
104105
Repeat { value, count: _ } => {
105106
visitor.visit_expr(&visitor.thir()[value]);

compiler/rustc_mir_build/src/build/expr/as_place.rs

+1
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
549549
| ExprKind::Break { .. }
550550
| ExprKind::Continue { .. }
551551
| ExprKind::Return { .. }
552+
| ExprKind::Become { .. }
552553
| ExprKind::Literal { .. }
553554
| ExprKind::NamedConst { .. }
554555
| ExprKind::NonHirLiteral { .. }

compiler/rustc_mir_build/src/build/expr/as_rvalue.rs

+1
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
532532
| ExprKind::Break { .. }
533533
| ExprKind::Continue { .. }
534534
| ExprKind::Return { .. }
535+
| ExprKind::Become { .. }
535536
| ExprKind::InlineAsm { .. }
536537
| ExprKind::PlaceTypeAscription { .. }
537538
| ExprKind::ValueTypeAscription { .. } => {

compiler/rustc_mir_build/src/build/expr/category.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ impl Category {
8282
| ExprKind::Block { .. }
8383
| ExprKind::Break { .. }
8484
| ExprKind::Continue { .. }
85-
| ExprKind::Return { .. } =>
85+
| ExprKind::Return { .. }
86+
| ExprKind::Become { .. } =>
8687
// FIXME(#27840) these probably want their own
8788
// category, like "nonterminating"
8889
{

compiler/rustc_mir_build/src/build/expr/into.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
489489
block.unit()
490490
}
491491

492-
ExprKind::Continue { .. } | ExprKind::Break { .. } | ExprKind::Return { .. } => {
492+
ExprKind::Continue { .. }
493+
| ExprKind::Break { .. }
494+
| ExprKind::Return { .. }
495+
| ExprKind::Become { .. } => {
493496
unpack!(block = this.stmt_expr(block, expr, None));
494497
// No assign, as these have type `!`.
495498
block.unit()

compiler/rustc_mir_build/src/build/expr/stmt.rs

+6
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
9999
BreakableTarget::Return,
100100
source_info,
101101
),
102+
ExprKind::Become { value } => this.break_scope(
103+
block,
104+
Some(&this.thir[value]),
105+
BreakableTarget::Become,
106+
source_info,
107+
),
102108
_ => {
103109
assert!(
104110
statement_scope.is_some(),

compiler/rustc_mir_build/src/build/scope.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ pub(crate) enum BreakableTarget {
182182
Continue(region::Scope),
183183
Break(region::Scope),
184184
Return,
185+
Become,
185186
}
186187

187188
rustc_index::newtype_index! {
@@ -627,10 +628,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
627628
.unwrap_or_else(|| span_bug!(span, "no enclosing breakable scope found"))
628629
};
629630
let (break_index, destination) = match target {
630-
BreakableTarget::Return => {
631+
BreakableTarget::Return | BreakableTarget::Become => {
631632
let scope = &self.scopes.breakable_scopes[0];
632633
if scope.break_destination != Place::return_place() {
633-
span_bug!(span, "`return` in item with no return scope");
634+
span_bug!(span, "`return` or `become` in item with no return scope");
634635
}
635636
(0, Some(scope.break_destination))
636637
}
@@ -668,6 +669,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
668669
(None, None) => {}
669670
}
670671

672+
// FIXME(explicit_tail_calls): this should drop stuff early for `become`
673+
671674
let region_scope = self.scopes.breakable_scopes[break_index].region_scope;
672675
let scope_index = self.scopes.scope_index(region_scope, span);
673676
let drops = if destination.is_some() {

compiler/rustc_mir_build/src/check_unsafety.rs

+1
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
316316
| ExprKind::Closure { .. }
317317
| ExprKind::Continue { .. }
318318
| ExprKind::Return { .. }
319+
| ExprKind::Become { .. }
319320
| ExprKind::Yield { .. }
320321
| ExprKind::Loop { .. }
321322
| ExprKind::Let { .. }

compiler/rustc_mir_build/src/thir/cx/expr.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -694,8 +694,8 @@ impl<'tcx> Cx<'tcx> {
694694

695695
ExprKind::Repeat { value: self.mirror_expr(v), count: *count }
696696
}
697-
hir::ExprKind::Ret(ref v) => ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) },
698-
hir::ExprKind::Become(_call) => unimplemented!("lol (lmao)"),
697+
hir::ExprKind::Ret(v) => ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) },
698+
hir::ExprKind::Become(call) => ExprKind::Become { value: self.mirror_expr(call) },
699699
hir::ExprKind::Break(dest, ref value) => match dest.target_id {
700700
Ok(target_id) => ExprKind::Break {
701701
label: region::Scope { id: target_id.local_id, data: region::ScopeData::Node },

compiler/rustc_mir_build/src/thir/print.rs

+6
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,12 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
421421

422422
print_indented!(self, "}", depth_lvl);
423423
}
424+
Become { value } => {
425+
print_indented!(self, "Return {", depth_lvl);
426+
print_indented!(self, "value:", depth_lvl + 1);
427+
self.print_expr(*value, depth_lvl + 2);
428+
print_indented!(self, "}", depth_lvl);
429+
}
424430
ConstBlock { did, substs } => {
425431
print_indented!(self, "ConstBlock {", depth_lvl);
426432
print_indented!(self, format!("did: {:?}", did), depth_lvl + 1);

compiler/rustc_ty_utils/src/consts.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ fn recurse_build<'tcx>(
240240
ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
241241
error(GenericConstantTooComplexSub::AssignNotSupported(node.span))?
242242
}
243-
ExprKind::Closure { .. } | ExprKind::Return { .. } => {
243+
// FIXME(explicit_tail_calls): maybe get `become` a new error
244+
ExprKind::Closure { .. } | ExprKind::Return { .. } | ExprKind::Become { .. } => {
244245
error(GenericConstantTooComplexSub::ClosureAndReturnNotSupported(node.span))?
245246
}
246247
// let expressions imply control flow
@@ -336,6 +337,7 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> {
336337
| thir::ExprKind::Break { .. }
337338
| thir::ExprKind::Continue { .. }
338339
| thir::ExprKind::Return { .. }
340+
| thir::ExprKind::Become { .. }
339341
| thir::ExprKind::Array { .. }
340342
| thir::ExprKind::Tuple { .. }
341343
| thir::ExprKind::Adt(_)

0 commit comments

Comments
 (0)