Skip to content
Closed
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4272f1b
get rid of nontrivial_structural_match lint and custom_eq const qualif
RalfJung Jan 27, 2024
32e4862
show indirect_structural_match and pointer_structural_match in future…
RalfJung Jan 27, 2024
0808691
update the tracking issue for structural match violations
RalfJung Jan 27, 2024
efbfb04
merge the accepted-structural-match tests into one
RalfJung Jan 28, 2024
c367983
Suggest name value cfg when only value is used for check-cfg
chenyukang Jan 28, 2024
0213c87
limit the names_possiblilities to less than 3
chenyukang Jan 30, 2024
ca243e7
add testcase for more than 3 cfg names
chenyukang Jan 30, 2024
d34b0fa
Add test for method on unbounded type parameter receiver
estebank Jan 26, 2024
20b1c2a
Account for unbounded type param receiver in suggestions
estebank Jan 26, 2024
9ccc770
fix rebase
estebank Jan 30, 2024
5c41409
Account for non-overlapping unmet trait bounds in suggestion
estebank Jan 30, 2024
0f55e1b
Simplify `impl_zeroable_primitive` macro.
reitermarkus Jan 31, 2024
a5042de
Make `NonZero` constructors generic.
reitermarkus Jan 22, 2024
3cc601a
Switch OwnedStore handle count to AtomicU32
GnomedDev Jan 31, 2024
a2a3c61
Already poison the `type_of` result of the anon const used in the `ty…
oli-obk Feb 1, 2024
009f970
inline a function that is only used in clippy
oli-obk Feb 1, 2024
0c4d089
Taint borrowck results without running any borrowck if the MIR body w…
oli-obk Feb 1, 2024
0f3976b
Continue to borrowck even if there were previous errors
oli-obk Feb 1, 2024
6fb1566
Simplify codegen diagnostic handling.
nnethercote Feb 2, 2024
4c038bd
Remove `SharedEmitterMessage::AbortIfErrors`.
nnethercote Feb 2, 2024
f4dce1e
Make `Emitter::emit_diagnostic` consuming.
nnethercote Feb 2, 2024
9adcd19
Rollup merge of #120396 - estebank:method-on-unbounded-type-param, r=…
matthiaskrgr Feb 5, 2024
e01ee4c
Rollup merge of #120423 - RalfJung:indirect-structural-match, r=petro…
matthiaskrgr Feb 5, 2024
0acfc79
Rollup merge of #120435 - chenyukang:yukang-fix-120427-cfg-name, r=Ur…
matthiaskrgr Feb 5, 2024
d4f90d3
Rollup merge of #120507 - estebank:issue-108428, r=davidtwco
matthiaskrgr Feb 5, 2024
5e7fb36
Rollup merge of #120521 - reitermarkus:generic-nonzero-constructors, …
matthiaskrgr Feb 5, 2024
a66a9f6
Rollup merge of #120527 - GnomedDev:atomicu32-handle, r=petrochenkov
matthiaskrgr Feb 5, 2024
749af61
Rollup merge of #120550 - oli-obk:track_errors8, r=estebank
matthiaskrgr Feb 5, 2024
bc0d618
Rollup merge of #120575 - nnethercote:simplify-codegen-diag-handling,…
matthiaskrgr Feb 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Make NonZero constructors generic.
  • Loading branch information
reitermarkus committed Jan 31, 2024
commit a5042de74199af0ff162b5581ad40e61de0ccd15
155 changes: 84 additions & 71 deletions library/core/src/num/nonzero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,90 @@ impl_zeroable_primitive!(isize);
#[rustc_diagnostic_item = "NonZero"]
pub struct NonZero<T: ZeroablePrimitive>(T);

impl<T> NonZero<T>
where
T: ZeroablePrimitive,
{
/// Creates a non-zero if the given value is not zero.
#[stable(feature = "nonzero", since = "1.28.0")]
#[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
#[rustc_allow_const_fn_unstable(const_refs_to_cell)]
#[must_use]
#[inline]
pub const fn new(n: T) -> Option<Self> {
// SAFETY: Memory layout optimization guarantees that `Option<NonZero<T>>` has
// the same layout and size as `T`, with `0` representing `None`.
unsafe { crate::mem::transmute_copy(&n) }
}

/// Creates a non-zero without checking whether the value is non-zero.
/// This results in undefined behaviour if the value is zero.
///
/// # Safety
///
/// The value must not be zero.
#[stable(feature = "nonzero", since = "1.28.0")]
#[rustc_const_stable(feature = "nonzero", since = "1.28.0")]
#[must_use]
#[inline]
pub const unsafe fn new_unchecked(n: T) -> Self {
match Self::new(n) {
Some(n) => n,
None => {
// SAFETY: The caller guarantees that `n` is non-zero, so this is unreachable.
unsafe {
crate::intrinsics::assert_unsafe_precondition!(
"NonZero::new_unchecked requires the argument to be non-zero",
() => false
);

crate::hint::unreachable_unchecked()
}
}
}
}

/// Converts a reference to a non-zero mutable reference
/// if the referenced value is not zero.
#[unstable(feature = "nonzero_from_mut", issue = "106290")]
#[must_use]
#[inline]
pub fn from_mut(n: &mut T) -> Option<&mut Self> {
// SAFETY: Memory layout optimization guarantees that `Option<NonZero<T>>` has
// the same layout and size as `T`, with `0` representing `None`.
let opt_n = unsafe { &mut *(n as *mut T as *mut Option<Self>) };

opt_n.as_mut()
}

/// Converts a mutable reference to a non-zero mutable reference
/// without checking whether the referenced value is non-zero.
/// This results in undefined behavior if the referenced value is zero.
///
/// # Safety
///
/// The referenced value must not be zero.
#[unstable(feature = "nonzero_from_mut", issue = "106290")]
#[must_use]
#[inline]
pub unsafe fn from_mut_unchecked(n: &mut T) -> &mut Self {
match Self::from_mut(n) {
Some(n) => n,
None => {
// SAFETY: The caller guarantees that `n` references a value that is non-zero, so this is unreachable.
unsafe {
crate::intrinsics::assert_unsafe_precondition!(
"NonZero::from_mut_unchecked requires the argument to dereference as non-zero",
() => false
);

crate::hint::unreachable_unchecked()
}
}
}
}
}

macro_rules! impl_nonzero_fmt {
( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
$(
Expand All @@ -100,7 +184,6 @@ macro_rules! impl_nonzero_fmt {
macro_rules! nonzero_integer {
(
#[$stability:meta]
#[$const_new_unchecked_stability:meta]
Self = $Ty:ident,
Primitive = $signedness:ident $Int:ident,
$(UnsignedNonZero = $UnsignedNonZero:ident,)?
Expand Down Expand Up @@ -143,74 +226,6 @@ macro_rules! nonzero_integer {
pub type $Ty = NonZero<$Int>;

impl $Ty {
/// Creates a non-zero without checking whether the value is non-zero.
/// This results in undefined behaviour if the value is zero.
///
/// # Safety
///
/// The value must not be zero.
#[$stability]
#[$const_new_unchecked_stability]
#[must_use]
#[inline]
pub const unsafe fn new_unchecked(n: $Int) -> Self {
crate::panic::debug_assert_nounwind!(
n != 0,
concat!(stringify!($Ty), "::new_unchecked requires a non-zero argument")
);
// SAFETY: this is guaranteed to be safe by the caller.
unsafe {
Self(n)
}
}

/// Creates a non-zero if the given value is not zero.
#[$stability]
#[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
#[must_use]
#[inline]
pub const fn new(n: $Int) -> Option<Self> {
if n != 0 {
// SAFETY: we just checked that there's no `0`
Some(unsafe { Self(n) })
} else {
None
}
}

/// 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.
///
/// # Safety
/// The referenced value must not be currently zero.
#[unstable(feature = "nonzero_from_mut", issue = "106290")]
#[must_use]
#[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 {
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 = "106290")]
#[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.
#[$stability]
#[inline]
Expand Down Expand Up @@ -724,7 +739,6 @@ macro_rules! nonzero_integer {
(Self = $Ty:ident, Primitive = unsigned $Int:ident $(,)?) => {
nonzero_integer! {
#[stable(feature = "nonzero", since = "1.28.0")]
#[rustc_const_stable(feature = "nonzero", since = "1.28.0")]
Self = $Ty,
Primitive = unsigned $Int,
UnsignedPrimitive = $Int,
Expand All @@ -735,7 +749,6 @@ macro_rules! nonzero_integer {
(Self = $Ty:ident, Primitive = signed $Int:ident, $($rest:tt)*) => {
nonzero_integer! {
#[stable(feature = "signed_nonzero", since = "1.34.0")]
#[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")]
Self = $Ty,
Primitive = signed $Int,
$($rest)*
Expand Down