]>
Commit | Line | Data |
---|---|---|
1b1a35ee | 1 | // run-pass |
0731742a | 2 | |
1b1a35ee | 3 | #![feature(const_fn_floating_point_arithmetic)] |
0731742a XL |
4 | |
5 | struct Foo<T>(T); | |
6 | struct Bar<T> { x: T } | |
7 | struct W(f32); | |
8 | struct A { a: f32 } | |
9 | ||
74b04a01 | 10 | #[allow(redundant_semicolons)] |
0731742a XL |
11 | const fn basics((a,): (f32,)) -> f32 { |
12 | // Deferred assignment: | |
13 | let b: f32; | |
14 | b = a + 1.0; | |
15 | ||
16 | // Immediate assignment: | |
17 | let c: f32 = b + 1.0; | |
18 | ||
19 | // Mutables: | |
20 | let mut d: f32 = c + 1.0; | |
21 | d = d + 1.0; | |
22 | // +4 so far. | |
23 | ||
24 | // No effect statements work: | |
25 | ; ; | |
26 | 1; | |
27 | ||
28 | // Array projection | |
29 | let mut arr: [f32; 1] = [0.0]; | |
30 | arr[0] = 1.0; | |
31 | d = d + arr[0]; | |
32 | // +5 | |
33 | ||
34 | // Field projection: | |
35 | let mut foo: Foo<f32> = Foo(0.0); | |
36 | let mut bar: Bar<f32> = Bar { x: 0.0 }; | |
37 | foo.0 = 1.0; | |
38 | bar.x = 1.0; | |
39 | d = d + foo.0 + bar.x; | |
40 | // +7 | |
41 | ||
42 | // Array + Field projection: | |
43 | let mut arr: [Foo<f32>; 1] = [Foo(0.0)]; | |
44 | arr[0].0 = 1.0; | |
45 | d = d + arr[0].0; | |
46 | let mut arr: [Bar<f32>; 1] = [Bar { x: 0.0 }]; | |
47 | arr[0].x = 1.0; | |
48 | d = d + arr[0].x; | |
49 | // +9 | |
50 | ||
51 | // Field + Array projection: | |
52 | let mut arr: Foo<[f32; 1]> = Foo([0.0]); | |
53 | (arr.0)[0] = 1.0; | |
54 | d = d + (arr.0)[0]; | |
55 | let mut arr: Bar<[f32; 1]> = Bar { x: [0.0] }; | |
56 | arr.x[0] = 1.0; | |
57 | d = d + arr.x[0]; | |
58 | // +11 | |
59 | ||
60 | d | |
61 | } | |
62 | ||
63 | const fn add_assign(W(a): W) -> f32 { | |
64 | // Mutables: | |
65 | let mut d: f32 = a + 1.0; | |
66 | d += 1.0; | |
67 | // +2 so far. | |
68 | ||
69 | // Array projection | |
70 | let mut arr: [f32; 1] = [0.0]; | |
71 | arr[0] += 1.0; | |
72 | d += arr[0]; | |
73 | // +3 | |
74 | ||
75 | // Field projection: | |
76 | let mut foo: Foo<f32> = Foo(0.0); | |
77 | let mut bar: Bar<f32> = Bar { x: 0.0 }; | |
78 | foo.0 += 1.0; | |
79 | bar.x += 1.0; | |
80 | d += foo.0 + bar.x; | |
81 | // +5 | |
82 | ||
83 | // Array + Field projection: | |
84 | let mut arr: [Foo<f32>; 1] = [Foo(0.0)]; | |
85 | arr[0].0 += 1.0; | |
86 | d += arr[0].0; | |
87 | let mut arr: [Bar<f32>; 1] = [Bar { x: 0.0 }]; | |
88 | arr[0].x += 1.0; | |
89 | d += arr[0].x; | |
90 | // +7 | |
91 | ||
92 | // Field + Array projection: | |
93 | let mut arr: Foo<[f32; 1]> = Foo([0.0]); | |
94 | (arr.0)[0] += 1.0; | |
95 | d += (arr.0)[0]; | |
96 | let mut arr: Bar<[f32; 1]> = Bar { x: [0.0] }; | |
97 | arr.x[0] += 1.0; | |
98 | d += arr.x[0]; | |
99 | // +9 | |
100 | ||
101 | d | |
102 | } | |
103 | ||
104 | const fn mul_assign(A { a }: A) -> f32 { | |
105 | // Mutables: | |
106 | let mut d: f32 = a + 1.0; | |
107 | d *= 2.0; | |
108 | // 2^1 * (a + 1) | |
109 | ||
110 | // Array projection | |
111 | let mut arr: [f32; 1] = [1.0]; | |
112 | arr[0] *= 2.0; | |
113 | d *= arr[0]; | |
114 | // 2^2 * (a + 1) | |
115 | ||
116 | // Field projection: | |
117 | let mut foo: Foo<f32> = Foo(1.0); | |
118 | let mut bar: Bar<f32> = Bar { x: 1.0 }; | |
119 | foo.0 *= 2.0; | |
120 | bar.x *= 2.0; | |
121 | d *= foo.0 + bar.x; | |
122 | // 2^4 * (a + 1) | |
123 | ||
124 | // Array + Field projection: | |
125 | let mut arr: [Foo<f32>; 1] = [Foo(1.0)]; | |
126 | arr[0].0 *= 2.0; | |
127 | d *= arr[0].0; | |
128 | let mut arr: [Bar<f32>; 1] = [Bar { x: 1.0 }]; | |
129 | arr[0].x *= 2.0; | |
130 | d *= arr[0].x; | |
131 | // 2^6 * (a + 1) | |
132 | ||
133 | // Field + Array projection: | |
134 | let mut arr: Foo<[f32; 1]> = Foo([1.0]); | |
135 | (arr.0)[0] *= 2.0; | |
136 | d *= (arr.0)[0]; | |
137 | let mut arr: Bar<[f32; 1]> = Bar { x: [1.0] }; | |
138 | arr.x[0] *= 2.0; | |
139 | d *= arr.x[0]; | |
140 | // 2^8 * (a + 1) | |
141 | ||
142 | d | |
143 | } | |
144 | ||
145 | const fn div_assign(a: [f32; 1]) -> f32 { | |
146 | let a = a[0]; | |
147 | // Mutables: | |
148 | let mut d: f32 = 1024.0 * a; | |
149 | d /= 2.0; | |
150 | // 512 | |
151 | ||
152 | // Array projection | |
153 | let mut arr: [f32; 1] = [4.0]; | |
154 | arr[0] /= 2.0; | |
155 | d /= arr[0]; | |
156 | // 256 | |
157 | ||
158 | // Field projection: | |
159 | let mut foo: Foo<f32> = Foo(4.0); | |
160 | let mut bar: Bar<f32> = Bar { x: 4.0 }; | |
161 | foo.0 /= 2.0; | |
162 | bar.x /= 2.0; | |
163 | d /= foo.0; | |
164 | d /= bar.x; | |
165 | // 64 | |
166 | ||
167 | // Array + Field projection: | |
168 | let mut arr: [Foo<f32>; 1] = [Foo(4.0)]; | |
169 | arr[0].0 /= 2.0; | |
170 | d /= arr[0].0; | |
171 | let mut arr: [Bar<f32>; 1] = [Bar { x: 4.0 }]; | |
172 | arr[0].x /= 2.0; | |
173 | d /= arr[0].x; | |
174 | // 16 | |
175 | ||
176 | // Field + Array projection: | |
177 | let mut arr: Foo<[f32; 1]> = Foo([4.0]); | |
178 | (arr.0)[0] /= 2.0; | |
179 | d /= (arr.0)[0]; | |
180 | let mut arr: Bar<[f32; 1]> = Bar { x: [4.0] }; | |
181 | arr.x[0] /= 2.0; | |
182 | d /= arr.x[0]; | |
183 | // 4 | |
184 | ||
185 | d | |
186 | } | |
187 | ||
188 | const fn rem_assign(W(a): W) -> f32 { | |
189 | // Mutables: | |
190 | let mut d: f32 = a; | |
191 | d %= 10.0; | |
192 | d += 10.0; | |
193 | ||
194 | // Array projection | |
195 | let mut arr: [f32; 1] = [3.0]; | |
196 | arr[0] %= 2.0; | |
197 | d %= 9.0 + arr[0]; | |
198 | d += 10.0; | |
199 | ||
200 | // Field projection: | |
201 | let mut foo: Foo<f32> = Foo(5.0); | |
202 | let mut bar: Bar<f32> = Bar { x: 7.0 }; | |
203 | foo.0 %= 2.0; | |
204 | bar.x %= 2.0; | |
205 | d %= 8.0 + foo.0 + bar.x; | |
206 | d += 10.0; | |
207 | ||
208 | // Array + Field projection: | |
209 | let mut arr: [Foo<f32>; 1] = [Foo(4.0)]; | |
210 | arr[0].0 %= 3.0; | |
211 | d %= 9.0 + arr[0].0; | |
212 | d += 10.0; | |
213 | let mut arr: [Bar<f32>; 1] = [Bar { x: 7.0 }]; | |
214 | arr[0].x %= 3.0; | |
215 | d %= 9.0 + arr[0].x; | |
216 | d += 10.0; | |
217 | ||
218 | // Field + Array projection: | |
219 | let mut arr: Foo<[f32; 1]> = Foo([6.0]); | |
220 | (arr.0)[0] %= 5.0; | |
221 | d %= 9.0 + (arr.0)[0]; | |
222 | let mut arr: Bar<[f32; 1]> = Bar { x: [11.0] }; | |
223 | arr.x[0] %= 5.0; | |
224 | d %= 9.0 + arr.x[0]; | |
225 | ||
226 | d | |
227 | } | |
228 | ||
229 | const fn sub_assign(W(a): W) -> f32 { | |
230 | // Mutables: | |
231 | let mut d: f32 = a; | |
232 | d -= 1.0; | |
233 | ||
234 | // Array projection | |
235 | let mut arr: [f32; 1] = [2.0]; | |
236 | arr[0] -= 1.0; | |
237 | d -= arr[0]; | |
238 | ||
239 | // Field projection: | |
240 | let mut foo: Foo<f32> = Foo(2.0); | |
241 | let mut bar: Bar<f32> = Bar { x: 2.0 }; | |
242 | foo.0 -= 1.0; | |
243 | bar.x -= 1.0; | |
244 | d -= foo.0 + bar.x; | |
245 | ||
246 | // Array + Field projection: | |
247 | let mut arr: [Foo<f32>; 1] = [Foo(2.0)]; | |
248 | arr[0].0 -= 1.0; | |
249 | d -= arr[0].0; | |
250 | let mut arr: [Bar<f32>; 1] = [Bar { x: 2.0 }]; | |
251 | arr[0].x -= 1.0; | |
252 | d -= arr[0].x; | |
253 | ||
254 | // Field + Array projection: | |
255 | let mut arr: Foo<[f32; 1]> = Foo([2.0]); | |
256 | (arr.0)[0] -= 1.0; | |
257 | d -= (arr.0)[0]; | |
258 | let mut arr: Bar<[f32; 1]> = Bar { x: [2.0] }; | |
259 | arr.x[0] -= 1.0; | |
260 | d -= arr.x[0]; | |
261 | ||
262 | d | |
263 | } | |
264 | ||
265 | macro_rules! test { | |
266 | ($c:ident, $e:expr, $r:expr) => { | |
267 | const $c: f32 = $e; | |
268 | assert_eq!($c, $r); | |
269 | assert_eq!($e, $r); | |
270 | } | |
271 | } | |
272 | ||
273 | fn main() { | |
274 | test!(BASICS, basics((2.0,)), 13.0); | |
275 | test!(ADD, add_assign(W(1.0)), 10.0); | |
276 | test!(MUL, mul_assign(A { a: 0.0 }), 256.0); | |
277 | test!(DIV, div_assign([1.0]), 4.0); | |
278 | test!(REM, rem_assign(W(5.0)), 5.0); | |
279 | test!(SUB, sub_assign(W(8.0)), 0.0); | |
280 | } |