fix(syntax): fix unsound use of NonZeroU32 (#4466)

`NonZeroU32::new_unchecked(idx as u32 + 1)` is unsound because if `idx == u32::MAX`, `idx + 1` wraps around back to zero. So unfortunately we need to use the checked version `NonZeroU32::new(idx as u32 + 1).unwrap()` to avoid UB in this edge case.
This commit is contained in:
overlookmotel 2024-07-26 00:14:44 +00:00
parent 81384f5059
commit 82ba2a073f
2 changed files with 9 additions and 9 deletions

View file

@ -13,9 +13,9 @@ pub struct ReferenceId(NonZeroU32);
impl Idx for ReferenceId {
#[allow(clippy::cast_possible_truncation)]
fn from_usize(idx: usize) -> Self {
// SAFETY: + 1 is always non-zero.
unsafe { Self(NonZeroU32::new_unchecked(idx as u32 + 1)) }
// NB: We can't use `NonZeroU32::new_unchecked(idx as u32 + 1)`
// because if `idx == u32::MAX`, `+ 1` would make it wrap around back to 0
Self(NonZeroU32::new(idx as u32 + 1).unwrap())
}
fn index(self) -> usize {

View file

@ -13,9 +13,9 @@ pub struct SymbolId(NonZeroU32);
impl Idx for SymbolId {
#[allow(clippy::cast_possible_truncation)]
fn from_usize(idx: usize) -> Self {
// SAFETY: + 1 is always non-zero.
unsafe { Self(NonZeroU32::new_unchecked(idx as u32 + 1)) }
// NB: We can't use `NonZeroU32::new_unchecked(idx as u32 + 1)`
// because if `idx == u32::MAX`, `+ 1` would make it wrap around back to 0
Self(NonZeroU32::new(idx as u32 + 1).unwrap())
}
fn index(self) -> usize {
@ -30,9 +30,9 @@ pub struct RedeclarationId(NonZeroU32);
impl Idx for RedeclarationId {
#[allow(clippy::cast_possible_truncation)]
fn from_usize(idx: usize) -> Self {
// SAFETY: + 1 is always non-zero.
unsafe { Self(NonZeroU32::new_unchecked(idx as u32 + 1)) }
// NB: We can't use `NonZeroU32::new_unchecked(idx as u32 + 1)`
// because if `idx == u32::MAX`, `+ 1` would make it wrap around back to 0
Self(NonZeroU32::new(idx as u32 + 1).unwrap())
}
fn index(self) -> usize {