]> git.lizzy.rs Git - rust.git/blob - tests/ui/regions/region-borrow-params-issue-29793-big.rs
internally change regions to be covariant
[rust.git] / tests / ui / regions / region-borrow-params-issue-29793-big.rs
1 // Issue #29793, big regression test: do not let borrows of
2 // parameters to ever be returned (expanded with exploration of
3 // variations).
4 //
5 // This is the version of the test that actually exposed unsound
6 // behavior (because the improperly accepted closure was actually
7 // able to be invoked).
8
9 struct WrapA<F>(Option<F>);
10
11 impl<F> WrapA<F> {
12     fn new() -> WrapA<F> {
13         WrapA(None)
14     }
15     fn set(mut self, f: F) -> Self {
16         self.0 = Some(f);
17         self
18     }
19 }
20
21 struct WrapB<F>(Option<F>);
22
23 impl<F> WrapB<F> {
24     fn new() -> WrapB<F> {
25         WrapB(None)
26     }
27     fn set(mut self, f: F) -> Self {
28         self.0 = Some(f);
29         self
30     }
31 }
32
33 trait DoStuff : Sized {
34     fn handle(self);
35 }
36
37 impl<F, T> DoStuff for WrapA<F>
38     where F: FnMut(usize, usize) -> T, T: DoStuff {
39         fn handle(mut self) {
40             if let Some(ref mut f) = self.0 {
41                 let x = f(1, 2);
42                 let _foo = [0usize; 16];
43                 x.handle();
44             }
45         }
46     }
47
48 impl<F> DoStuff for WrapB<F> where F: FnMut(bool) -> usize {
49     fn handle(mut self) {
50         if let Some(ref mut f) = self.0 {
51             println!("{}", f(true));
52         }
53     }
54 }
55
56 impl<F, T> WrapA<F>
57     where F: FnMut(usize, usize) -> T, T: DoStuff {
58         fn handle_ref(&mut self) {
59             if let Some(ref mut f) = self.0 {
60                 let x = f(1, 2);
61             }
62         }
63     }
64
65 fn main() {
66     let mut w = WrapA::new().set(|x: usize, y: usize| {
67         WrapB::new().set(|t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`)
68             //~^ ERROR closure may outlive the current function
69             //~| ERROR closure may outlive the current function
70     });
71
72     w.handle(); // This works
73     // w.handle_ref(); // This doesn't
74 }