]> git.lizzy.rs Git - rust.git/blob - src/test/ui/regions/region-borrow-params-issue-29793-big.rs
Auto merge of #54720 - davidtwco:issue-51191, r=nikomatsakis
[rust.git] / src / test / ui / regions / region-borrow-params-issue-29793-big.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // Issue #29793, big regression test: do not let borrows of
12 // parameters to ever be returned (expanded with exploration of
13 // variations).
14 //
15 // This is the version of the test that actually exposed unsound
16 // behavior (because the improperly accepted closure was actually
17 // able to be invoked).
18
19 // ignore-tidy-linelength
20 // revisions: ast mir
21 //[mir]compile-flags: -Z borrowck=mir
22
23 struct WrapA<F>(Option<F>);
24
25 impl<F> WrapA<F> {
26     fn new() -> WrapA<F> {
27         WrapA(None)
28     }
29     fn set(mut self, f: F) -> Self {
30         self.0 = Some(f);
31         self
32     }
33 }
34
35 struct WrapB<F>(Option<F>);
36
37 impl<F> WrapB<F> {
38     fn new() -> WrapB<F> {
39         WrapB(None)
40     }
41     fn set(mut self, f: F) -> Self {
42         self.0 = Some(f);
43         self
44     }
45 }
46
47 trait DoStuff : Sized {
48     fn handle(self);
49 }
50
51 impl<F, T> DoStuff for WrapA<F>
52     where F: FnMut(usize, usize) -> T, T: DoStuff {
53         fn handle(mut self) {
54             if let Some(ref mut f) = self.0 {
55                 let x = f(1, 2);
56                 let _foo = [0usize; 16];
57                 x.handle();
58             }
59         }
60     }
61
62 impl<F> DoStuff for WrapB<F> where F: FnMut(bool) -> usize {
63     fn handle(mut self) {
64         if let Some(ref mut f) = self.0 {
65             println!("{}", f(true));
66         }
67     }
68 }
69
70 impl<F, T> WrapA<F>
71     where F: FnMut(usize, usize) -> T, T: DoStuff {
72         fn handle_ref(&mut self) {
73             if let Some(ref mut f) = self.0 {
74                 let x = f(1, 2);
75             }
76         }
77     }
78
79 fn main() {
80     let mut w = WrapA::new().set(|x: usize, y: usize| {
81         WrapB::new().set(|t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`)
82             //[ast]~^ ERROR `x` does not live long enough
83             //[ast]~| ERROR `y` does not live long enough
84             //[mir]~^^^ ERROR `x` does not live long enough
85             //[mir]~| ERROR `y` does not live long enough
86     });
87
88     w.handle(); // This works
89     // w.handle_ref(); // This doesn't
90 }