]> git.lizzy.rs Git - rust.git/blob - src/test/ui/generator/smoke-resume-args.rs
Auto merge of #98051 - davidtwco:split-dwarf-stabilization, r=wesleywiser
[rust.git] / src / test / ui / generator / smoke-resume-args.rs
1 // run-pass
2
3 // revisions: default nomiropt
4 //[nomiropt]compile-flags: -Z mir-opt-level=0
5
6 #![feature(generators, generator_trait)]
7
8 use std::fmt::Debug;
9 use std::marker::Unpin;
10 use std::ops::{
11     Generator,
12     GeneratorState::{self, *},
13 };
14 use std::pin::Pin;
15 use std::sync::atomic::{AtomicUsize, Ordering};
16
17 fn drain<G: Generator<R, Yield = Y> + Unpin, R, Y>(
18     gen: &mut G,
19     inout: Vec<(R, GeneratorState<Y, G::Return>)>,
20 ) where
21     Y: Debug + PartialEq,
22     G::Return: Debug + PartialEq,
23 {
24     let mut gen = Pin::new(gen);
25
26     for (input, out) in inout {
27         assert_eq!(gen.as_mut().resume(input), out);
28     }
29 }
30
31 static DROPS: AtomicUsize = AtomicUsize::new(0);
32
33 #[derive(Debug, PartialEq)]
34 struct DropMe;
35
36 impl Drop for DropMe {
37     fn drop(&mut self) {
38         DROPS.fetch_add(1, Ordering::SeqCst);
39     }
40 }
41
42 fn expect_drops<T>(expected_drops: usize, f: impl FnOnce() -> T) -> T {
43     DROPS.store(0, Ordering::SeqCst);
44
45     let res = f();
46
47     let actual_drops = DROPS.load(Ordering::SeqCst);
48     assert_eq!(actual_drops, expected_drops);
49     res
50 }
51
52 fn main() {
53     drain(
54         &mut |mut b| {
55             while b != 0 {
56                 b = yield (b + 1);
57             }
58             -1
59         },
60         vec![(1, Yielded(2)), (-45, Yielded(-44)), (500, Yielded(501)), (0, Complete(-1))],
61     );
62
63     expect_drops(2, || drain(&mut |a| yield a, vec![(DropMe, Yielded(DropMe))]));
64
65     expect_drops(6, || {
66         drain(
67             &mut |a| yield yield a,
68             vec![(DropMe, Yielded(DropMe)), (DropMe, Yielded(DropMe)), (DropMe, Complete(DropMe))],
69         )
70     });
71
72     #[allow(unreachable_code)]
73     expect_drops(2, || drain(&mut |a| yield return a, vec![(DropMe, Complete(DropMe))]));
74
75     expect_drops(2, || {
76         drain(
77             &mut |a: DropMe| {
78                 if false { yield () } else { a }
79             },
80             vec![(DropMe, Complete(DropMe))],
81         )
82     });
83
84     expect_drops(4, || {
85         drain(
86             #[allow(unused_assignments, unused_variables)]
87             &mut |mut a: DropMe| {
88                 a = yield;
89                 a = yield;
90                 a = yield;
91             },
92             vec![
93                 (DropMe, Yielded(())),
94                 (DropMe, Yielded(())),
95                 (DropMe, Yielded(())),
96                 (DropMe, Complete(())),
97             ],
98         )
99     });
100 }