]> git.proxmox.com Git - rustc.git/blob - src/test/run-pass/mir_trans_calls.rs
New upstream version 1.12.0+dfsg1
[rustc.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, fn_traits)]
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 #[derive(PartialEq, Eq, Debug)]
34 struct Foo;
35 impl Foo {
36 fn inherent_method(&self, a: isize) -> isize { a }
37 }
38
39 #[rustc_mir]
40 fn test3(x: &Foo, a: isize) -> isize {
41 // Test calling inherent method
42 x.inherent_method(a)
43 }
44
45 trait Bar {
46 fn extension_method(&self, a: isize) -> isize { a }
47 }
48 impl Bar for Foo {}
49
50 #[rustc_mir]
51 fn test4(x: &Foo, a: isize) -> isize {
52 // Test calling extension method
53 x.extension_method(a)
54 }
55
56 #[rustc_mir]
57 fn test5(x: &Bar, a: isize) -> isize {
58 // Test calling method on trait object
59 x.extension_method(a)
60 }
61
62 #[rustc_mir]
63 fn test6<T: Bar>(x: &T, a: isize) -> isize {
64 // Test calling extension method on generic callee
65 x.extension_method(a)
66 }
67
68 trait One<T = Self> {
69 fn one() -> T;
70 }
71 impl One for isize {
72 fn one() -> isize { 1 }
73 }
74
75 #[rustc_mir]
76 fn test7() -> isize {
77 // Test calling trait static method
78 <isize as One>::one()
79 }
80
81 struct Two;
82 impl Two {
83 fn two() -> isize { 2 }
84 }
85
86 #[rustc_mir]
87 fn test8() -> isize {
88 // Test calling impl static method
89 Two::two()
90 }
91
92 extern fn simple_extern(x: u32, y: (u32, u32)) -> u32 {
93 x + y.0 * y.1
94 }
95
96 #[rustc_mir]
97 fn test9() -> u32 {
98 simple_extern(41, (42, 43))
99 }
100
101 #[rustc_mir]
102 fn test_closure<F>(f: &F, x: i32, y: i32) -> i32
103 where F: Fn(i32, i32) -> i32
104 {
105 f(x, y)
106 }
107
108 #[rustc_mir]
109 fn test_fn_object(f: &Fn(i32, i32) -> i32, x: i32, y: i32) -> i32 {
110 f(x, y)
111 }
112
113 #[rustc_mir]
114 fn test_fn_impl(f: &&Fn(i32, i32) -> i32, x: i32, y: i32) -> i32 {
115 // This call goes through the Fn implementation for &Fn provided in
116 // core::ops::impls. It expands to a static Fn::call() that calls the
117 // Fn::call() implementation of the object shim underneath.
118 f(x, y)
119 }
120
121 #[rustc_mir]
122 fn test_fn_direct_call<F>(f: &F, x: i32, y: i32) -> i32
123 where F: Fn(i32, i32) -> i32
124 {
125 f.call((x, y))
126 }
127
128 #[rustc_mir]
129 fn test_fn_const_call<F>(f: &F) -> i32
130 where F: Fn(i32, i32) -> i32
131 {
132 f.call((100, -1))
133 }
134
135 #[rustc_mir]
136 fn test_fn_nil_call<F>(f: &F) -> i32
137 where F: Fn() -> i32
138 {
139 f()
140 }
141
142 #[rustc_mir]
143 fn test_fn_transmute_zst(x: ()) -> [(); 1] {
144 fn id<T>(x: T) -> T {x}
145
146 id(unsafe {
147 std::mem::transmute(x)
148 })
149 }
150
151 #[rustc_mir]
152 fn test_fn_ignored_pair() -> ((), ()) {
153 ((), ())
154 }
155
156 #[rustc_mir]
157 fn test_fn_ignored_pair_0() {
158 test_fn_ignored_pair().0
159 }
160
161 #[rustc_mir]
162 fn id<T>(x: T) -> T { x }
163
164 #[rustc_mir]
165 fn ignored_pair_named() -> (Foo, Foo) {
166 (Foo, Foo)
167 }
168
169 #[rustc_mir]
170 fn test_fn_ignored_pair_named() -> (Foo, Foo) {
171 id(ignored_pair_named())
172 }
173
174 #[rustc_mir]
175 fn test_fn_nested_pair(x: &((f32, f32), u32)) -> (f32, f32) {
176 let y = *x;
177 let z = y.0;
178 (z.0, z.1)
179 }
180
181 fn main() {
182 assert_eq!(test1(1, (2, 3), &[4, 5, 6]), (1, (2, 3), &[4, 5, 6][..]));
183 assert_eq!(test2(98), 98);
184 assert_eq!(test3(&Foo, 42), 42);
185 assert_eq!(test4(&Foo, 970), 970);
186 assert_eq!(test5(&Foo, 8576), 8576);
187 assert_eq!(test6(&Foo, 12367), 12367);
188 assert_eq!(test7(), 1);
189 assert_eq!(test8(), 2);
190 assert_eq!(test9(), 41 + 42 * 43);
191
192 let r = 3;
193 let closure = |x: i32, y: i32| { r*(x + (y*2)) };
194 assert_eq!(test_fn_const_call(&closure), 294);
195 assert_eq!(test_closure(&closure, 100, 1), 306);
196 let function_object = &closure as &Fn(i32, i32) -> i32;
197 assert_eq!(test_fn_object(function_object, 100, 2), 312);
198 assert_eq!(test_fn_impl(&function_object, 100, 3), 318);
199 assert_eq!(test_fn_direct_call(&closure, 100, 4), 324);
200
201 assert_eq!(test_fn_nil_call(&(|| 42)), 42);
202 assert_eq!(test_fn_transmute_zst(()), [()]);
203
204 assert_eq!(test_fn_ignored_pair_0(), ());
205 assert_eq!(test_fn_ignored_pair_named(), (Foo, Foo));
206 assert_eq!(test_fn_nested_pair(&((1.0, 2.0), 0)), (1.0, 2.0));
207 }