]>
Commit | Line | Data |
---|---|---|
ba9703b0 XL |
1 | //! Tests that generator discriminant sizes and ranges are chosen optimally and that they are |
2 | //! reflected in the output of `mem::discriminant`. | |
3 | ||
4 | // run-pass | |
5 | ||
f9f354fc | 6 | #![feature(generators, generator_trait, core_intrinsics, discriminant_kind)] |
ba9703b0 XL |
7 | |
8 | use std::intrinsics::discriminant_value; | |
f9f354fc | 9 | use std::marker::{Unpin, DiscriminantKind}; |
ba9703b0 XL |
10 | use std::mem::size_of_val; |
11 | use std::{cmp, ops::*}; | |
12 | ||
13 | macro_rules! yield25 { | |
14 | ($e:expr) => { | |
15 | yield $e; | |
16 | yield $e; | |
17 | yield $e; | |
18 | yield $e; | |
19 | yield $e; | |
20 | ||
21 | yield $e; | |
22 | yield $e; | |
23 | yield $e; | |
24 | yield $e; | |
25 | yield $e; | |
26 | ||
27 | yield $e; | |
28 | yield $e; | |
29 | yield $e; | |
30 | yield $e; | |
31 | yield $e; | |
32 | ||
33 | yield $e; | |
34 | yield $e; | |
35 | yield $e; | |
36 | yield $e; | |
37 | yield $e; | |
38 | ||
39 | yield $e; | |
40 | yield $e; | |
41 | yield $e; | |
42 | yield $e; | |
43 | yield $e; | |
44 | }; | |
45 | } | |
46 | ||
47 | /// Yields 250 times. | |
48 | macro_rules! yield250 { | |
49 | () => { | |
50 | yield250!(()) | |
51 | }; | |
52 | ||
53 | ($e:expr) => { | |
54 | yield25!($e); | |
55 | yield25!($e); | |
56 | yield25!($e); | |
57 | yield25!($e); | |
58 | yield25!($e); | |
59 | ||
60 | yield25!($e); | |
61 | yield25!($e); | |
62 | yield25!($e); | |
63 | yield25!($e); | |
64 | yield25!($e); | |
65 | }; | |
66 | } | |
67 | ||
f9f354fc XL |
68 | fn cycle( |
69 | gen: impl Generator<()> + Unpin + DiscriminantKind<Discriminant = i32>, | |
70 | expected_max_discr: i32 | |
71 | ) { | |
ba9703b0 XL |
72 | let mut gen = Box::pin(gen); |
73 | let mut max_discr = 0; | |
74 | loop { | |
75 | max_discr = cmp::max(max_discr, discriminant_value(gen.as_mut().get_mut())); | |
76 | match gen.as_mut().resume(()) { | |
77 | GeneratorState::Yielded(_) => {} | |
78 | GeneratorState::Complete(_) => { | |
79 | assert_eq!(max_discr, expected_max_discr); | |
80 | return; | |
81 | } | |
82 | } | |
83 | } | |
84 | } | |
85 | ||
86 | fn main() { | |
87 | // Has only one invalid discr. value. | |
88 | let gen_u8_tiny_niche = || { | |
89 | || { | |
90 | // 3 reserved variants | |
91 | ||
92 | yield250!(); // 253 variants | |
93 | ||
94 | yield; // 254 | |
95 | yield; // 255 | |
96 | } | |
97 | }; | |
98 | ||
99 | // Uses all values in the u8 discriminant. | |
100 | let gen_u8_full = || { | |
101 | || { | |
102 | // 3 reserved variants | |
103 | ||
104 | yield250!(); // 253 variants | |
105 | ||
106 | yield; // 254 | |
107 | yield; // 255 | |
108 | yield; // 256 | |
109 | } | |
110 | }; | |
111 | ||
112 | // Barely needs a u16 discriminant. | |
113 | let gen_u16 = || { | |
114 | || { | |
115 | // 3 reserved variants | |
116 | ||
117 | yield250!(); // 253 variants | |
118 | ||
119 | yield; // 254 | |
120 | yield; // 255 | |
121 | yield; // 256 | |
122 | yield; // 257 | |
123 | } | |
124 | }; | |
125 | ||
126 | assert_eq!(size_of_val(&gen_u8_tiny_niche()), 1); | |
127 | assert_eq!(size_of_val(&Some(gen_u8_tiny_niche())), 1); // uses niche | |
128 | assert_eq!(size_of_val(&Some(Some(gen_u8_tiny_niche()))), 2); // cannot use niche anymore | |
129 | assert_eq!(size_of_val(&gen_u8_full()), 1); | |
130 | assert_eq!(size_of_val(&Some(gen_u8_full())), 2); // cannot use niche | |
131 | assert_eq!(size_of_val(&gen_u16()), 2); | |
132 | assert_eq!(size_of_val(&Some(gen_u16())), 2); // uses niche | |
133 | ||
134 | cycle(gen_u8_tiny_niche(), 254); | |
135 | cycle(gen_u8_full(), 255); | |
136 | cycle(gen_u16(), 256); | |
137 | } |