1 // rust-lang/rust#45696: This test is checking that we can return
2 // mutable borrows owned by boxes even when the boxes are dropped.
6 // This function shows quite directly what is going on: We have a
7 // reborrow of contents within the box.
8 fn return_borrow_from_dropped_box_1(x
: Box
<&mut u32>) -> &mut u32 { &mut **x }
10 // This function is the way you'll probably see this in practice (the
11 // reborrow is now implicit).
12 fn return_borrow_from_dropped_box_2(x
: Box
<&mut u32>) -> &mut u32 { *x }
14 // For the remaining tests we just add some fields or other
15 // indirection to ensure that the compiler isn't just special-casing
16 // the above `Box<&mut T>` as the only type that would work.
18 // Here we add a tuple of indirection between the box and the
20 type BoxedTup
<'a
, 'b
> = Box
<(&'a
mut u32, &'b
mut u32)>;
22 fn return_borrow_of_field_from_dropped_box_1
<'a
>(x
: BoxedTup
<'a
, '_
>) -> &'a
mut u32 {
26 fn return_borrow_of_field_from_dropped_box_2
<'a
>(x
: BoxedTup
<'a
, '_
>) -> &'a
mut u32 {
30 fn return_borrow_from_dropped_tupled_box_1
<'a
>(x
: (BoxedTup
<'a
, '_
>, &mut u32)) -> &'a
mut u32 {
34 fn return_borrow_from_dropped_tupled_box_2
<'a
>(x
: (BoxedTup
<'a
, '_
>, &mut u32)) -> &'a
mut u32 {
42 *return_borrow_from_dropped_box_1(Box
::new(&mut x
)) += 10;
43 assert_eq
!((x
, y
, z
), (12, 3, 4));
44 *return_borrow_from_dropped_box_2(Box
::new(&mut x
)) += 10;
45 assert_eq
!((x
, y
, z
), (22, 3, 4));
46 *return_borrow_of_field_from_dropped_box_1(Box
::new((&mut x
, &mut y
))) += 10;
47 assert_eq
!((x
, y
, z
), (32, 3, 4));
48 *return_borrow_of_field_from_dropped_box_2(Box
::new((&mut x
, &mut y
))) += 10;
49 assert_eq
!((x
, y
, z
), (42, 3, 4));
50 *return_borrow_from_dropped_tupled_box_1((Box
::new((&mut x
, &mut y
)), &mut z
)) += 10;
51 assert_eq
!((x
, y
, z
), (52, 3, 4));
52 *return_borrow_from_dropped_tupled_box_2((Box
::new((&mut x
, &mut y
)), &mut z
)) += 10;
53 assert_eq
!((x
, y
, z
), (62, 3, 4));
56 // These scribbling tests have been transcribed from
57 // issue-45696-scribble-on-boxed-borrow.rs
59 // In the context of that file, these tests are meant to show cases
60 // that should be *accepted* by the compiler, so here we are actually
61 // checking that the code we get when they are compiled matches our
64 struct Scribble
<'a
>(&'a
mut u32);
66 impl<'a
> Drop
for Scribble
<'a
> { fn drop(&mut self) { *self.0 = 42; }
}
68 // this is okay, in both AST-borrowck and NLL: The `Scribble` here *has*
69 // to strictly outlive `'a`
70 fn borrowed_scribble
<'a
>(s
: &'a
mut Scribble
) -> &'a
mut u32 {
74 // this, by analogy to previous case, is also okay.
75 fn boxed_borrowed_scribble
<'a
>(s
: Box
<&'a
mut Scribble
>) -> &'a
mut u32 {
79 // this, by analogy to previous case, is also okay.
80 fn boxed_boxed_borrowed_scribble
<'a
>(s
: Box
<Box
<&'a
mut Scribble
>>) -> &'a
mut u32 {
84 fn scribbling_tests() {
87 let mut long_lived
= Scribble(&mut x
);
88 *borrowed_scribble(&mut long_lived
) += 10;
89 assert_eq
!(*long_lived
.0, 11);
90 // (Scribble dtor runs here, after `&mut`-borrow above ends)
95 let mut long_lived
= Scribble(&mut x
);
96 *boxed_borrowed_scribble(Box
::new(&mut long_lived
)) += 10;
97 assert_eq
!(*long_lived
.0, 11);
98 // (Scribble dtor runs here, after `&mut`-borrow above ends)
103 let mut long_lived
= Scribble(&mut x
);
104 *boxed_boxed_borrowed_scribble(Box
::new(Box
::new(&mut long_lived
))) += 10;
105 assert_eq
!(*long_lived
.0, 11);
106 // (Scribble dtor runs here, after `&mut`-borrow above ends)