Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
Expand Down Expand Up @@ -1458,10 +1457,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {

match &fn_abi.ret.mode {
PassMode::Ignore | PassMode::Indirect { .. } => self.ret_void(),
PassMode::Direct(_) | PassMode::Pair { .. } => self.ret(call),
mode @ PassMode::Cast { .. } => {
bug!("Encountered `PassMode::{mode:?}` during codegen")
}
PassMode::Direct(_) | PassMode::Pair { .. } | PassMode::Cast { .. } => self.ret(call),
}
}

Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let return_dest = self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs);
target.map(|target| (return_dest, target))
}
CallKind::Tail => None,
CallKind::Tail => {
if fn_abi.ret.is_indirect() {
match self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs) {
ReturnDest::Nothing => {}
_ => bug!(
"tail calls to functions with indirect returns cannot store into a destination"
),
}
}
None
}
};

// Split the rust-call tupled arguments off.
Expand Down
20 changes: 20 additions & 0 deletions tests/ui/explicit-tail-calls/become-cast-return.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@ run-pass
//@ ignore-backends: gcc
#![expect(incomplete_features)]
#![feature(explicit_tail_calls)]

#[inline(never)]
fn leaf(_: &Box<u8>) -> [u8; 1] {
[1]
}

#[inline(never)]
fn dispatch(param: &Box<u8>) -> [u8; 1] {
become leaf(param)
}

fn main() {
let data = Box::new(0);
let out = dispatch(&data);
assert_eq!(out, [1]);
}
20 changes: 20 additions & 0 deletions tests/ui/explicit-tail-calls/become-indirect-return.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@ run-pass
//@ ignore-backends: gcc
#![expect(incomplete_features)]
#![feature(explicit_tail_calls)]

#[inline(never)]
fn op_dummy(_param: &Box<u8>) -> [u8; 24] {
[1; 24]
}

#[inline(never)]
fn dispatch(param: &Box<u8>) -> [u8; 24] {
become op_dummy(param)
}

fn main() {
let param = Box::new(0);
let result = dispatch(&param);
assert_eq!(result, [1; 24]);
}
Loading