]> git.lizzy.rs Git - rust.git/blob - tests/ui/moves/moves-based-on-type-no-recursive-stack-closure.rs
Rollup merge of #106446 - bzEq:fix-unwind-lsda, r=Amanieu
[rust.git] / tests / ui / moves / moves-based-on-type-no-recursive-stack-closure.rs
1 // Tests correct kind-checking of the reason stack closures without the :Copy
2 // bound must be noncopyable. For details see
3 // https://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/
4
5 struct R<'a> {
6     // This struct is needed to create the
7     // otherwise infinite type of a fn that
8     // accepts itself as argument:
9     c: Box<dyn FnMut(&mut R, bool) + 'a>
10 }
11
12 fn innocent_looking_victim() {
13     let mut x = Some("hello".to_string());
14     conspirator(|f, writer| {
15         if writer {
16             x = None;
17         } else {
18             match x {
19                 Some(ref msg) => {
20                     (f.c)(f, true);
21                     //~^ ERROR: cannot borrow `*f` as mutable more than once at a time
22                     println!("{}", msg);
23                 },
24                 None => panic!("oops"),
25             }
26         }
27     })
28 }
29
30 fn conspirator<F>(mut f: F) where F: FnMut(&mut R, bool) {
31     let mut r = R {c: Box::new(f)};
32     f(&mut r, false) //~ ERROR borrow of moved value
33 }
34
35 fn main() { innocent_looking_victim() }