]> git.lizzy.rs Git - rust.git/commitdiff
Expand long-live-borrows-in-boxes test to include simplier illustrative cases.
authorFelix S. Klock II <pnkfelix@pnkfx.org>
Mon, 30 Jul 2018 14:17:04 +0000 (16:17 +0200)
committerFelix S. Klock II <pnkfelix@pnkfx.org>
Wed, 1 Aug 2018 15:44:53 +0000 (17:44 +0200)
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.

src/test/ui/issue-45696-long-live-borrows-in-boxes.rs

index e5326bb315ea392720faf822e4215479adb0c7d6..881f37c2e0b0e59dc6c68d5ff2e9732af7b182f4 100644 (file)
 
 // 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