diff options
| author | Stuart Cook <Zalathar@users.noreply.github.com> | 2025-08-15 16:16:31 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-15 16:16:31 +1000 |
| commit | 44eb7a167c9df395c803bf113a933f668b4c278a (patch) | |
| tree | 0b352a5e4f981570afdb0135b40f873df7a56441 /compiler/rustc_codegen_ssa/src | |
| parent | 603b61df5768c95c994a4cde42898edf394c5f6f (diff) | |
| parent | fa18b3ebe29154440f6e8d9ad83021802b3aaa29 (diff) | |
| download | rust-44eb7a167c9df395c803bf113a933f668b4c278a.tar.gz rust-44eb7a167c9df395c803bf113a933f668b4c278a.zip | |
Rollup merge of #144865 - WaffleLapkin:track-tail, r=lqd
Fix tail calls to `#[track_caller]` functions We want `#[track_caller]` to be semver independent, i.e. it should not be a breaking change to add or remove it. Since it changes ABI of a function (adding an additional argument) we have to be careful to preserve this property when adding tail calls. The only way to achieve this that I can see is: - we forbid tail calls in functions which are marked with `#[track_caller]` (already implemented) - tail-calling a `#[track_caller]` marked function downgrades the tail-call to a normal call (or equivalently tail-calls the shim made by fn def to fn ptr cast) (this pr) Ideally the downgrade would be performed by a MIR pass, but that requires post mono MIR opts (cc ```@saethlin,``` rust-lang/rust#131650). For now I've changed code in cg_ssa to accomodate this behaviour (+ added a hack to mono collector so that the shim is actually generated) Additionally I added a lint, although I don't think it's strictly necessary. Alternative to rust-lang/rust#144762 (and thus closes rust-lang/rust#144762) Fixes https://github.com/rust-lang/rust/issues/144755
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/block.rs | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index e96590441fa..c3dc3e42b83 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}; @@ -35,7 +36,7 @@ enum MergingSucc { True, } -/// Indicates to the call terminator codegen whether a cal +/// Indicates to the call terminator codegen whether a call /// is a normal call or an explicit tail call. #[derive(Debug, PartialEq)] enum CallKind { @@ -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), |
