]> git.lizzy.rs Git - rust.git/blob - src/test/run-pass/mir_trans_calls.rs
[MIR] Implement extern call support
[rust.git] / src / test / run-pass / mir_trans_calls.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![feature(rustc_attrs)]
12
13 #[rustc_mir]
14 fn test1(a: isize, b: (i32, i32), c: &[i32]) -> (isize, (i32, i32), &[i32]) {
15     // Test passing a number of arguments including a fat pointer.
16     // Also returning via an out pointer
17     fn callee(a: isize, b: (i32, i32), c: &[i32]) -> (isize, (i32, i32), &[i32]) {
18         (a, b, c)
19     }
20     callee(a, b, c)
21 }
22
23 #[rustc_mir]
24 fn test2(a: isize) -> isize {
25     // Test passing a single argument.
26     // Not using out pointer.
27     fn callee(a: isize) -> isize {
28         a
29     }
30     callee(a)
31 }
32
33 struct Foo;
34 impl Foo {
35     fn inherent_method(&self, a: isize) -> isize { a }
36 }
37
38 #[rustc_mir]
39 fn test3(x: &Foo, a: isize) -> isize {
40     // Test calling inherent method
41     x.inherent_method(a)
42 }
43
44 trait Bar {
45     fn extension_method(&self, a: isize) -> isize { a }
46 }
47 impl Bar for Foo {}
48
49 #[rustc_mir]
50 fn test4(x: &Foo, a: isize) -> isize {
51     // Test calling extension method
52     x.extension_method(a)
53 }
54
55 #[rustc_mir]
56 fn test5(x: &Bar, a: isize) -> isize {
57     // Test calling method on trait object
58     x.extension_method(a)
59 }
60
61 #[rustc_mir]
62 fn test6<T: Bar>(x: &T, a: isize) -> isize {
63     // Test calling extension method on generic callee
64     x.extension_method(a)
65 }
66
67 trait One<T = Self> {
68     fn one() -> T;
69 }
70 impl One for isize {
71     fn one() -> isize { 1 }
72 }
73
74 #[rustc_mir]
75 fn test7() -> isize {
76     // Test calling trait static method
77     <isize as One>::one()
78 }
79
80 struct Two;
81 impl Two {
82     fn two() -> isize { 2 }
83 }
84
85 #[rustc_mir]
86 fn test8() -> isize {
87     // Test calling impl static method
88     Two::two()
89 }
90
91 extern fn simple_extern(x: u32, y: (u32, u32)) -> u32 {
92     x + y.0 * y.1
93 }
94
95 #[rustc_mir]
96 fn test9() -> u32 {
97     simple_extern(41, (42, 43))
98 }
99
100 #[rustc_mir]
101 fn test_closure<F>(f: &F, x: i32, y: i32) -> i32
102     where F: Fn(i32, i32) -> i32
103 {
104     f(x, y)
105 }
106
107 #[rustc_mir]
108 fn test_fn_object(f: &Fn(i32, i32) -> i32, x: i32, y: i32) -> i32 {
109     f(x, y)
110 }
111
112 #[rustc_mir]
113 fn test_fn_impl(f: &&Fn(i32, i32) -> i32, x: i32, y: i32) -> i32 {
114     // This call goes through the Fn implementation for &Fn provided in
115     // core::ops::impls. It expands to a static Fn::call() that calls the
116     // Fn::call() implemenation of the object shim underneath.
117     f(x, y)
118 }
119
120 fn main() {
121     assert_eq!(test1(1, (2, 3), &[4, 5, 6]), (1, (2, 3), &[4, 5, 6][..]));
122     assert_eq!(test2(98), 98);
123     assert_eq!(test3(&Foo, 42), 42);
124     assert_eq!(test4(&Foo, 970), 970);
125     assert_eq!(test5(&Foo, 8576), 8576);
126     assert_eq!(test6(&Foo, 12367), 12367);
127     assert_eq!(test7(), 1);
128     assert_eq!(test8(), 2);
129     assert_eq!(test9(), 41 + 42 * 43);
130
131     let closure = |x: i32, y: i32| { x + y };
132     assert_eq!(test_closure(&closure, 100, 1), 101);
133     let function_object = &closure as &Fn(i32, i32) -> i32;
134     assert_eq!(test_fn_object(function_object, 100, 2), 102);
135     assert_eq!(test_fn_impl(&function_object, 100, 3), 103);
136 }