about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--example/std_example.rs19
-rw-r--r--src/abi/mod.rs13
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: std::marker::Tuple>(_: 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)),