diff options
| author | Waffle Lapkin <waffle.lapkin@gmail.com> | 2025-08-03 17:03:25 +0200 |
|---|---|---|
| committer | Waffle Lapkin <waffle.lapkin@gmail.com> | 2025-08-13 02:26:52 +0200 |
| commit | 85d1c89e0fe2c9db253c6e4e53a19302584a2dfd (patch) | |
| tree | d1f50304add0dc7d890eac4d2831666c7b499c65 /compiler/rustc_codegen_ssa/src | |
| parent | 07b7dc90ee4df5815dbb91ef8e98cb93571230f5 (diff) | |
| download | rust-85d1c89e0fe2c9db253c6e4e53a19302584a2dfd.tar.gz rust-85d1c89e0fe2c9db253c6e4e53a19302584a2dfd.zip | |
fix tail calls to `#[track_caller]` functions
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/block.rs | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index e96590441fa..f151e24947e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -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), |
