From 360ce780fdae0dcb31cfa0f7ffa8a6c9fd62ed32 Mon Sep 17 00:00:00 2001 From: Mazdak Date: Wed, 8 Nov 2017 23:10:33 +0100 Subject: [PATCH 1/7] added associated function Box::leak --- src/liballoc/boxed.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 79292d390e5d2..bcf0505ee82f7 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -364,6 +364,47 @@ impl Box { pub fn into_unique(b: Box) -> Unique { unsafe { mem::transmute(b) } } + + /// Consumes and leaks the `Box`, returning a static reference, + /// `&'static T`. + /// + /// This function is mainly useful for data that lives for the remainder of + /// the programs life. Dropping the returned reference will cause a memory + /// leak. If this is not acceptable, the reference should first be wrapped + /// with the [`Box::from_raw`] function producing a `Box` which can then be + /// dropped which will properly destroy `T` and release the memory. + /// + /// Note: this is an associated function, which means that you have + /// to call it as `Box::leak(b)` instead of `b.leak()`. This + /// is so that there is no conflict with a method on the inner type. + /// + /// [`Box::from_raw`]: struct.Box.html#method.from_raw + /// + /// # Examples + /// + /// Simple usage: + /// + /// ``` + /// let x = Box::new(41); + /// let static_ref = Box::leak(x); + /// *static_ref += 1; + /// assert_eq!(*static_ref, 42); + /// ``` + /// + /// Unsized data: + /// + /// ``` + /// let x = vec![1, 2, 3].into_boxed_slice(); + /// let static_ref = Box::leak(x); + /// static_ref[0] = 4; + /// assert_eq!(*static_ref, [4, 2, 3]); + /// ``` + #[unstable(feature = "box_leak", reason = "needs an FCP to stabilize", + issue = "0")] + #[inline] + pub fn leak(b: Box) -> &'static mut T { + unsafe { &mut *Box::into_raw(b) } + } } #[stable(feature = "rust1", since = "1.0.0")] From 2b48b4779ecde356b701a1b12a602443a78d0e6d Mon Sep 17 00:00:00 2001 From: Mazdak Date: Wed, 8 Nov 2017 23:59:35 +0100 Subject: [PATCH 2/7] Box::leak - improve documentation --- src/liballoc/boxed.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index bcf0505ee82f7..7c3452cc753f7 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -365,14 +365,15 @@ impl Box { unsafe { mem::transmute(b) } } - /// Consumes and leaks the `Box`, returning a static reference, - /// `&'static T`. + /// Consumes and leaks the `Box`, returning a static mutable reference, + /// `&'static mut T`. /// /// This function is mainly useful for data that lives for the remainder of - /// the programs life. Dropping the returned reference will cause a memory + /// the program's life. Dropping the returned reference will cause a memory /// leak. If this is not acceptable, the reference should first be wrapped - /// with the [`Box::from_raw`] function producing a `Box` which can then be - /// dropped which will properly destroy `T` and release the memory. + /// with the [`Box::from_raw`] function producing a `Box`. This `Box` can + /// then be dropped which will properly destroy `T` and release the + /// allocated memory. /// /// Note: this is an associated function, which means that you have /// to call it as `Box::leak(b)` instead of `b.leak()`. This From 79f62cb4d36e77c041fbed60ee0dde2535b9a946 Mon Sep 17 00:00:00 2001 From: Mazdak Date: Thu, 9 Nov 2017 00:15:07 +0100 Subject: [PATCH 3/7] Box::leak - fixed bug in documentation --- src/liballoc/boxed.rs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 7c3452cc753f7..ccaa4d497d45c 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -386,19 +386,27 @@ impl Box { /// Simple usage: /// /// ``` - /// let x = Box::new(41); - /// let static_ref = Box::leak(x); - /// *static_ref += 1; - /// assert_eq!(*static_ref, 42); + /// #![feature(box_leak)] + /// + /// fn main() { + /// let x = Box::new(41); + /// let static_ref = Box::leak(x); + /// *static_ref += 1; + /// assert_eq!(*static_ref, 42); + /// } /// ``` /// /// Unsized data: /// /// ``` - /// let x = vec![1, 2, 3].into_boxed_slice(); - /// let static_ref = Box::leak(x); - /// static_ref[0] = 4; - /// assert_eq!(*static_ref, [4, 2, 3]); + /// #![feature(box_leak)] + /// + /// fn main() { + /// let x = vec![1, 2, 3].into_boxed_slice(); + /// let static_ref = Box::leak(x); + /// static_ref[0] = 4; + /// assert_eq!(*static_ref, [4, 2, 3]); + /// } /// ``` #[unstable(feature = "box_leak", reason = "needs an FCP to stabilize", issue = "0")] From dabb0c6605d2afb96892f7a3dad64b13c934de74 Mon Sep 17 00:00:00 2001 From: Mazdak Date: Thu, 9 Nov 2017 23:25:32 +0100 Subject: [PATCH 4/7] Box::leak - relaxed constraints wrt. lifetimes --- src/liballoc/boxed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index ccaa4d497d45c..58e5c4d66e4c2 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -390,7 +390,7 @@ impl Box { /// /// fn main() { /// let x = Box::new(41); - /// let static_ref = Box::leak(x); + /// let static_ref: &'static mut usize = Box::leak(x); /// *static_ref += 1; /// assert_eq!(*static_ref, 42); /// } @@ -411,7 +411,7 @@ impl Box { #[unstable(feature = "box_leak", reason = "needs an FCP to stabilize", issue = "0")] #[inline] - pub fn leak(b: Box) -> &'static mut T { + pub fn leak<'a, T: 'a>(b: Box) -> &'a mut T { unsafe { &mut *Box::into_raw(b) } } } From ee24e992b640d09d31d34938dbe7131db9cb18a9 Mon Sep 17 00:00:00 2001 From: Mazdak Date: Thu, 9 Nov 2017 23:27:58 +0100 Subject: [PATCH 5/7] Box::leak - updated documentation --- src/liballoc/boxed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 58e5c4d66e4c2..49f5f68fa770a 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -365,8 +365,8 @@ impl Box { unsafe { mem::transmute(b) } } - /// Consumes and leaks the `Box`, returning a static mutable reference, - /// `&'static mut T`. + /// Consumes and leaks the `Box`, returning a mutable reference, + /// `&'a mut T`. Here, the lifetime `'a` may be chosen to be `'static`. /// /// This function is mainly useful for data that lives for the remainder of /// the program's life. Dropping the returned reference will cause a memory From 46800ab135f70d8869e58e4163730ba2b38006ba Mon Sep 17 00:00:00 2001 From: Mazdak Date: Thu, 9 Nov 2017 23:39:18 +0100 Subject: [PATCH 6/7] Box::leak - made an oops, fixed now =) --- src/liballoc/boxed.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 49f5f68fa770a..c76f51057ff98 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -411,7 +411,10 @@ impl Box { #[unstable(feature = "box_leak", reason = "needs an FCP to stabilize", issue = "0")] #[inline] - pub fn leak<'a, T: 'a>(b: Box) -> &'a mut T { + pub fn leak<'a>(b: Box) -> &'a mut T + where + T: 'a // Technically not needed, but kept to be explicit. + { unsafe { &mut *Box::into_raw(b) } } } From bc18d99232b4d049e24d64ae228f0ee0c01fcebd Mon Sep 17 00:00:00 2001 From: Mazdak Date: Wed, 22 Nov 2017 07:21:30 +0100 Subject: [PATCH 7/7] Box::leak: update unstable issue number (46179). --- src/liballoc/boxed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index c76f51057ff98..7910c6b61f3c6 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -409,7 +409,7 @@ impl Box { /// } /// ``` #[unstable(feature = "box_leak", reason = "needs an FCP to stabilize", - issue = "0")] + issue = "46179")] #[inline] pub fn leak<'a>(b: Box) -> &'a mut T where