@@ -250,6 +250,9 @@ pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { this.inner().strong.loa
250250///
251251/// Returns `None` if the `Arc<T>` is not unique.
252252///
253+ /// This function is marked **unsafe** because it is racy if weak pointers
254+ /// are active.
255+ ///
253256/// # Examples
254257///
255258/// ```
@@ -258,24 +261,27 @@ pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { this.inner().strong.loa
258261/// # fn main() {
259262/// use alloc::arc::{Arc, get_mut};
260263///
264+ /// # unsafe {
261265/// let mut x = Arc::new(3);
262266/// *get_mut(&mut x).unwrap() = 4;
263267/// assert_eq!(*x, 4);
264268///
265269/// let _y = x.clone();
266270/// assert!(get_mut(&mut x).is_none());
267271/// # }
272+ /// # }
268273/// ```
269274#[ inline]
270275#[ unstable( feature = "alloc" ) ]
271- pub fn get_mut < T : ?Sized > ( this : & mut Arc < T > ) -> Option < & mut T > {
276+ pub unsafe fn get_mut < T : ?Sized > ( this : & mut Arc < T > ) -> Option < & mut T > {
277+ // FIXME(#24880) potential race with upgraded weak pointers here
272278 if strong_count ( this) == 1 && weak_count ( this) == 0 {
273279 // This unsafety is ok because we're guaranteed that the pointer
274280 // returned is the *only* pointer that will ever be returned to T. Our
275281 // reference count is guaranteed to be 1 at this point, and we required
276282 // the Arc itself to be `mut`, so we're returning the only possible
277283 // reference to the inner data.
278- let inner = unsafe { & mut * * this. _ptr } ;
284+ let inner = & mut * * this. _ptr ;
279285 Some ( & mut inner. data )
280286 } else {
281287 None
@@ -332,19 +338,26 @@ impl<T: Clone> Arc<T> {
332338 /// This is also referred to as a copy-on-write operation because the inner
333339 /// data is cloned if the reference count is greater than one.
334340 ///
341+ /// This method is marked **unsafe** because it is racy if weak pointers
342+ /// are active.
343+ ///
335344 /// # Examples
336345 ///
337346 /// ```
338347 /// # #![feature(alloc)]
339348 /// use std::sync::Arc;
340349 ///
350+ /// # unsafe {
341351 /// let mut five = Arc::new(5);
342352 ///
343353 /// let mut_five = five.make_unique();
354+ /// # }
344355 /// ```
345356 #[ inline]
346357 #[ unstable( feature = "alloc" ) ]
347- pub fn make_unique ( & mut self ) -> & mut T {
358+ pub unsafe fn make_unique ( & mut self ) -> & mut T {
359+ // FIXME(#24880) potential race with upgraded weak pointers here
360+ //
348361 // Note that we hold a strong reference, which also counts as a weak
349362 // reference, so we only clone if there is an additional reference of
350363 // either kind.
@@ -354,7 +367,7 @@ impl<T: Clone> Arc<T> {
354367 }
355368 // As with `get_mut()`, the unsafety is ok because our reference was
356369 // either unique to begin with, or became one upon cloning the contents.
357- let inner = unsafe { & mut * * self . _ptr } ;
370+ let inner = & mut * * self . _ptr ;
358371 & mut inner. data
359372 }
360373}
@@ -744,39 +757,43 @@ mod tests {
744757
745758 #[ test]
746759 fn test_arc_get_mut ( ) {
747- let mut x = Arc :: new ( 3 ) ;
748- * get_mut ( & mut x) . unwrap ( ) = 4 ;
749- assert_eq ! ( * x, 4 ) ;
750- let y = x. clone ( ) ;
751- assert ! ( get_mut( & mut x) . is_none( ) ) ;
752- drop ( y) ;
753- assert ! ( get_mut( & mut x) . is_some( ) ) ;
754- let _w = x. downgrade ( ) ;
755- assert ! ( get_mut( & mut x) . is_none( ) ) ;
760+ unsafe {
761+ let mut x = Arc :: new ( 3 ) ;
762+ * get_mut ( & mut x) . unwrap ( ) = 4 ;
763+ assert_eq ! ( * x, 4 ) ;
764+ let y = x. clone ( ) ;
765+ assert ! ( get_mut( & mut x) . is_none( ) ) ;
766+ drop ( y) ;
767+ assert ! ( get_mut( & mut x) . is_some( ) ) ;
768+ let _w = x. downgrade ( ) ;
769+ assert ! ( get_mut( & mut x) . is_none( ) ) ;
770+ }
756771 }
757772
758773 #[ test]
759774 fn test_cowarc_clone_make_unique ( ) {
760- let mut cow0 = Arc :: new ( 75 ) ;
761- let mut cow1 = cow0. clone ( ) ;
762- let mut cow2 = cow1. clone ( ) ;
763-
764- assert ! ( 75 == * cow0. make_unique( ) ) ;
765- assert ! ( 75 == * cow1. make_unique( ) ) ;
766- assert ! ( 75 == * cow2. make_unique( ) ) ;
767-
768- * cow0. make_unique ( ) += 1 ;
769- * cow1. make_unique ( ) += 2 ;
770- * cow2. make_unique ( ) += 3 ;
771-
772- assert ! ( 76 == * cow0) ;
773- assert ! ( 77 == * cow1) ;
774- assert ! ( 78 == * cow2) ;
775-
776- // none should point to the same backing memory
777- assert ! ( * cow0 != * cow1) ;
778- assert ! ( * cow0 != * cow2) ;
779- assert ! ( * cow1 != * cow2) ;
775+ unsafe {
776+ let mut cow0 = Arc :: new ( 75 ) ;
777+ let mut cow1 = cow0. clone ( ) ;
778+ let mut cow2 = cow1. clone ( ) ;
779+
780+ assert ! ( 75 == * cow0. make_unique( ) ) ;
781+ assert ! ( 75 == * cow1. make_unique( ) ) ;
782+ assert ! ( 75 == * cow2. make_unique( ) ) ;
783+
784+ * cow0. make_unique ( ) += 1 ;
785+ * cow1. make_unique ( ) += 2 ;
786+ * cow2. make_unique ( ) += 3 ;
787+
788+ assert ! ( 76 == * cow0) ;
789+ assert ! ( 77 == * cow1) ;
790+ assert ! ( 78 == * cow2) ;
791+
792+ // none should point to the same backing memory
793+ assert ! ( * cow0 != * cow1) ;
794+ assert ! ( * cow0 != * cow2) ;
795+ assert ! ( * cow1 != * cow2) ;
796+ }
780797 }
781798
782799 #[ test]
@@ -789,7 +806,9 @@ mod tests {
789806 assert ! ( 75 == * cow1) ;
790807 assert ! ( 75 == * cow2) ;
791808
792- * cow0. make_unique ( ) += 1 ;
809+ unsafe {
810+ * cow0. make_unique ( ) += 1 ;
811+ }
793812
794813 assert ! ( 76 == * cow0) ;
795814 assert ! ( 75 == * cow1) ;
@@ -810,7 +829,9 @@ mod tests {
810829 assert ! ( 75 == * cow0) ;
811830 assert ! ( 75 == * cow1_weak. upgrade( ) . unwrap( ) ) ;
812831
813- * cow0. make_unique ( ) += 1 ;
832+ unsafe {
833+ * cow0. make_unique ( ) += 1 ;
834+ }
814835
815836 assert ! ( 76 == * cow0) ;
816837 assert ! ( cow1_weak. upgrade( ) . is_none( ) ) ;
0 commit comments