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_monomorphize | |
| parent | 07b7dc90ee4df5815dbb91ef8e98cb93571230f5 (diff) | |
| download | rust-85d1c89e0fe2c9db253c6e4e53a19302584a2dfd.tar.gz rust-85d1c89e0fe2c9db253c6e4e53a19302584a2dfd.zip | |
fix tail calls to `#[track_caller]` functions
Diffstat (limited to 'compiler/rustc_monomorphize')
| -rw-r--r-- | compiler/rustc_monomorphize/src/collector.rs | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 35b80a9b96f..5c94242b450 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -788,7 +788,35 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { // *Before* monomorphizing, record that we already handled this mention. self.used_mentioned_items.insert(MentionedItem::Fn(callee_ty)); let callee_ty = self.monomorphize(callee_ty); - visit_fn_use(self.tcx, callee_ty, true, source, &mut self.used_items) + + // HACK(explicit_tail_calls): collect tail calls to `#[track_caller]` functions as indirect, + // because we later call them as such, to prevent issues with ABI incompatibility. + // Ideally we'd replace such tail calls with normal call + return, but this requires + // post-mono MIR optimizations, which we don't yet have. + let force_indirect_call = + if matches!(terminator.kind, mir::TerminatorKind::TailCall { .. }) + && let &ty::FnDef(def_id, args) = callee_ty.kind() + && let instance = ty::Instance::expect_resolve( + self.tcx, + ty::TypingEnv::fully_monomorphized(), + def_id, + args, + source, + ) + && instance.def.requires_caller_location(self.tcx) + { + true + } else { + false + }; + + visit_fn_use( + self.tcx, + callee_ty, + !force_indirect_call, + source, + &mut self.used_items, + ) } mir::TerminatorKind::Drop { ref place, .. } => { let ty = place.ty(self.body, self.tcx).ty; |
