Skip to content

Commit

Permalink
Expand long-live-borrows-in-boxes test to include simplier illustrati…
Browse files Browse the repository at this point in the history
…ve cases.

After talking about the PR with eddyb, I decided it was best to try to
have some test cases that simplify the problem down to its core, so
that people trying to understand what the issue is here will see those
core examples first.
  • Loading branch information
pnkfelix committed Aug 1, 2018
1 parent 469d6a8 commit a1b8a93
Showing 1 changed file with 35 additions and 5 deletions.
40 changes: 35 additions & 5 deletions src/test/ui/issue-45696-long-live-borrows-in-boxes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,54 @@

// run-pass

type Boxed<'a, 'b> = Box<(&'a mut u32, &'b mut u32)>;
// This function shows quite directly what is going on: We have a
// reborrow of contents within the box.
fn return_borrow_from_dropped_box_1(x: Box<&mut u32>) -> &mut u32 { &mut **x }

fn return_borrow_from_dropped_box<'a>(x: Boxed<'a, '_>) -> &'a mut u32 {
// This function is the way you'll probably see this in practice (the
// reborrow is now implicit).
fn return_borrow_from_dropped_box_2(x: Box<&mut u32>) -> &mut u32 { *x }

// For the remaining tests we just add some fields or other
// indirection to ensure that the compiler isn't just special-casing
// the above `Box<&mut T>` as the only type that would work.

// Here we add a tuple of indirection between the box and the
// reference.
type BoxedTup<'a, 'b> = Box<(&'a mut u32, &'b mut u32)>;

fn return_borrow_of_field_from_dropped_box_1<'a>(x: BoxedTup<'a, '_>) -> &'a mut u32 {
&mut *x.0
}

fn return_borrow_from_dropped_tupled_box<'a>(x: (Boxed<'a, '_>, &mut u32)) -> &'a mut u32 {
fn return_borrow_of_field_from_dropped_box_2<'a>(x: BoxedTup<'a, '_>) -> &'a mut u32 {
x.0
}

fn return_borrow_from_dropped_tupled_box_1<'a>(x: (BoxedTup<'a, '_>, &mut u32)) -> &'a mut u32 {
&mut *(x.0).0
}

fn return_borrow_from_dropped_tupled_box_2<'a>(x: (BoxedTup<'a, '_>, &mut u32)) -> &'a mut u32 {
(x.0).0
}

fn basic_tests() {
let mut x = 2;
let mut y = 3;
let mut z = 4;
*return_borrow_from_dropped_box(Box::new((&mut x, &mut y))) += 10;
*return_borrow_from_dropped_box_1(Box::new(&mut x)) += 10;
assert_eq!((x, y, z), (12, 3, 4));
*return_borrow_from_dropped_tupled_box((Box::new((&mut x, &mut y)), &mut z)) += 10;
*return_borrow_from_dropped_box_2(Box::new(&mut x)) += 10;
assert_eq!((x, y, z), (22, 3, 4));
*return_borrow_of_field_from_dropped_box_1(Box::new((&mut x, &mut y))) += 10;
assert_eq!((x, y, z), (32, 3, 4));
*return_borrow_of_field_from_dropped_box_2(Box::new((&mut x, &mut y))) += 10;
assert_eq!((x, y, z), (42, 3, 4));
*return_borrow_from_dropped_tupled_box_1((Box::new((&mut x, &mut y)), &mut z)) += 10;
assert_eq!((x, y, z), (52, 3, 4));
*return_borrow_from_dropped_tupled_box_2((Box::new((&mut x, &mut y)), &mut z)) += 10;
assert_eq!((x, y, z), (62, 3, 4));
}

// These scribbling tests have been transcribed from
Expand Down

0 comments on commit a1b8a93

Please sign in to comment.