135 lines
2.9 KiB
Rust
135 lines
2.9 KiB
Rust
|
//! Tests that generator discriminant sizes and ranges are chosen optimally and that they are
|
||
|
//! reflected in the output of `mem::discriminant`.
|
||
|
|
||
|
// run-pass
|
||
|
|
||
|
#![feature(generators, generator_trait, core_intrinsics)]
|
||
|
|
||
|
use std::intrinsics::discriminant_value;
|
||
|
use std::marker::Unpin;
|
||
|
use std::mem::size_of_val;
|
||
|
use std::{cmp, ops::*};
|
||
|
|
||
|
macro_rules! yield25 {
|
||
|
($e:expr) => {
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
yield $e;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/// Yields 250 times.
|
||
|
macro_rules! yield250 {
|
||
|
() => {
|
||
|
yield250!(())
|
||
|
};
|
||
|
|
||
|
($e:expr) => {
|
||
|
yield25!($e);
|
||
|
yield25!($e);
|
||
|
yield25!($e);
|
||
|
yield25!($e);
|
||
|
yield25!($e);
|
||
|
|
||
|
yield25!($e);
|
||
|
yield25!($e);
|
||
|
yield25!($e);
|
||
|
yield25!($e);
|
||
|
yield25!($e);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
fn cycle(gen: impl Generator<()> + Unpin, expected_max_discr: u64) {
|
||
|
let mut gen = Box::pin(gen);
|
||
|
let mut max_discr = 0;
|
||
|
loop {
|
||
|
max_discr = cmp::max(max_discr, discriminant_value(gen.as_mut().get_mut()));
|
||
|
match gen.as_mut().resume(()) {
|
||
|
GeneratorState::Yielded(_) => {}
|
||
|
GeneratorState::Complete(_) => {
|
||
|
assert_eq!(max_discr, expected_max_discr);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn main() {
|
||
|
// Has only one invalid discr. value.
|
||
|
let gen_u8_tiny_niche = || {
|
||
|
|| {
|
||
|
// 3 reserved variants
|
||
|
|
||
|
yield250!(); // 253 variants
|
||
|
|
||
|
yield; // 254
|
||
|
yield; // 255
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Uses all values in the u8 discriminant.
|
||
|
let gen_u8_full = || {
|
||
|
|| {
|
||
|
// 3 reserved variants
|
||
|
|
||
|
yield250!(); // 253 variants
|
||
|
|
||
|
yield; // 254
|
||
|
yield; // 255
|
||
|
yield; // 256
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Barely needs a u16 discriminant.
|
||
|
let gen_u16 = || {
|
||
|
|| {
|
||
|
// 3 reserved variants
|
||
|
|
||
|
yield250!(); // 253 variants
|
||
|
|
||
|
yield; // 254
|
||
|
yield; // 255
|
||
|
yield; // 256
|
||
|
yield; // 257
|
||
|
}
|
||
|
};
|
||
|
|
||
|
assert_eq!(size_of_val(&gen_u8_tiny_niche()), 1);
|
||
|
assert_eq!(size_of_val(&Some(gen_u8_tiny_niche())), 1); // uses niche
|
||
|
assert_eq!(size_of_val(&Some(Some(gen_u8_tiny_niche()))), 2); // cannot use niche anymore
|
||
|
assert_eq!(size_of_val(&gen_u8_full()), 1);
|
||
|
assert_eq!(size_of_val(&Some(gen_u8_full())), 2); // cannot use niche
|
||
|
assert_eq!(size_of_val(&gen_u16()), 2);
|
||
|
assert_eq!(size_of_val(&Some(gen_u16())), 2); // uses niche
|
||
|
|
||
|
cycle(gen_u8_tiny_niche(), 254);
|
||
|
cycle(gen_u8_full(), 255);
|
||
|
cycle(gen_u16(), 256);
|
||
|
}
|