Support tail calls in mir via TerminatorKind::TailCall
This commit is contained in:
parent
e2cf31a614
commit
484152d562
41 changed files with 328 additions and 88 deletions
|
@ -2,7 +2,9 @@ use crate::build::scope::BreakableTarget;
|
|||
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
|
||||
use rustc_middle::middle::region;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::thir::*;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use tracing::debug;
|
||||
|
||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
@ -91,9 +93,38 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
ExprKind::Return { value } => {
|
||||
this.break_scope(block, value, BreakableTarget::Return, source_info)
|
||||
}
|
||||
// FIXME(explicit_tail_calls): properly lower tail calls here
|
||||
ExprKind::Become { value } => {
|
||||
this.break_scope(block, Some(value), BreakableTarget::Return, source_info)
|
||||
let v = &this.thir[value];
|
||||
let ExprKind::Scope { value, .. } = v.kind else {
|
||||
span_bug!(v.span, "`thir_check_tail_calls` should have disallowed this {v:?}")
|
||||
};
|
||||
|
||||
let v = &this.thir[value];
|
||||
let ExprKind::Call { ref args, fun, fn_span, .. } = v.kind else {
|
||||
span_bug!(v.span, "`thir_check_tail_calls` should have disallowed this {v:?}")
|
||||
};
|
||||
|
||||
let fun = unpack!(block = this.as_local_operand(block, fun));
|
||||
let args: Vec<_> = args
|
||||
.into_iter()
|
||||
.copied()
|
||||
.map(|arg| Spanned {
|
||||
node: unpack!(block = this.as_local_call_operand(block, arg)),
|
||||
span: this.thir.exprs[arg].span,
|
||||
})
|
||||
.collect();
|
||||
|
||||
this.record_operands_moved(&args);
|
||||
|
||||
debug!("expr_into_dest: fn_span={:?}", fn_span);
|
||||
|
||||
this.cfg.terminate(
|
||||
block,
|
||||
source_info,
|
||||
TerminatorKind::TailCall { func: fun, args, fn_span },
|
||||
);
|
||||
|
||||
this.cfg.start_new_block().unit()
|
||||
}
|
||||
_ => {
|
||||
assert!(
|
||||
|
|
|
@ -1523,6 +1523,7 @@ impl<'tcx> DropTreeBuilder<'tcx> for Unwind {
|
|||
| TerminatorKind::UnwindResume
|
||||
| TerminatorKind::UnwindTerminate(_)
|
||||
| TerminatorKind::Return
|
||||
| TerminatorKind::TailCall { .. }
|
||||
| TerminatorKind::Unreachable
|
||||
| TerminatorKind::Yield { .. }
|
||||
| TerminatorKind::CoroutineDrop
|
||||
|
|
|
@ -196,6 +196,8 @@ impl<'mir, 'tcx, C: TerminatorClassifier<'tcx>> TriColorVisitor<BasicBlocks<'tcx
|
|||
| TerminatorKind::CoroutineDrop
|
||||
| TerminatorKind::UnwindResume
|
||||
| TerminatorKind::Return
|
||||
// FIXME(explicit_tail_calls) Is this right??
|
||||
| TerminatorKind::TailCall { .. }
|
||||
| TerminatorKind::Unreachable
|
||||
| TerminatorKind::Yield { .. } => ControlFlow::Break(NonRecursive),
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue