// We trans them in place in `trans_intrinsic_call`
assert!(abi != synabi::RustIntrinsic);
+ let is_rust_fn = abi == synabi::Rust || abi == synabi::RustCall;
+
// Generate a location to store the result. If the user does
// not care about the result, just make a stack slot.
let opt_llretslot = match dest {
None
}
Some(expr::SaveIn(dst)) => Some(dst),
- Some(expr::Ignore) => {
+ Some(expr::Ignore) if !is_rust_fn ||
+ type_of::return_uses_outptr(ccx, ret_ty) ||
+ ty::type_needs_drop(bcx.tcx(), ret_ty) => {
if !type_is_zero_size(ccx, ret_ty) {
Some(alloc_ty(bcx, ret_ty, "__llret"))
} else {
Some(C_undef(llty.ptr_to()))
}
}
+ Some(expr::Ignore) => None
};
let mut llresult = unsafe {
// and done, either the return value of the function will have been
// written in opt_llretslot (if it is Some) or `llresult` will be
// set appropriately (otherwise).
- if abi == synabi::Rust || abi == synabi::RustCall {
+ if is_rust_fn {
let mut llargs = Vec::new();
// Push the out-pointer if we use an out-pointer for this
// If the caller doesn't care about the result of this fn call,
// drop the temporary slot we made.
- match dest {
- None => {
- assert!(!type_of::return_uses_outptr(bcx.ccx(), ret_ty));
- }
- Some(expr::Ignore) => {
+ match (dest, opt_llretslot) {
+ (Some(expr::Ignore), Some(llretslot)) => {
// drop the value if it is not being saved.
- bcx = glue::drop_ty(bcx, opt_llretslot.unwrap(), ret_ty);
+ bcx = glue::drop_ty(bcx, llretslot, ret_ty);
}
- Some(expr::SaveIn(_)) => { }
+ _ => {}
}
if ty::type_is_bot(ret_ty) {