1 // edition:2021
2 
3 // Test borrow checker when we precise capture when using boxes
4 
5 struct MetaData { x: String, name: String }
6 struct Data { m: MetaData }
7 struct BoxedData(Box<Data>);
8 struct EvenMoreBoxedData(Box<BoxedData>);
9 
10 // Check diagnostics when the same path is mutated both inside and outside the closure
box_1()11 fn box_1() {
12     let m = MetaData { x: format!("x"), name: format!("name") };
13     let d = Data { m };
14     let b = BoxedData(Box::new(d));
15     let mut e = EvenMoreBoxedData(Box::new(b));
16 
17     let mut c = || {
18         e.0.0.m.x = format!("not-x");
19     };
20 
21     e.0.0.m.x = format!("not-x");
22     //~^ ERROR: cannot assign to `e.0.0.m.x` because it is borrowed
23     c();
24 }
25 
26 // Check diagnostics when a path is mutated inside a closure while attempting to read it outside
27 // the closure.
box_2()28 fn box_2() {
29     let m = MetaData { x: format!("x"), name: format!("name") };
30     let d = Data { m };
31     let b = BoxedData(Box::new(d));
32     let mut e = EvenMoreBoxedData(Box::new(b));
33 
34     let mut c = || {
35         e.0.0.m.x = format!("not-x");
36     };
37 
38     println!("{}", e.0.0.m.x);
39     //~^ ERROR: cannot borrow `e.0.0.m.x` as immutable because it is also borrowed as mutable
40     c();
41 }
42 
43 // Check diagnostics when a path is read inside a closure while attempting to mutate it outside
44 // the closure.
box_3()45 fn box_3() {
46     let m = MetaData { x: format!("x"), name: format!("name") };
47     let d = Data { m };
48     let b = BoxedData(Box::new(d));
49     let mut e = EvenMoreBoxedData(Box::new(b));
50 
51     let c = || {
52         println!("{}", e.0.0.m.x);
53     };
54 
55     e.0.0.m.x = format!("not-x");
56     //~^ ERROR: cannot assign to `e.0.0.m.x` because it is borrowed
57     c();
58 }
59 
main()60 fn main() {
61     box_1();
62     box_2();
63     box_3();
64 }
65