fix tail calls to #[track_caller] functions

This commit is contained in:
Waffle Lapkin
2025-08-03 17:03:25 +02:00
parent 07b7dc90ee
commit 85d1c89e0f
9 changed files with 134 additions and 8 deletions

View File

@@ -5,6 +5,7 @@ use rustc_ast as ast;
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_data_structures::packed::Pu128;
use rustc_hir::lang_items::LangItem;
use rustc_lint_defs::builtin::TAIL_CALL_TRACK_CALLER;
use rustc_middle::mir::{self, AssertKind, InlineAsmMacro, SwitchTargets, UnwindTerminateReason};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
@@ -906,7 +907,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
fn_span,
);
let instance = match instance.def {
match instance.def {
// We don't need AsyncDropGlueCtorShim here because it is not `noop func`,
// it is `func returning noop future`
ty::InstanceKind::DropGlue(_, None) => {
@@ -995,14 +996,35 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
intrinsic.name,
);
}
instance
(Some(instance), None)
}
}
}
_ => instance,
};
(Some(instance), None)
_ if kind == CallKind::Tail
&& instance.def.requires_caller_location(bx.tcx()) =>
{
if let Some(hir_id) =
terminator.source_info.scope.lint_root(&self.mir.source_scopes)
{
let msg = "tail calling a function marked with `#[track_caller]` has no special effect";
bx.tcx().node_lint(TAIL_CALL_TRACK_CALLER, hir_id, |d| {
_ = d.primary_message(msg).span(fn_span)
});
}
let instance = ty::Instance::resolve_for_fn_ptr(
bx.tcx(),
bx.typing_env(),
def_id,
generic_args,
)
.unwrap();
(None, Some(bx.get_fn_addr(instance)))
}
_ => (Some(instance), None),
}
}
ty::FnPtr(..) => (None, Some(callee.immediate())),
_ => bug!("{} is not callable", callee.layout.ty),