Skip to content

Commit

Permalink
Added assert_unsafe_precondition! check for NonZeroXxx::from_mut_unch…
Browse files Browse the repository at this point in the history
…ecked
  • Loading branch information
SOF3 authored and dtolnay committed Jan 19, 2024
1 parent 4459be7 commit 3acb445
Showing 1 changed file with 20 additions and 13 deletions.
33 changes: 20 additions & 13 deletions library/core/src/num/nonzero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,18 +171,6 @@ macro_rules! nonzero_integer {
}
}

/// Converts a primitive mutable reference to a non-zero mutable reference
/// if the referenced integer is not zero.
#[unstable(feature = "nonzero_from_mut", issue = "none")]
#[must_use]
#[inline]
pub fn from_mut(n: &mut $Int) -> Option<&mut Self> {
// SAFETY: Self is repr(transparent), and the value is non-zero.
// As long as the returned reference is alive,
// the user cannot `*n = 0` directly.
(*n != 0).then(|| unsafe { &mut *(n as *mut $Int as *mut Self) })
}

/// Converts a primitive mutable reference to a non-zero mutable reference
/// without checking whether the referenced value is non-zero.
/// This results in undefined behavior if `*n` is zero.
Expand All @@ -194,7 +182,26 @@ macro_rules! nonzero_integer {
#[inline]
pub unsafe fn from_mut_unchecked(n: &mut $Int) -> &mut Self {
// SAFETY: Self is repr(transparent), and the value is assumed to be non-zero.
unsafe { &mut *(n as *mut $Int as *mut Self) }
unsafe {
let n_alias = &mut *n;
core::intrinsics::assert_unsafe_precondition!(
concat!(stringify!($Ty), "::from_mut_unchecked requires the argument to dereference as non-zero"),
(n_alias: &mut $Int) => *n_alias != 0
);
&mut *(n as *mut $Int as *mut Self)
}
}

/// Converts a primitive mutable reference to a non-zero mutable reference
/// if the referenced integer is not zero.
#[unstable(feature = "nonzero_from_mut", issue = "none")]
#[must_use]
#[inline]
pub fn from_mut(n: &mut $Int) -> Option<&mut Self> {
// SAFETY: Self is repr(transparent), and the value is non-zero.
// As long as the returned reference is alive,
// the user cannot `*n = 0` directly.
(*n != 0).then(|| unsafe { &mut *(n as *mut $Int as *mut Self) })
}

/// Returns the value as a primitive type.
Expand Down

0 comments on commit 3acb445

Please sign in to comment.