1 //! Tests that generator discriminant sizes and ranges are chosen optimally and that they are
2 //! reflected in the output of `mem::discriminant`.
6 #![feature(generators, generator_trait, core_intrinsics, discriminant_kind)]
8 use std::intrinsics::discriminant_value;
9 use std::marker::{Unpin, DiscriminantKind};
10 use std::mem::size_of_val;
11 use std::{cmp, ops::*};
13 macro_rules! yield25 {
48 macro_rules! yield250 {
69 gen: impl Generator<()> + Unpin + DiscriminantKind<Discriminant = u32>,
70 expected_max_discr: u32
72 let mut gen = Box::pin(gen);
73 let mut max_discr = 0;
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);
87 // Has only one invalid discr. value.
88 let gen_u8_tiny_niche = || {
90 // 3 reserved variants
92 yield250!(); // 253 variants
99 // Uses all values in the u8 discriminant.
100 let gen_u8_full = || {
102 // 3 reserved variants
104 yield250!(); // 253 variants
112 // Barely needs a u16 discriminant.
115 // 3 reserved variants
117 yield250!(); // 253 variants
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
134 cycle(gen_u8_tiny_niche(), 254);
135 cycle(gen_u8_full(), 255);
136 cycle(gen_u16(), 256);