summaryrefslogtreecommitdiffstats
path: root/src/test/ui/generator/discriminant.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/generator/discriminant.rs
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/generator/discriminant.rs')
-rw-r--r--src/test/ui/generator/discriminant.rs137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/test/ui/generator/discriminant.rs b/src/test/ui/generator/discriminant.rs
new file mode 100644
index 000000000..195e77022
--- /dev/null
+++ b/src/test/ui/generator/discriminant.rs
@@ -0,0 +1,137 @@
+//! 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, discriminant_kind)]
+
+use std::intrinsics::discriminant_value;
+use std::marker::{Unpin, DiscriminantKind};
+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 + DiscriminantKind<Discriminant = u32>,
+ expected_max_discr: u32
+) {
+ 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);
+}