Skip to content

Commit fc550d4

Browse files
committed
Auto merge of #61421 - vorner:string-in-rc-into-raw-docs, r=RalfJung
docs: Use String in Rc::into_raw examples It is unclear if accessing an integer after `drop_in_place` has been called on it is undefined behaviour or not, as demonstrated by the discussion in #60766 (review). Avoid these uncertainties by using String which frees memory in its `drop_in_place` to make sure this is undefined behaviour. The message in the docs should be to watch out and not access the data after that, not discussing when one maybe could get away with it O:-).
2 parents e699ea0 + 79e5839 commit fc550d4

File tree

2 files changed

+28
-28
lines changed

2 files changed

+28
-28
lines changed

src/liballoc/rc.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -375,9 +375,9 @@ impl<T: ?Sized> Rc<T> {
375375
/// ```
376376
/// use std::rc::Rc;
377377
///
378-
/// let x = Rc::new(10);
378+
/// let x = Rc::new("hello".to_owned());
379379
/// let x_ptr = Rc::into_raw(x);
380-
/// assert_eq!(unsafe { *x_ptr }, 10);
380+
/// assert_eq!(unsafe { &*x_ptr }, "hello");
381381
/// ```
382382
#[stable(feature = "rc_raw", since = "1.17.0")]
383383
pub fn into_raw(this: Self) -> *const T {
@@ -401,13 +401,13 @@ impl<T: ?Sized> Rc<T> {
401401
/// ```
402402
/// use std::rc::Rc;
403403
///
404-
/// let x = Rc::new(10);
404+
/// let x = Rc::new("hello".to_owned());
405405
/// let x_ptr = Rc::into_raw(x);
406406
///
407407
/// unsafe {
408408
/// // Convert back to an `Rc` to prevent leak.
409409
/// let x = Rc::from_raw(x_ptr);
410-
/// assert_eq!(*x, 10);
410+
/// assert_eq!(&*x, "hello");
411411
///
412412
/// // Further calls to `Rc::from_raw(x_ptr)` would be memory unsafe.
413413
/// }
@@ -437,10 +437,10 @@ impl<T: ?Sized> Rc<T> {
437437
///
438438
/// use std::rc::Rc;
439439
///
440-
/// let x = Rc::new(10);
440+
/// let x = Rc::new("hello".to_owned());
441441
/// let ptr = Rc::into_raw_non_null(x);
442-
/// let deref = unsafe { *ptr.as_ref() };
443-
/// assert_eq!(deref, 10);
442+
/// let deref = unsafe { ptr.as_ref() };
443+
/// assert_eq!(deref, "hello");
444444
/// ```
445445
#[unstable(feature = "rc_into_raw_non_null", issue = "47336")]
446446
#[inline]
@@ -1294,17 +1294,17 @@ impl<T> Weak<T> {
12941294
/// use std::rc::{Rc, Weak};
12951295
/// use std::ptr;
12961296
///
1297-
/// let strong = Rc::new(42);
1297+
/// let strong = Rc::new("hello".to_owned());
12981298
/// let weak = Rc::downgrade(&strong);
12991299
/// // Both point to the same object
13001300
/// assert!(ptr::eq(&*strong, Weak::as_raw(&weak)));
13011301
/// // The strong here keeps it alive, so we can still access the object.
1302-
/// assert_eq!(42, unsafe { *Weak::as_raw(&weak) });
1302+
/// assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) });
13031303
///
13041304
/// drop(strong);
13051305
/// // But not any more. We can do Weak::as_raw(&weak), but accessing the pointer would lead to
13061306
/// // undefined behaviour.
1307-
/// // assert_eq!(42, unsafe { *Weak::as_raw(&weak) });
1307+
/// // assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) });
13081308
/// ```
13091309
///
13101310
/// [`null`]: ../../std/ptr/fn.null.html
@@ -1339,12 +1339,12 @@ impl<T> Weak<T> {
13391339
///
13401340
/// use std::rc::{Rc, Weak};
13411341
///
1342-
/// let strong = Rc::new(42);
1342+
/// let strong = Rc::new("hello".to_owned());
13431343
/// let weak = Rc::downgrade(&strong);
13441344
/// let raw = Weak::into_raw(weak);
13451345
///
13461346
/// assert_eq!(1, Rc::weak_count(&strong));
1347-
/// assert_eq!(42, unsafe { *raw });
1347+
/// assert_eq!("hello", unsafe { &*raw });
13481348
///
13491349
/// drop(unsafe { Weak::from_raw(raw) });
13501350
/// assert_eq!(0, Rc::weak_count(&strong));
@@ -1380,14 +1380,14 @@ impl<T> Weak<T> {
13801380
///
13811381
/// use std::rc::{Rc, Weak};
13821382
///
1383-
/// let strong = Rc::new(42);
1383+
/// let strong = Rc::new("hello".to_owned());
13841384
///
13851385
/// let raw_1 = Weak::into_raw(Rc::downgrade(&strong));
13861386
/// let raw_2 = Weak::into_raw(Rc::downgrade(&strong));
13871387
///
13881388
/// assert_eq!(2, Rc::weak_count(&strong));
13891389
///
1390-
/// assert_eq!(42, *Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap());
1390+
/// assert_eq!("hello", &*Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap());
13911391
/// assert_eq!(1, Rc::weak_count(&strong));
13921392
///
13931393
/// drop(strong);

src/liballoc/sync.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -356,9 +356,9 @@ impl<T: ?Sized> Arc<T> {
356356
/// ```
357357
/// use std::sync::Arc;
358358
///
359-
/// let x = Arc::new(10);
359+
/// let x = Arc::new("hello".to_owned());
360360
/// let x_ptr = Arc::into_raw(x);
361-
/// assert_eq!(unsafe { *x_ptr }, 10);
361+
/// assert_eq!(unsafe { &*x_ptr }, "hello");
362362
/// ```
363363
#[stable(feature = "rc_raw", since = "1.17.0")]
364364
pub fn into_raw(this: Self) -> *const T {
@@ -382,13 +382,13 @@ impl<T: ?Sized> Arc<T> {
382382
/// ```
383383
/// use std::sync::Arc;
384384
///
385-
/// let x = Arc::new(10);
385+
/// let x = Arc::new("hello".to_owned());
386386
/// let x_ptr = Arc::into_raw(x);
387387
///
388388
/// unsafe {
389389
/// // Convert back to an `Arc` to prevent leak.
390390
/// let x = Arc::from_raw(x_ptr);
391-
/// assert_eq!(*x, 10);
391+
/// assert_eq!(&*x, "hello");
392392
///
393393
/// // Further calls to `Arc::from_raw(x_ptr)` would be memory unsafe.
394394
/// }
@@ -418,10 +418,10 @@ impl<T: ?Sized> Arc<T> {
418418
///
419419
/// use std::sync::Arc;
420420
///
421-
/// let x = Arc::new(10);
421+
/// let x = Arc::new("hello".to_owned());
422422
/// let ptr = Arc::into_raw_non_null(x);
423-
/// let deref = unsafe { *ptr.as_ref() };
424-
/// assert_eq!(deref, 10);
423+
/// let deref = unsafe { ptr.as_ref() };
424+
/// assert_eq!(deref, "hello");
425425
/// ```
426426
#[unstable(feature = "rc_into_raw_non_null", issue = "47336")]
427427
#[inline]
@@ -1083,17 +1083,17 @@ impl<T> Weak<T> {
10831083
/// use std::sync::{Arc, Weak};
10841084
/// use std::ptr;
10851085
///
1086-
/// let strong = Arc::new(42);
1086+
/// let strong = Arc::new("hello".to_owned());
10871087
/// let weak = Arc::downgrade(&strong);
10881088
/// // Both point to the same object
10891089
/// assert!(ptr::eq(&*strong, Weak::as_raw(&weak)));
10901090
/// // The strong here keeps it alive, so we can still access the object.
1091-
/// assert_eq!(42, unsafe { *Weak::as_raw(&weak) });
1091+
/// assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) });
10921092
///
10931093
/// drop(strong);
10941094
/// // But not any more. We can do Weak::as_raw(&weak), but accessing the pointer would lead to
10951095
/// // undefined behaviour.
1096-
/// // assert_eq!(42, unsafe { *Weak::as_raw(&weak) });
1096+
/// // assert_eq!("hello", unsafe { &*Weak::as_raw(&weak) });
10971097
/// ```
10981098
///
10991099
/// [`null`]: ../../std/ptr/fn.null.html
@@ -1128,12 +1128,12 @@ impl<T> Weak<T> {
11281128
///
11291129
/// use std::sync::{Arc, Weak};
11301130
///
1131-
/// let strong = Arc::new(42);
1131+
/// let strong = Arc::new("hello".to_owned());
11321132
/// let weak = Arc::downgrade(&strong);
11331133
/// let raw = Weak::into_raw(weak);
11341134
///
11351135
/// assert_eq!(1, Arc::weak_count(&strong));
1136-
/// assert_eq!(42, unsafe { *raw });
1136+
/// assert_eq!("hello", unsafe { &*raw });
11371137
///
11381138
/// drop(unsafe { Weak::from_raw(raw) });
11391139
/// assert_eq!(0, Arc::weak_count(&strong));
@@ -1170,14 +1170,14 @@ impl<T> Weak<T> {
11701170
///
11711171
/// use std::sync::{Arc, Weak};
11721172
///
1173-
/// let strong = Arc::new(42);
1173+
/// let strong = Arc::new("hello".to_owned());
11741174
///
11751175
/// let raw_1 = Weak::into_raw(Arc::downgrade(&strong));
11761176
/// let raw_2 = Weak::into_raw(Arc::downgrade(&strong));
11771177
///
11781178
/// assert_eq!(2, Arc::weak_count(&strong));
11791179
///
1180-
/// assert_eq!(42, *Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap());
1180+
/// assert_eq!("hello", &*Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap());
11811181
/// assert_eq!(1, Arc::weak_count(&strong));
11821182
///
11831183
/// drop(strong);

0 commit comments

Comments
 (0)