]> git.lizzy.rs Git - rust.git/commitdiff
Correctly "detuple" arguments when creating trait object shims for a trait method...
authorNiko Matsakis <niko@alum.mit.edu>
Mon, 5 Jan 2015 18:53:39 +0000 (13:53 -0500)
committerJorge Aparicio <japaricious@gmail.com>
Mon, 5 Jan 2015 22:22:18 +0000 (17:22 -0500)
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/meth.rs
src/test/run-pass/overloaded-calls-object-one-arg.rs [new file with mode: 0644]
src/test/run-pass/overloaded-calls-object-two-args.rs [new file with mode: 0644]
src/test/run-pass/overloaded-calls-object-zero-args.rs [new file with mode: 0644]

index 9454de771389e3dbbd8ee6aef1d5802fcce67fe8..65e6d7e1924b6050f8625c466203fb433a523c5e 100644 (file)
@@ -100,7 +100,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
 
     fn datum_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
                                 -> Callee<'blk, 'tcx> {
-        let DatumBlock { mut bcx, datum, .. } = expr::trans(bcx, expr);
+        let DatumBlock { bcx, datum, .. } = expr::trans(bcx, expr);
         match datum.ty.sty {
             ty::ty_bare_fn(..) => {
                 let llval = datum.to_llscalarish(bcx);
index c13516134c20c7988a940899f429e17a95a44189..e219b45d3d9f499ee07eb36d97fc97b0a27e565a 100644 (file)
@@ -599,8 +599,27 @@ pub fn trans_object_shim<'a, 'tcx>(
            bcx.val_to_string(llobject));
 
     // the remaining arguments will be, well, whatever they are
+    let input_tys =
+        match fty.abi {
+            RustCall => {
+                // unpack the tuple to extract the input type arguments:
+                match fty.sig.0.inputs[1].sty {
+                    ty::ty_tup(ref tys) => tys.as_slice(),
+                    _ => {
+                        bcx.sess().bug(
+                            format!("rust-call expects a tuple not {}",
+                                    fty.sig.0.inputs[1].repr(tcx)).as_slice());
+                    }
+                }
+            }
+            _ => {
+                // skip the self parameter:
+                fty.sig.0.inputs.slice_from(1)
+            }
+        };
+
     let llargs: Vec<_> =
-        fty.sig.0.inputs[1..].iter()
+        input_tys.iter()
         .enumerate()
         .map(|(i, _)| {
             let llarg = get_param(fcx.llfn, fcx.arg_pos(i+1) as u32);
@@ -609,6 +628,7 @@ pub fn trans_object_shim<'a, 'tcx>(
             llarg
         })
         .collect();
+
     assert!(!fcx.needs_ret_allocas);
 
     let dest =
diff --git a/src/test/run-pass/overloaded-calls-object-one-arg.rs b/src/test/run-pass/overloaded-calls-object-one-arg.rs
new file mode 100644 (file)
index 0000000..25b63cd
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tests calls to closure arguments where the closure takes 1 argument.
+// This is a bit tricky due to rust-call ABI.
+
+fn foo(f: &mut FnMut(int) -> int) -> int {
+    f(22)
+}
+
+fn main() {
+    let z = foo(&mut |x| x *100);
+    assert_eq!(z, 2200);
+}
diff --git a/src/test/run-pass/overloaded-calls-object-two-args.rs b/src/test/run-pass/overloaded-calls-object-two-args.rs
new file mode 100644 (file)
index 0000000..026ebc3
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tests calls to closure arguments where the closure takes 2 arguments.
+// This is a bit tricky due to rust-call ABI.
+
+fn foo(f: &mut FnMut(int, int) -> int) -> int {
+    f(1, 2)
+}
+
+fn main() {
+    let z = foo(&mut |x, y| x * 10 + y);
+    assert_eq!(z, 12);
+}
diff --git a/src/test/run-pass/overloaded-calls-object-zero-args.rs b/src/test/run-pass/overloaded-calls-object-zero-args.rs
new file mode 100644 (file)
index 0000000..442df1e
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tests calls to closure arguments where the closure takes 0 arguments.
+// This is a bit tricky due to rust-call ABI.
+
+fn foo(f: &mut FnMut()) -> int {
+    f()
+}
+
+fn main() {
+    let z = foo(|| 22);
+    assert_eq!(z, 22);
+}