]> git.lizzy.rs Git - rust.git/blob - src/test/ui/mir/mir_codegen_calls.rs
Merge commit 'e18101137866b79045fee0ef996e696e68c920b4' into clippyup
[rust.git] / src / test / ui / mir / mir_codegen_calls.rs
1 // run-pass
2 #![feature(fn_traits, test)]
3
4 extern crate test;
5
6 fn test1(a: isize, b: (i32, i32), c: &[i32]) -> (isize, (i32, i32), &[i32]) {
7     // Test passing a number of arguments including a fat pointer.
8     // Also returning via an out pointer
9     fn callee(a: isize, b: (i32, i32), c: &[i32]) -> (isize, (i32, i32), &[i32]) {
10         (a, b, c)
11     }
12     callee(a, b, c)
13 }
14
15 fn test2(a: isize) -> isize {
16     // Test passing a single argument.
17     // Not using out pointer.
18     fn callee(a: isize) -> isize {
19         a
20     }
21     callee(a)
22 }
23
24 #[derive(PartialEq, Eq, Debug)]
25 struct Foo;
26 impl Foo {
27     fn inherent_method(&self, a: isize) -> isize { a }
28 }
29
30 fn test3(x: &Foo, a: isize) -> isize {
31     // Test calling inherent method
32     x.inherent_method(a)
33 }
34
35 trait Bar {
36     fn extension_method(&self, a: isize) -> isize { a }
37 }
38 impl Bar for Foo {}
39
40 fn test4(x: &Foo, a: isize) -> isize {
41     // Test calling extension method
42     x.extension_method(a)
43 }
44
45 fn test5(x: &dyn Bar, a: isize) -> isize {
46     // Test calling method on trait object
47     x.extension_method(a)
48 }
49
50 fn test6<T: Bar>(x: &T, a: isize) -> isize {
51     // Test calling extension method on generic callee
52     x.extension_method(a)
53 }
54
55 trait One<T = Self> {
56     fn one() -> T;
57 }
58 impl One for isize {
59     fn one() -> isize { 1 }
60 }
61
62 fn test7() -> isize {
63     // Test calling trait static method
64     <isize as One>::one()
65 }
66
67 struct Two;
68 impl Two {
69     fn two() -> isize { 2 }
70 }
71
72 fn test8() -> isize {
73     // Test calling impl static method
74     Two::two()
75 }
76
77 #[allow(improper_ctypes_definitions)]
78 extern "C" fn simple_extern(x: u32, y: (u32, u32)) -> u32 {
79     x + y.0 * y.1
80 }
81
82 fn test9() -> u32 {
83     simple_extern(41, (42, 43))
84 }
85
86 fn test_closure<F>(f: &F, x: i32, y: i32) -> i32
87     where F: Fn(i32, i32) -> i32
88 {
89     f(x, y)
90 }
91
92 fn test_fn_object(f: &dyn Fn(i32, i32) -> i32, x: i32, y: i32) -> i32 {
93     f(x, y)
94 }
95
96 fn test_fn_impl(f: &&dyn Fn(i32, i32) -> i32, x: i32, y: i32) -> i32 {
97     // This call goes through the Fn implementation for &Fn provided in
98     // core::ops::impls. It expands to a static Fn::call() that calls the
99     // Fn::call() implementation of the object shim underneath.
100     f(x, y)
101 }
102
103 fn test_fn_direct_call<F>(f: &F, x: i32, y: i32) -> i32
104     where F: Fn(i32, i32) -> i32
105 {
106     f.call((x, y))
107 }
108
109 fn test_fn_const_call<F>(f: &F) -> i32
110     where F: Fn(i32, i32) -> i32
111 {
112     f.call((100, -1))
113 }
114
115 fn test_fn_nil_call<F>(f: &F) -> i32
116     where F: Fn() -> i32
117 {
118     f()
119 }
120
121 fn test_fn_transmute_zst(x: ()) -> [(); 1] {
122     fn id<T>(x: T) -> T {x}
123
124     id(unsafe {
125         std::mem::transmute(x)
126     })
127 }
128
129 fn test_fn_ignored_pair() -> ((), ()) {
130     ((), ())
131 }
132
133 fn test_fn_ignored_pair_0() {
134     test_fn_ignored_pair().0
135 }
136
137 fn id<T>(x: T) -> T { x }
138
139 fn ignored_pair_named() -> (Foo, Foo) {
140     (Foo, Foo)
141 }
142
143 fn test_fn_ignored_pair_named() -> (Foo, Foo) {
144     id(ignored_pair_named())
145 }
146
147 fn test_fn_nested_pair(x: &((f32, f32), u32)) -> (f32, f32) {
148     let y = *x;
149     let z = y.0;
150     (z.0, z.1)
151 }
152
153 fn test_fn_const_arg_by_ref(mut a: [u64; 4]) -> u64 {
154     // Mutate the by-reference argument, which won't work with
155     // a non-immediate constant unless it's copied to the stack.
156     let a = test::black_box(&mut a);
157     a[0] += a[1];
158     a[0] += a[2];
159     a[0] += a[3];
160     a[0]
161 }
162
163 fn main() {
164     assert_eq!(test1(1, (2, 3), &[4, 5, 6]), (1, (2, 3), &[4, 5, 6][..]));
165     assert_eq!(test2(98), 98);
166     assert_eq!(test3(&Foo, 42), 42);
167     assert_eq!(test4(&Foo, 970), 970);
168     assert_eq!(test5(&Foo, 8576), 8576);
169     assert_eq!(test6(&Foo, 12367), 12367);
170     assert_eq!(test7(), 1);
171     assert_eq!(test8(), 2);
172     assert_eq!(test9(), 41 + 42 * 43);
173
174     let r = 3;
175     let closure = |x: i32, y: i32| { r*(x + (y*2)) };
176     assert_eq!(test_fn_const_call(&closure), 294);
177     assert_eq!(test_closure(&closure, 100, 1), 306);
178     let function_object = &closure as &dyn Fn(i32, i32) -> i32;
179     assert_eq!(test_fn_object(function_object, 100, 2), 312);
180     assert_eq!(test_fn_impl(&function_object, 100, 3), 318);
181     assert_eq!(test_fn_direct_call(&closure, 100, 4), 324);
182
183     assert_eq!(test_fn_nil_call(&(|| 42)), 42);
184     assert_eq!(test_fn_transmute_zst(()), [()]);
185
186     assert_eq!(test_fn_ignored_pair_0(), ());
187     assert_eq!(test_fn_ignored_pair_named(), (Foo, Foo));
188     assert_eq!(test_fn_nested_pair(&((1.0, 2.0), 0)), (1.0, 2.0));
189
190     const ARRAY: [u64; 4] = [1, 2, 3, 4];
191     assert_eq!(test_fn_const_arg_by_ref(ARRAY), 1 + 2 + 3 + 4);
192 }