From aebbeceb88ccfa2ebf80a1c0dc97838b79406387 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 20 Jun 2023 10:05:16 +0000 Subject: [PATCH] Handle rust-call abi without self argument Fixes #1236 --- example/std_example.rs | 19 ++++++++++++++++++- src/abi/mod.rs | 13 +++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/example/std_example.rs b/example/std_example.rs index b762bba70eb..490cc2404f6 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -1,4 +1,12 @@ -#![feature(core_intrinsics, generators, generator_trait, is_sorted, repr_simd)] +#![feature( + core_intrinsics, + generators, + generator_trait, + is_sorted, + repr_simd, + tuple_trait, + unboxed_closures +)] #[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; @@ -157,6 +165,8 @@ fn main() { foo(I64X2(0, 0)); transmute_fat_pointer(); + + rust_call_abi(); } fn panic(_: u128) { @@ -174,6 +184,13 @@ fn transmute_fat_pointer() -> TwoPtrs { unsafe { transmute::<_, TwoPtrs>("true !") } } +extern "rust-call" fn rust_call_abi_callee(_: T) {} + +fn rust_call_abi() { + rust_call_abi_callee(()); + rust_call_abi_callee((1, 2)); +} + #[repr(simd)] struct I64X2(i64, i64); diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 84e09cf0abe..f41e6ce67c0 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -445,9 +445,14 @@ pub(crate) fn codegen_terminator_call<'tcx>( // Unpack arguments tuple for closures let mut args = if fn_sig.abi() == Abi::RustCall { - assert_eq!(args.len(), 2, "rust-call abi requires two arguments"); - let self_arg = codegen_call_argument_operand(fx, &args[0]); - let pack_arg = codegen_call_argument_operand(fx, &args[1]); + let (self_arg, pack_arg) = match args { + [pack_arg] => (None, codegen_call_argument_operand(fx, pack_arg)), + [self_arg, pack_arg] => ( + Some(codegen_call_argument_operand(fx, self_arg)), + codegen_call_argument_operand(fx, pack_arg), + ), + _ => panic!("rust-call abi requires one or two arguments"), + }; let tupled_arguments = match pack_arg.value.layout().ty.kind() { ty::Tuple(ref tupled_arguments) => tupled_arguments, @@ -455,7 +460,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( }; let mut args = Vec::with_capacity(1 + tupled_arguments.len()); - args.push(self_arg); + args.extend(self_arg); for i in 0..tupled_arguments.len() { args.push(CallArgument { value: pack_arg.value.value_field(fx, FieldIdx::new(i)),