summaryrefslogtreecommitdiffstats
path: root/tests/ui/liveness/liveness-upvars.rs
blob: d446d57d3964726aac90d4d741011f2b4896d40d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// edition:2018
// check-pass
#![feature(generators)]
#![warn(unused)]
#![allow(unreachable_code)]

pub fn unintentional_copy_one() {
    let mut last = None;
    let mut f = move |s| {
        last = Some(s); //~  WARN value assigned to `last` is never read
                        //~| WARN unused variable: `last`
    };
    f("a");
    f("b");
    f("c");
    dbg!(last.unwrap());
}

pub fn unintentional_copy_two() {
    let mut sum = 0;
    (1..10).for_each(move |x| {
        sum += x; //~ WARN unused variable: `sum`
    });
    dbg!(sum);
}

pub fn f() {
    let mut c = 0;

    // Captured by value, but variable is dead on entry.
    let _ = move || {
        c = 1; //~ WARN value captured by `c` is never read
        println!("{}", c);
    };
    let _ = async move {
        c = 1; //~ WARN value captured by `c` is never read
        println!("{}", c);
    };

    // Read and written to, but never actually used.
    let _ = move || {
        c += 1; //~ WARN unused variable: `c`
    };
    let _ = async move {
        c += 1; //~  WARN value assigned to `c` is never read
                //~| WARN unused variable: `c`
    };

    let _ = move || {
        println!("{}", c);
        // Value is read by closure itself on later invocations.
        c += 1;
    };
    let b = Box::new(42);
    let _ = move || {
        println!("{}", c);
        // Never read because this is FnOnce closure.
        c += 1; //~  WARN value assigned to `c` is never read
        drop(b);
    };
    let _ = async move {
        println!("{}", c);
        // Never read because this is a generator.
        c += 1; //~  WARN value assigned to `c` is never read
    };
}

pub fn nested() {
    let mut d = None;
    let mut e = None;
    let _ = || {
        let _ = || {
            d = Some("d1"); //~ WARN value assigned to `d` is never read
            d = Some("d2");
        };
        let _ = move || {
            e = Some("e1"); //~  WARN value assigned to `e` is never read
                            //~| WARN unused variable: `e`
            e = Some("e2"); //~  WARN value assigned to `e` is never read
        };
    };
}

pub fn g<T: Default>(mut v: T) {
    let _ = |r| {
        if r {
            v = T::default(); //~ WARN value assigned to `v` is never read
        } else {
            drop(v);
        }
    };
}

pub fn h<T: Copy + Default + std::fmt::Debug>() {
    let mut z = T::default();
    let _ = move |b| {
        loop {
            if b {
                z = T::default(); //~  WARN value assigned to `z` is never read
                                  //~| WARN unused variable: `z`
            } else {
                return;
            }
        }
        dbg!(z);
    };
}

async fn yield_now() {
    todo!();
}

pub fn async_generator() {
    let mut state: u32 = 0;

    let _ = async {
        state = 1;
        yield_now().await;
        state = 2;
        yield_now().await;
        state = 3;
    };

    let _ = async move {
        state = 4;  //~  WARN value assigned to `state` is never read
                    //~| WARN unused variable: `state`
        yield_now().await;
        state = 5;  //~ WARN value assigned to `state` is never read
    };
}

pub fn generator() {
    let mut s: u32 = 0;
    let _ = |_| {
        s = 0;
        yield ();
        s = 1; //~ WARN value assigned to `s` is never read
        yield (s = 2);
        s = yield (); //~ WARN value assigned to `s` is never read
        s = 3;
    };
}

fn main() {}