Skip to content

Commit 8c38cb7

Browse files
committed
Add examples to show when {Arc,Rc}::get_mut_unchecked is disallowed.
1 parent 96650fc commit 8c38cb7

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

library/alloc/src/rc.rs

+32
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,38 @@ impl<T: ?Sized> Rc<T> {
11101110
/// }
11111111
/// assert_eq!(*x, "foo");
11121112
/// ```
1113+
/// Other `Rc` pointers to the same allocation must be to the same type.
1114+
/// ```ignore
1115+
/// #![feature(get_mut_unchecked)]
1116+
///
1117+
/// use std::rc::Rc;
1118+
///
1119+
/// let x: Rc<str> = Rc::from("Hello, world!");
1120+
/// let mut y: Rc<[u8]> = x.clone().into();
1121+
/// unsafe {
1122+
/// // this is Undefined Behavior, because x's inner type is str, not [u8]
1123+
/// Rc::get_mut_unchecked(&mut y).fill(0xff); // 0xff is invalid in UTF-8
1124+
/// }
1125+
/// println!("{}", &*x); // Invliad UTF-8 in a str
1126+
/// ```
1127+
/// Other `Rc` pointers to the same allocation must be to the exact same type, including lifetimes.
1128+
/// ```ignore
1129+
/// #![feature(get_mut_unchecked)]
1130+
///
1131+
/// use std::rc::Rc;
1132+
///
1133+
/// let x: Rc<&str> = Rc::new("Hello, world!");
1134+
/// {
1135+
/// let s = String::from("Oh, no!");
1136+
/// let mut y: Rc<&str> = x.clone().into();
1137+
/// unsafe {
1138+
/// // this is Undefined Behavior, because x's inner type
1139+
/// // is &'long str, not &'short str
1140+
/// *Rc::get_mut_unchecked(&mut y) = &s;
1141+
/// }
1142+
/// }
1143+
/// println!("{}", &*x); // Use-after-free
1144+
/// ```
11131145
#[inline]
11141146
#[unstable(feature = "get_mut_unchecked", issue = "63292")]
11151147
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {

library/alloc/src/sync.rs

+32
Original file line numberDiff line numberDiff line change
@@ -1649,6 +1649,38 @@ impl<T: ?Sized> Arc<T> {
16491649
/// }
16501650
/// assert_eq!(*x, "foo");
16511651
/// ```
1652+
/// Other `Arc` pointers to the same allocation must be to the same type.
1653+
/// ```ignore
1654+
/// #![feature(get_mut_unchecked)]
1655+
///
1656+
/// use std::sync::Arc;
1657+
///
1658+
/// let x: Arc<str> = Arc::from("Hello, world!");
1659+
/// let mut y: Arc<[u8]> = x.clone().into();
1660+
/// unsafe {
1661+
/// // this is Undefined Behavior, because x's inner type is str, not [u8]
1662+
/// Arc::get_mut_unchecked(&mut y).fill(0xff); // 0xff is invalid in UTF-8
1663+
/// }
1664+
/// println!("{}", &*x); // Invliad UTF-8 in a str
1665+
/// ```
1666+
/// Other `Arc` pointers to the same allocation must be to the exact same type, including lifetimes.
1667+
/// ```ignore
1668+
/// #![feature(get_mut_unchecked)]
1669+
///
1670+
/// use std::sync::Arc;
1671+
///
1672+
/// let x: Arc<&str> = Arc::new("Hello, world!");
1673+
/// {
1674+
/// let s = String::from("Oh, no!");
1675+
/// let mut y: Arc<&str> = x.clone().into();
1676+
/// unsafe {
1677+
/// // this is Undefined Behavior, because x's inner type
1678+
/// // is &'long str, not &'short str
1679+
/// *Arc::get_mut_unchecked(&mut y) = &s;
1680+
/// }
1681+
/// }
1682+
/// println!("{}", &*x); // Use-after-free
1683+
/// ```
16521684
#[inline]
16531685
#[unstable(feature = "get_mut_unchecked", issue = "63292")]
16541686
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {

0 commit comments

Comments
 (0)