Support tail calls in mir via TerminatorKind::TailCall

This commit is contained in:
Maybe Waffle 2024-02-15 19:54:37 +00:00 committed by Maybe Lapkin
parent e2cf31a614
commit 484152d562
41 changed files with 328 additions and 88 deletions

View file

@ -135,6 +135,8 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
ccx: &'mir ConstCx<'mir, 'tcx>,
tainted_by_errors: Option<ErrorGuaranteed>,
) -> ConstQualifs {
// FIXME(explicit_tail_calls): uhhhh I think we can return without return now, does it change anything
// Find the `Return` terminator if one exists.
//
// If no `Return` terminator exists, this MIR is divergent. Just return the conservative
@ -711,7 +713,14 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
self.super_terminator(terminator, location);
match &terminator.kind {
TerminatorKind::Call { func, args, fn_span, call_source, .. } => {
TerminatorKind::Call { func, args, fn_span, .. }
| TerminatorKind::TailCall { func, args, fn_span, .. } => {
let call_source = match terminator.kind {
TerminatorKind::Call { call_source, .. } => call_source,
TerminatorKind::TailCall { .. } => CallSource::Normal,
_ => unreachable!(),
};
let ConstCx { tcx, body, param_env, .. } = *self.ccx;
let caller = self.def_id();
@ -783,7 +792,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
callee,
args: fn_args,
span: *fn_span,
call_source: *call_source,
call_source,
feature: Some(if tcx.features().const_trait_impl {
sym::effects
} else {
@ -830,7 +839,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
callee,
args: fn_args,
span: *fn_span,
call_source: *call_source,
call_source,
feature: None,
});
return;

View file

@ -108,6 +108,7 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> {
mir::TerminatorKind::UnwindTerminate(_)
| mir::TerminatorKind::Call { .. }
| mir::TerminatorKind::TailCall { .. }
| mir::TerminatorKind::Assert { .. }
| mir::TerminatorKind::FalseEdge { .. }
| mir::TerminatorKind::FalseUnwind { .. }

View file

@ -172,6 +172,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
}
TailCall { func: _, args: _, fn_span: _ } => todo!(),
Drop { place, target, unwind, replace: _ } => {
let place = self.eval_place(place)?;
let instance = Instance::resolve_drop_in_place(*self.tcx, place.layout.ty);