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)]
8 use std::intrinsics::discriminant_value;
9 use std::marker::Unpin;
10 use std::mem::size_of_val;
11 use std::{cmp, ops::*};
13 macro_rules! yield25 {
48 macro_rules! yield250 {
68 fn cycle(gen: impl Generator<()> + Unpin, expected_max_discr: u64) {
69 let mut gen = Box::pin(gen);
70 let mut max_discr = 0;
72 max_discr = cmp::max(max_discr, discriminant_value(gen.as_mut().get_mut()));
73 match gen.as_mut().resume(()) {
74 GeneratorState::Yielded(_) => {}
75 GeneratorState::Complete(_) => {
76 assert_eq!(max_discr, expected_max_discr);
84 // Has only one invalid discr. value.
85 let gen_u8_tiny_niche = || {
87 // 3 reserved variants
89 yield250!(); // 253 variants
96 // Uses all values in the u8 discriminant.
97 let gen_u8_full = || {
99 // 3 reserved variants
101 yield250!(); // 253 variants
109 // Barely needs a u16 discriminant.
112 // 3 reserved variants
114 yield250!(); // 253 variants
123 assert_eq!(size_of_val(&gen_u8_tiny_niche()), 1);
124 assert_eq!(size_of_val(&Some(gen_u8_tiny_niche())), 1); // uses niche
125 assert_eq!(size_of_val(&Some(Some(gen_u8_tiny_niche()))), 2); // cannot use niche anymore
126 assert_eq!(size_of_val(&gen_u8_full()), 1);
127 assert_eq!(size_of_val(&Some(gen_u8_full())), 2); // cannot use niche
128 assert_eq!(size_of_val(&gen_u16()), 2);
129 assert_eq!(size_of_val(&Some(gen_u16())), 2); // uses niche
131 cycle(gen_u8_tiny_niche(), 254);
132 cycle(gen_u8_full(), 255);
133 cycle(gen_u16(), 256);