2013-06-25 00:02:24 +00:00
|
|
|
// Tests correct kind-checking of the reason stack closures without the :Copy
|
|
|
|
// bound must be noncopyable. For details see
|
2021-06-23 20:26:46 +00:00
|
|
|
// https://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/
|
2013-06-25 00:02:24 +00:00
|
|
|
|
2013-12-10 07:16:18 +00:00
|
|
|
struct R<'a> {
|
2013-06-25 00:02:24 +00:00
|
|
|
// This struct is needed to create the
|
|
|
|
// otherwise infinite type of a fn that
|
|
|
|
// accepts itself as argument:
|
2019-05-28 18:46:13 +00:00
|
|
|
c: Box<dyn FnMut(&mut R, bool) + 'a>
|
2013-06-25 00:02:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn innocent_looking_victim() {
|
2014-05-25 10:10:11 +00:00
|
|
|
let mut x = Some("hello".to_string());
|
2013-11-22 01:23:21 +00:00
|
|
|
conspirator(|f, writer| {
|
2013-06-25 00:02:24 +00:00
|
|
|
if writer {
|
|
|
|
x = None;
|
|
|
|
} else {
|
|
|
|
match x {
|
|
|
|
Some(ref msg) => {
|
2015-01-05 19:07:10 +00:00
|
|
|
(f.c)(f, true);
|
2015-01-03 15:45:00 +00:00
|
|
|
//~^ ERROR: cannot borrow `*f` as mutable more than once at a time
|
2014-10-15 01:07:11 +00:00
|
|
|
println!("{}", msg);
|
2013-06-25 00:02:24 +00:00
|
|
|
},
|
2014-10-09 19:17:22 +00:00
|
|
|
None => panic!("oops"),
|
2013-06-25 00:02:24 +00:00
|
|
|
}
|
|
|
|
}
|
2013-11-22 01:23:21 +00:00
|
|
|
})
|
2013-06-25 00:02:24 +00:00
|
|
|
}
|
|
|
|
|
2015-01-03 15:45:00 +00:00
|
|
|
fn conspirator<F>(mut f: F) where F: FnMut(&mut R, bool) {
|
2015-02-15 08:52:21 +00:00
|
|
|
let mut r = R {c: Box::new(f)};
|
2019-04-22 07:40:08 +00:00
|
|
|
f(&mut r, false) //~ ERROR borrow of moved value
|
2013-06-25 00:02:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn main() { innocent_looking_victim() }
|