Skip to content

Commit aa931e9

Browse files
committed
std: Move free-functions to associated functions
This commit moves the free functions in the `rc`, `arc`, and `boxed` modules to associated functions on their respective types, following the recent trend towards this pattern. The previous free functions are all left in-place with `#[deprecated]` pointers towards the new locations. This commit also deprecates `arc::get_mut` and `Arc::make_unique` with no replacement as they are racy in the face of weak pointers.
1 parent 3346fb0 commit aa931e9

File tree

3 files changed

+153
-35
lines changed

3 files changed

+153
-35
lines changed

src/liballoc/arc.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,21 @@ impl<T: ?Sized> Arc<T> {
205205
self.inner().weak.fetch_add(1, Relaxed);
206206
Weak { _ptr: self._ptr }
207207
}
208-
}
209208

210-
impl<T: ?Sized> Arc<T> {
209+
/// Get the number of weak references to this value.
210+
#[inline]
211+
#[unstable(feature = "arc_counts")]
212+
pub fn weak_count(this: &Arc<T>) -> usize {
213+
this.inner().weak.load(SeqCst) - 1
214+
}
215+
216+
/// Get the number of strong references to this value.
217+
#[inline]
218+
#[unstable(feature = "arc_counts")]
219+
pub fn strong_count(this: &Arc<T>) -> usize {
220+
this.inner().strong.load(SeqCst)
221+
}
222+
211223
#[inline]
212224
fn inner(&self) -> &ArcInner<T> {
213225
// This unsafety is ok because while this arc is alive we're guaranteed
@@ -237,12 +249,14 @@ impl<T: ?Sized> Arc<T> {
237249
/// Get the number of weak references to this value.
238250
#[inline]
239251
#[unstable(feature = "arc_counts")]
240-
pub fn weak_count<T: ?Sized>(this: &Arc<T>) -> usize { this.inner().weak.load(SeqCst) - 1 }
252+
#[deprecated(since = "1.2.0", reason = "renamed to Arc::weak_count")]
253+
pub fn weak_count<T: ?Sized>(this: &Arc<T>) -> usize { Arc::weak_count(this) }
241254

242255
/// Get the number of strong references to this value.
243256
#[inline]
244257
#[unstable(feature = "arc_counts")]
245-
pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { this.inner().strong.load(SeqCst) }
258+
#[deprecated(since = "1.2.0", reason = "renamed to Arc::strong_count")]
259+
pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { Arc::strong_count(this) }
246260

247261

248262
/// Returns a mutable reference to the contained value if the `Arc<T>` is unique.
@@ -272,6 +286,8 @@ pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { this.inner().strong.loa
272286
/// ```
273287
#[inline]
274288
#[unstable(feature = "arc_unique")]
289+
#[deprecated(since = "1.2.0",
290+
reason = "this function is unsafe with weak pointers")]
275291
pub unsafe fn get_mut<T: ?Sized>(this: &mut Arc<T>) -> Option<&mut T> {
276292
// FIXME(#24880) potential race with upgraded weak pointers here
277293
if strong_count(this) == 1 && weak_count(this) == 0 {
@@ -353,6 +369,8 @@ impl<T: Clone> Arc<T> {
353369
/// ```
354370
#[inline]
355371
#[unstable(feature = "arc_unique")]
372+
#[deprecated(since = "1.2.0",
373+
reason = "this function is unsafe with weak pointers")]
356374
pub unsafe fn make_unique(&mut self) -> &mut T {
357375
// FIXME(#24880) potential race with upgraded weak pointers here
358376
//

src/liballoc/boxed.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,29 @@ impl<T : ?Sized> Box<T> {
127127
pub unsafe fn from_raw(raw: *mut T) -> Self {
128128
mem::transmute(raw)
129129
}
130+
131+
/// Consumes the `Box`, returning the wrapped raw pointer.
132+
///
133+
/// After call to this function, caller is responsible for the memory
134+
/// previously managed by `Box`, in particular caller should properly
135+
/// destroy `T` and release memory. The proper way to do it is to
136+
/// convert pointer back to `Box` with `Box::from_raw` function, because
137+
/// `Box` does not specify, how memory is allocated.
138+
///
139+
/// # Examples
140+
/// ```
141+
/// # #![feature(box_raw)]
142+
/// use std::boxed;
143+
///
144+
/// let seventeen = Box::new(17u32);
145+
/// let raw = boxed::into_raw(seventeen);
146+
/// let boxed_again = unsafe { Box::from_raw(raw) };
147+
/// ```
148+
#[unstable(feature = "box_raw", reason = "may be renamed")]
149+
#[inline]
150+
pub fn into_raw(b: Box<T>) -> *mut T {
151+
unsafe { mem::transmute(b) }
152+
}
130153
}
131154

132155
/// Consumes the `Box`, returning the wrapped raw pointer.
@@ -146,11 +169,11 @@ impl<T : ?Sized> Box<T> {
146169
/// let raw = boxed::into_raw(seventeen);
147170
/// let boxed_again = unsafe { Box::from_raw(raw) };
148171
/// ```
149-
#[unstable(feature = "box_raw",
150-
reason = "may be renamed")]
172+
#[unstable(feature = "box_raw", reason = "may be renamed")]
173+
#[deprecated(since = "1.2.0", reason = "renamed to Box::into_raw")]
151174
#[inline]
152175
pub fn into_raw<T : ?Sized>(b: Box<T>) -> *mut T {
153-
unsafe { mem::transmute(b) }
176+
Box::into_raw(b)
154177
}
155178

156179
#[stable(feature = "rust1", since = "1.0.0")]

src/liballoc/rc.rs

Lines changed: 105 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,42 @@ impl<T> Rc<T> {
220220
}
221221
}
222222
}
223+
224+
/// Unwraps the contained value if the `Rc<T>` is unique.
225+
///
226+
/// If the `Rc<T>` is not unique, an `Err` is returned with the same
227+
/// `Rc<T>`.
228+
///
229+
/// # Examples
230+
///
231+
/// ```
232+
/// # #![feature(rc_unique)]
233+
/// use std::rc::{self, Rc};
234+
///
235+
/// let x = Rc::new(3);
236+
/// assert_eq!(rc::try_unwrap(x), Ok(3));
237+
///
238+
/// let x = Rc::new(4);
239+
/// let _y = x.clone();
240+
/// assert_eq!(rc::try_unwrap(x), Err(Rc::new(4)));
241+
/// ```
242+
#[inline]
243+
#[unstable(feature = "rc_unique")]
244+
pub fn try_unwrap(rc: Rc<T>) -> Result<T, Rc<T>> {
245+
if Rc::is_unique(&rc) {
246+
unsafe {
247+
let val = ptr::read(&*rc); // copy the contained object
248+
// destruct the box and skip our Drop
249+
// we can ignore the refcounts because we know we're unique
250+
deallocate(*rc._ptr as *mut u8, size_of::<RcBox<T>>(),
251+
min_align_of::<RcBox<T>>());
252+
forget(rc);
253+
Ok(val)
254+
}
255+
} else {
256+
Err(rc)
257+
}
258+
}
223259
}
224260

225261
impl<T: ?Sized> Rc<T> {
@@ -241,17 +277,78 @@ impl<T: ?Sized> Rc<T> {
241277
self.inc_weak();
242278
Weak { _ptr: self._ptr }
243279
}
280+
281+
/// Get the number of weak references to this value.
282+
#[inline]
283+
#[unstable(feature = "rc_counts")]
284+
pub fn weak_count(this: &Rc<T>) -> usize { this.weak() - 1 }
285+
286+
/// Get the number of strong references to this value.
287+
#[inline]
288+
#[unstable(feature = "rc_counts")]
289+
pub fn strong_count(this: &Rc<T>) -> usize { this.strong() }
290+
291+
/// Returns true if there are no other `Rc` or `Weak<T>` values that share
292+
/// the same inner value.
293+
///
294+
/// # Examples
295+
///
296+
/// ```
297+
/// # #![feature(rc_unique)]
298+
/// use std::rc;
299+
/// use std::rc::Rc;
300+
///
301+
/// let five = Rc::new(5);
302+
///
303+
/// rc::is_unique(&five);
304+
/// ```
305+
#[inline]
306+
#[unstable(feature = "rc_unique")]
307+
pub fn is_unique(rc: &Rc<T>) -> bool {
308+
weak_count(rc) == 0 && strong_count(rc) == 1
309+
}
310+
311+
/// Returns a mutable reference to the contained value if the `Rc<T>` is
312+
/// unique.
313+
///
314+
/// Returns `None` if the `Rc<T>` is not unique.
315+
///
316+
/// # Examples
317+
///
318+
/// ```
319+
/// # #![feature(rc_unique)]
320+
/// use std::rc::{self, Rc};
321+
///
322+
/// let mut x = Rc::new(3);
323+
/// *rc::get_mut(&mut x).unwrap() = 4;
324+
/// assert_eq!(*x, 4);
325+
///
326+
/// let _y = x.clone();
327+
/// assert!(rc::get_mut(&mut x).is_none());
328+
/// ```
329+
#[inline]
330+
#[unstable(feature = "rc_unique")]
331+
pub fn get_mut(rc: &mut Rc<T>) -> Option<&mut T> {
332+
if Rc::is_unique(rc) {
333+
let inner = unsafe { &mut **rc._ptr };
334+
Some(&mut inner.value)
335+
} else {
336+
None
337+
}
338+
}
244339
}
245340

246341
/// Get the number of weak references to this value.
247342
#[inline]
248343
#[unstable(feature = "rc_counts")]
249-
pub fn weak_count<T: ?Sized>(this: &Rc<T>) -> usize { this.weak() - 1 }
344+
#[deprecated(since = "1.2.0", reason = "renamed to Rc::weak_count")]
345+
pub fn weak_count<T: ?Sized>(this: &Rc<T>) -> usize { Rc::weak_count(this) }
250346

251347
/// Get the number of strong references to this value.
252348
#[inline]
253349
#[unstable(feature = "rc_counts")]
254-
pub fn strong_count<T: ?Sized>(this: &Rc<T>) -> usize { this.strong() }
350+
#[deprecated(since = "1.2.0", reason = "renamed to Rc::strong_count")]
351+
pub fn strong_count<T: ?Sized>(this: &Rc<T>) -> usize { Rc::strong_count(this) }
255352

256353
/// Returns true if there are no other `Rc` or `Weak<T>` values that share the
257354
/// same inner value.
@@ -269,9 +366,8 @@ pub fn strong_count<T: ?Sized>(this: &Rc<T>) -> usize { this.strong() }
269366
/// ```
270367
#[inline]
271368
#[unstable(feature = "rc_unique")]
272-
pub fn is_unique<T>(rc: &Rc<T>) -> bool {
273-
weak_count(rc) == 0 && strong_count(rc) == 1
274-
}
369+
#[deprecated(since = "1.2.0", reason = "renamed to Rc::is_unique")]
370+
pub fn is_unique<T>(rc: &Rc<T>) -> bool { Rc::is_unique(rc) }
275371

276372
/// Unwraps the contained value if the `Rc<T>` is unique.
277373
///
@@ -292,21 +388,8 @@ pub fn is_unique<T>(rc: &Rc<T>) -> bool {
292388
/// ```
293389
#[inline]
294390
#[unstable(feature = "rc_unique")]
295-
pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> {
296-
if is_unique(&rc) {
297-
unsafe {
298-
let val = ptr::read(&*rc); // copy the contained object
299-
// destruct the box and skip our Drop
300-
// we can ignore the refcounts because we know we're unique
301-
deallocate(*rc._ptr as *mut u8, size_of::<RcBox<T>>(),
302-
min_align_of::<RcBox<T>>());
303-
forget(rc);
304-
Ok(val)
305-
}
306-
} else {
307-
Err(rc)
308-
}
309-
}
391+
#[deprecated(since = "1.2.0", reason = "renamed to Rc::try_unwrap")]
392+
pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> { Rc::try_unwrap(rc) }
310393

311394
/// Returns a mutable reference to the contained value if the `Rc<T>` is unique.
312395
///
@@ -327,14 +410,8 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> {
327410
/// ```
328411
#[inline]
329412
#[unstable(feature = "rc_unique")]
330-
pub fn get_mut<T>(rc: &mut Rc<T>) -> Option<&mut T> {
331-
if is_unique(rc) {
332-
let inner = unsafe { &mut **rc._ptr };
333-
Some(&mut inner.value)
334-
} else {
335-
None
336-
}
337-
}
413+
#[deprecated(since = "1.2.0", reason = "renamed to Rc::get_mut")]
414+
pub fn get_mut<T>(rc: &mut Rc<T>) -> Option<&mut T> { Rc::get_mut(rc) }
338415

339416
impl<T: Clone> Rc<T> {
340417
/// Make a mutable reference from the given `Rc<T>`.

0 commit comments

Comments
 (0)