decay_type/
lib.rs

1#[doc(hidden)]
2#[macro_export]
3macro_rules! decay_type {
4    // Order matches from least general to most. This is so the more general
5    // matches aren't used when there are more specific mathces available. If
6    // this happens, then the lifetime of the type (e.g. &, &mut) will be
7    // stored in the `typename` arg, meaning the decayed type will still contain
8    // the lifetime (which we want to avoid).
9    (&&'static mut str) => (String);
10    (&&'static str) => (String);
11    (&'static mut str) => (String);
12    (&'static str) => (String);
13    (&& mut str) => (String);
14    (&& str) => (String);
15    (& mut str) => (String);
16    (& str) => (String);
17    (str) => (String);
18    (&&'static mut $($typename:tt)*) => ($($typename)*);
19    (&&'static $($typename:tt)*) => ($($typename)*);
20    (&'static mut $($typename:tt)*) => ($($typename)*);
21    (&'static $($typename:tt)*) => ($($typename)*);
22    (&& mut $($typename:tt)*) => ($($typename)*);
23    (&& $($typename:tt)*) => ($($typename)*);
24    (& mut $($typename:tt)*) => ($($typename)*);
25    (& $($typename:tt)*) => ($($typename)*);
26    ($($typename:tt)*) => ($($typename)*);
27}
28
29#[cfg(test)]
30mod tests {
31    use std::any::TypeId;
32
33    // Compile-time tests. These ensure that the decay macro works correctly
34    // when using it to *declare* varialbes with decayed types.
35    //
36    // The tests ensure both primitive, string and complex types are properly
37    // decayed. If they are not properly decayed, buidling the test will produce
38    // a compiler error because the reference types have to explicit lifetime
39    // (required when declaring struct fields as references).
40
41    #[test]
42    fn test_decaying_integral_types_in_struct_definition() {
43        #[allow(dead_code)]
44        struct IntegralTypeDecay {
45            value: decay_type!(i32),
46            reference: decay_type!(&i32),
47            mut_ref: decay_type!(&mut i32),
48            double_ref: decay_type!(&&i32),
49            double_mutable_ref: decay_type!(&&mut i32),
50            static_ref: decay_type!(&'static i32),
51            static_mutable_ref: decay_type!(&'static mut i32),
52            double_static_ref: decay_type!(&&'static i32),
53            double_static_mutable_ref: decay_type!(&&'static mut i32)
54        }
55    }
56
57    #[test]
58    fn test_decaying_str_types_in_struct_definition() {
59        #[allow(dead_code)]
60        struct StrTypeDecay {
61            value: decay_type!(str),
62            reference: decay_type!(&str),
63            mut_ref: decay_type!(&mut str),
64            double_ref: decay_type!(&&str),
65            double_mutable_ref: decay_type!(&&mut str),
66            static_ref: decay_type!(&'static str),
67            static_mutable_ref: decay_type!(&'static mut str),
68            double_static_ref: decay_type!(&&'static str),
69            double_static_mutable_ref: decay_type!(&&'static mut str)
70        }
71    }
72
73    #[test]
74    fn test_decaying_string_types_in_struct_definition() {
75        #[allow(dead_code)]
76        struct StringTypeDecay {
77            value: decay_type!(String),
78            reference: decay_type!(&String),
79            mut_ref: decay_type!(&mut String),
80            double_ref: decay_type!(&&String),
81            double_mutable_ref: decay_type!(&&mut String),
82            static_ref: decay_type!(&'static String),
83            static_mutable_ref: decay_type!(&'static mut String),
84            double_static_ref: decay_type!(&&'static String),
85            double_static_mutable_ref: decay_type!(&&'static mut String)
86        }
87    }
88
89    #[test]
90    fn test_decaying_struct_types_in_struct_definition() {
91        #[allow(dead_code)]
92        struct Person {
93            name: String,
94            age: u8
95        }
96
97        #[allow(dead_code)]
98        struct StructTypeDecay {
99            value: decay_type!(Person),
100            reference: decay_type!(&Person),
101            mut_ref: decay_type!(&mut Person),
102            double_ref: decay_type!(&&Person),
103            double_mutable_ref: decay_type!(&&mut Person),
104            static_ref: decay_type!(&'static Person),
105            static_mutable_ref: decay_type!(&'static mut Person),
106            double_static_ref: decay_type!(&&'static Person),
107            double_static_mutable_ref: decay_type!(&&'static mut Person)
108        }
109    }
110
111    #[test]
112    fn test_decaying_generic_types_in_struct_definition() {
113        #[allow(dead_code)]
114        struct Foo<T> {
115            value: T
116        }
117
118        #[allow(dead_code)]
119        struct GenericStructTypeDecay {
120            value: decay_type!(Foo<i32>),
121            reference: decay_type!(&Foo<i32>),
122            mut_ref: decay_type!(&mut Foo<i32>),
123            double_ref: decay_type!(&&Foo<i32>),
124            double_mutable_ref: decay_type!(&&mut Foo<i32>),
125            static_ref: decay_type!(&'static Foo<i32>),
126            static_mutable_ref: decay_type!(&'static mut Foo<i32>),
127            double_static_ref: decay_type!(&&'static Foo<i32>),
128            double_static_mutable_ref: decay_type!(&&'static mut Foo<i32>)
129        }
130    }
131
132    #[test]
133    fn test_decaying_nested_generic_types_in_struct_definition() {
134        #[allow(dead_code)]
135        struct Foo<T> {
136            value: T
137        }
138
139        #[allow(dead_code)]
140        struct Bar<T> {
141            value: T
142        }
143
144        #[allow(dead_code)]
145        struct NestedGenericStructTypeDecay {
146            value: decay_type!(Foo<Bar<i32>>),
147            reference: decay_type!(&Foo<Bar<i32>>),
148            mut_ref: decay_type!(&mut Foo<Bar<i32>>),
149            double_ref: decay_type!(&&Foo<Bar<i32>>),
150            double_mutable_ref: decay_type!(&&mut Foo<Bar<i32>>),
151            static_ref: decay_type!(&'static Foo<Bar<i32>>),
152            static_mutable_ref: decay_type!(&'static mut Foo<Bar<i32>>),
153            double_static_ref: decay_type!(&&'static Foo<Bar<i32>>),
154            double_static_mutable_ref: decay_type!(&&'static mut Foo<Bar<i32>>)
155        }
156    }
157
158    #[test]
159    fn decaying_value_type() {
160        assert_eq!(TypeId::of::<i32>(), TypeId::of::<decay_type!(i32)>());
161    }
162
163    #[test]
164    fn decaying_ref_type() {
165        assert_eq!(TypeId::of::<i32>(), TypeId::of::<decay_type!(&i32)>());
166    }
167
168    #[test]
169    fn decaying_mutable_ref_type() {
170        assert_eq!(TypeId::of::<i32>(), TypeId::of::<decay_type!(&mut i32)>());
171    }
172
173    #[test]
174    fn decaying_double_ref_type() {
175        assert_eq!(TypeId::of::<i32>(), TypeId::of::<decay_type!(&& i32)>());
176    }
177
178    #[test]
179    fn decaying_double_mutable_ref_type() {
180        assert_eq!(TypeId::of::<i32>(), TypeId::of::<decay_type!(&&mut i32)>());
181    }
182
183    #[test]
184    fn decaying_static_reference_type() {
185        assert_eq!(
186            TypeId::of::<i32>(),
187            TypeId::of::<decay_type!(&'static i32)>());
188    }
189
190    #[test]
191    fn decaying_static_mutable_reference_type() {
192        assert_eq!(
193            TypeId::of::<i32>(),
194            TypeId::of::<decay_type!(&'static mut i32)>());
195    }
196
197    #[test]
198    fn decaying_double_static_reference_type() {
199        assert_eq!(
200            TypeId::of::<i32>(),
201            TypeId::of::<decay_type!(&&'static i32)>());
202    }
203
204    #[test]
205    fn decaying_value_str() {
206        assert_eq!(TypeId::of::<String>(), TypeId::of::<decay_type!(str)>());
207    }
208
209    #[test]
210    fn decaying_ref_str() {
211        assert_eq!(TypeId::of::<String>(), TypeId::of::<decay_type!(&str)>());
212    }
213
214    #[test]
215    fn decaying_mutable_ref_str() {
216        assert_eq!(
217            TypeId::of::<String>(),
218            TypeId::of::<decay_type!(&mut str)>());
219    }
220
221    #[test]
222    fn decaying_double_ref_str() {
223        assert_eq!(TypeId::of::<String>(), TypeId::of::<decay_type!(&& str)>());
224    }
225
226    #[test]
227    fn decaying_double_mutable_ref_str() {
228        assert_eq!(
229            TypeId::of::<String>(),
230            TypeId::of::<decay_type!(&&mut str)>());
231    }
232
233    #[test]
234    fn decaying_static_reference_str() {
235        assert_eq!(
236            TypeId::of::<String>(),
237            TypeId::of::<decay_type!(&'static str)>());
238    }
239
240    #[test]
241    fn decaying_static_mutable_reference_str() {
242        assert_eq!(
243            TypeId::of::<String>(),
244            TypeId::of::<decay_type!(&'static mut str)>());
245    }
246
247    #[test]
248    fn decaying_double_static_reference_str() {
249        assert_eq!(
250            TypeId::of::<String>(),
251            TypeId::of::<decay_type!(&&'static str)>());
252    }
253
254    #[test]
255    fn decaying_value_string() {
256        assert_eq!(TypeId::of::<String>(), TypeId::of::<decay_type!(String)>());
257    }
258
259    #[test]
260    fn decaying_ref_string() {
261        assert_eq!(TypeId::of::<String>(), TypeId::of::<decay_type!(&String)>());
262    }
263
264    #[test]
265    fn decaying_mutable_ref_string() {
266        assert_eq!(
267            TypeId::of::<String>(),
268            TypeId::of::<decay_type!(&mut String)>());
269    }
270
271    #[test]
272    fn decaying_double_ref_string() {
273        assert_eq!(
274            TypeId::of::<String>(),
275            TypeId::of::<decay_type!(&& String)>());
276    }
277
278    #[test]
279    fn decaying_double_mutable_ref_string() {
280        assert_eq!(
281            TypeId::of::<String>(),
282            TypeId::of::<decay_type!(&&mut String)>());
283    }
284
285    #[test]
286    fn decaying_static_reference_string() {
287        assert_eq!(
288            TypeId::of::<String>(),
289            TypeId::of::<decay_type!(&'static String)>());
290    }
291
292    #[test]
293    fn decaying_static_mutable_reference_string() {
294        assert_eq!(
295            TypeId::of::<String>(),
296            TypeId::of::<decay_type!(&'static mut String)>());
297    }
298
299    #[test]
300    fn decaying_double_static_reference_string() {
301        assert_eq!(
302            TypeId::of::<String>(),
303            TypeId::of::<decay_type!(&&'static String)>());
304    }
305
306    #[allow(dead_code)]
307    struct Point {
308        x: f64,
309        y: f64
310    }
311
312    #[test]
313    fn decaying_value_struct() {
314        assert_eq!(TypeId::of::<Point>(), TypeId::of::<decay_type!(Point)>());
315    }
316
317    #[test]
318    fn decaying_ref_struct() {
319        assert_eq!(TypeId::of::<Point>(), TypeId::of::<decay_type!(&Point)>());
320    }
321
322    #[test]
323    fn decaying_mutable_ref_struct() {
324        assert_eq!(
325            TypeId::of::<Point>(),
326            TypeId::of::<decay_type!(&mut Point)>());
327    }
328
329    #[test]
330    fn decaying_double_ref_struct() {
331        assert_eq!(
332            TypeId::of::<Point>(),
333            TypeId::of::<decay_type!(&& Point)>());
334    }
335
336    #[test]
337    fn decaying_double_mutable_ref_struct() {
338        assert_eq!(
339
340            TypeId::of::<Point>(),
341            TypeId::of::<decay_type!(&&mut Point)>());
342    }
343
344    #[test]
345    fn decaying_static_reference_struct() {
346        assert_eq!(
347            TypeId::of::<Point>(),
348            TypeId::of::<decay_type!(&'static Point)>());
349    }
350
351    #[test]
352    fn decaying_static_mutable_reference_struct() {
353        assert_eq!(
354            TypeId::of::<Point>(),
355            TypeId::of::<decay_type!(&'static mut Point)>());
356    }
357
358    #[test]
359    fn decaying_double_static_reference_struct() {
360        assert_eq!(
361            TypeId::of::<Point>(),
362            TypeId::of::<decay_type!(&&'static Point)>());
363    }
364
365    #[allow(dead_code)]
366    struct Foo<T> {
367        value: T
368    }
369
370    #[allow(dead_code)]
371    struct Bar<T> {
372        value: T
373    }
374
375    #[test]
376    fn decaying_value_generic_struct() {
377        assert_eq!(
378            TypeId::of::<Foo<i32>>(),
379            TypeId::of::<decay_type!(Foo<i32>)>());
380    }
381
382    #[test]
383    fn decaying_ref_generic_struct() {
384        assert_eq!(
385            TypeId::of::<Foo<i32>>(),
386            TypeId::of::<decay_type!(&Foo<i32>)>());
387    }
388
389    #[test]
390    fn decaying_mutable_ref_generic_struct() {
391        assert_eq!(
392            TypeId::of::<Foo<i32>>(),
393            TypeId::of::<decay_type!(&mut Foo<i32>)>());
394    }
395
396    #[test]
397    fn decaying_double_ref_generic_struct() {
398        assert_eq!(
399            TypeId::of::<Foo<i32>>(),
400            TypeId::of::<decay_type!(&& Foo<i32>)>());
401    }
402
403    #[test]
404    fn decaying_double_mutable_ref_generic_struct() {
405        assert_eq!(
406            TypeId::of::<Foo<i32>>(),
407            TypeId::of::<decay_type!(&&mut Foo<i32>)>());
408    }
409
410    #[test]
411    fn decaying_static_reference_generic_struct() {
412        assert_eq!(
413            TypeId::of::<Foo<i32>>(),
414            TypeId::of::<decay_type!(&'static Foo<i32>)>());
415    }
416
417    #[test]
418    fn decaying_static_mutable_reference_generic_struct() {
419        assert_eq!(
420            TypeId::of::<Foo<i32>>(),
421            TypeId::of::<decay_type!(&'static mut Foo<i32>)>());
422    }
423
424    #[test]
425    fn decaying_double_static_reference_generic_struct() {
426        assert_eq!(
427            TypeId::of::<Foo<i32>>(),
428            TypeId::of::<decay_type!(&&'static Foo<i32>)>());
429    }
430
431    #[test]
432    fn decaying_value_nested_generic_struct() {
433        assert_eq!(
434            TypeId::of::<Foo<Bar<i32>>>(),
435            TypeId::of::<decay_type!(Foo<Bar<i32>>)>());
436    }
437
438    #[test]
439    fn decaying_ref_nested_generic_struct() {
440        assert_eq!(
441            TypeId::of::<Foo<Bar<i32>>>(),
442            TypeId::of::<decay_type!(&Foo<Bar<i32>>)>());
443    }
444
445    #[test]
446    fn decaying_mutable_ref_nested_generic_struct() {
447        assert_eq!(
448            TypeId::of::<Foo<Bar<i32>>>(),
449            TypeId::of::<decay_type!(&mut Foo<Bar<i32>>)>());
450    }
451
452    #[test]
453    fn decaying_double_ref_nested_generic_struct() {
454        assert_eq!(
455            TypeId::of::<Foo<Bar<i32>>>(),
456            TypeId::of::<decay_type!(&& Foo<Bar<i32>>)>());
457    }
458
459    #[test]
460    fn decaying_double_mutable_ref_nested_generic_struct() {
461        assert_eq!(
462            TypeId::of::<Foo<Bar<i32>>>(),
463            TypeId::of::<decay_type!(&&mut Foo<Bar<i32>>)>());
464    }
465
466    #[test]
467    fn decaying_static_reference_nested_generic_struct() {
468        assert_eq!(
469            TypeId::of::<Foo<Bar<i32>>>(),
470            TypeId::of::<decay_type!(&'static Foo<Bar<i32>>)>());
471    }
472
473    #[test]
474    fn decaying_static_mutable_reference_nested_generic_struct() {
475        assert_eq!(
476            TypeId::of::<Foo<Bar<i32>>>(),
477            TypeId::of::<decay_type!(&'static mut Foo<Bar<i32>>)>());
478    }
479
480    #[test]
481    fn decaying_double_static_reference_nested_generic_struct() {
482        assert_eq!(
483            TypeId::of::<Foo<Bar<i32>>>(),
484            TypeId::of::<decay_type!(&&'static Foo<Bar<i32>>)>());
485    }
486
487}