]> git.lizzy.rs Git - rust.git/blob - src/test/ui/generator/discriminant.rs
Auto merge of #102655 - joboet:windows_tls_opt, r=ChrisDenton
[rust.git] / src / test / ui / generator / discriminant.rs
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
6 #![feature(generators, generator_trait, core_intrinsics, discriminant_kind)]
7
8 use std::intrinsics::discriminant_value;
9 use std::marker::{Unpin, DiscriminantKind};
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
68 fn cycle(
69     gen: impl Generator<()> + Unpin + DiscriminantKind<Discriminant = u32>,
70     expected_max_discr: u32
71 ) {
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 }