1
Fork 0

Auto merge of #120165 - reitermarkus:nonzero-switch-alias-direction, r=dtolnay

Switch `NonZero` alias direction.

Step 4 mentioned in https://github.com/rust-lang/rust/pull/100428#pullrequestreview-1767139731.

Depends on https://github.com/rust-lang/rust/pull/120160.

r? `@dtolnay`
This commit is contained in:
bors 2024-01-29 08:52:13 +00:00
commit fb4bca04fa
22 changed files with 210 additions and 192 deletions

View file

@ -2140,46 +2140,50 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr_ty: Ty<'tcx>, expr_ty: Ty<'tcx>,
) -> bool { ) -> bool {
let tcx = self.tcx; let tcx = self.tcx;
let (adt, unwrap) = match expected.kind() { let (adt, substs, unwrap) = match expected.kind() {
// In case Option<NonZero*> is wanted, but * is provided, suggest calling new // In case Option<NonZero*> is wanted, but * is provided, suggest calling new
ty::Adt(adt, args) if tcx.is_diagnostic_item(sym::Option, adt.did()) => { ty::Adt(adt, substs) if tcx.is_diagnostic_item(sym::Option, adt.did()) => {
// Unwrap option let nonzero_type = substs.type_at(0); // Unwrap option type.
let ty::Adt(adt, _) = args.type_at(0).kind() else { let ty::Adt(adt, substs) = nonzero_type.kind() else {
return false; return false;
}; };
(adt, substs, "")
(adt, "")
} }
// In case NonZero* is wanted, but * is provided also add `.unwrap()` to satisfy types // In case `NonZero<*>` is wanted but `*` is provided, also add `.unwrap()` to satisfy types.
ty::Adt(adt, _) => (adt, ".unwrap()"), ty::Adt(adt, substs) => (adt, substs, ".unwrap()"),
_ => return false, _ => return false,
}; };
let map = [ if !self.tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
(sym::NonZeroU8, tcx.types.u8), return false;
(sym::NonZeroU16, tcx.types.u16), }
(sym::NonZeroU32, tcx.types.u32),
(sym::NonZeroU64, tcx.types.u64), // FIXME: This can be simplified once `NonZero<T>` is stable.
(sym::NonZeroU128, tcx.types.u128), let coercable_types = [
(sym::NonZeroI8, tcx.types.i8), ("NonZeroU8", tcx.types.u8),
(sym::NonZeroI16, tcx.types.i16), ("NonZeroU16", tcx.types.u16),
(sym::NonZeroI32, tcx.types.i32), ("NonZeroU32", tcx.types.u32),
(sym::NonZeroI64, tcx.types.i64), ("NonZeroU64", tcx.types.u64),
(sym::NonZeroI128, tcx.types.i128), ("NonZeroU128", tcx.types.u128),
("NonZeroI8", tcx.types.i8),
("NonZeroI16", tcx.types.i16),
("NonZeroI32", tcx.types.i32),
("NonZeroI64", tcx.types.i64),
("NonZeroI128", tcx.types.i128),
]; ];
let Some((s, _)) = map.iter().find(|&&(s, t)| { let int_type = substs.type_at(0);
self.tcx.is_diagnostic_item(s, adt.did()) && self.can_coerce(expr_ty, t)
let Some(nonzero_alias) = coercable_types.iter().find_map(|(nonzero_alias, t)| {
if *t == int_type && self.can_coerce(expr_ty, *t) { Some(nonzero_alias) } else { None }
}) else { }) else {
return false; return false;
}; };
let path = self.tcx.def_path_str(adt.non_enum_variant().def_id);
err.multipart_suggestion( err.multipart_suggestion(
format!("consider calling `{s}::new`"), format!("consider calling `{nonzero_alias}::new`"),
vec![ vec![
(expr.span.shrink_to_lo(), format!("{path}::new(")), (expr.span.shrink_to_lo(), format!("{nonzero_alias}::new(")),
(expr.span.shrink_to_hi(), format!("){unwrap}")), (expr.span.shrink_to_hi(), format!("){unwrap}")),
], ],
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,

View file

@ -246,17 +246,7 @@ symbols! {
MutexGuard, MutexGuard,
N, N,
NonNull, NonNull,
NonZeroI128, NonZero,
NonZeroI16,
NonZeroI32,
NonZeroI64,
NonZeroI8,
NonZeroU128,
NonZeroU16,
NonZeroU32,
NonZeroU64,
NonZeroU8,
NonZeroUsize,
None, None,
Normal, Normal,
Ok, Ok,

View file

@ -61,7 +61,15 @@ pub use dec2flt::ParseFloatError;
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub use error::ParseIntError; pub use error::ParseIntError;
pub(crate) use nonzero::NonZero; #[unstable(
feature = "nonzero_internals",
reason = "implementation detail which may disappear or be replaced at any time",
issue = "none"
)]
pub use nonzero::ZeroablePrimitive;
#[unstable(feature = "generic_nonzero", issue = "120257")]
pub use nonzero::NonZero;
#[stable(feature = "nonzero", since = "1.28.0")] #[stable(feature = "nonzero", since = "1.28.0")]
pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}; pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};

View file

@ -3,6 +3,8 @@
use crate::cmp::Ordering; use crate::cmp::Ordering;
use crate::fmt; use crate::fmt;
use crate::hash::{Hash, Hasher}; use crate::hash::{Hash, Hasher};
#[cfg(bootstrap)]
use crate::marker::StructuralEq;
use crate::marker::StructuralPartialEq; use crate::marker::StructuralPartialEq;
use crate::ops::{BitOr, BitOrAssign, Div, Neg, Rem}; use crate::ops::{BitOr, BitOrAssign, Div, Neg, Rem};
use crate::str::FromStr; use crate::str::FromStr;
@ -30,9 +32,7 @@ mod private {
issue = "none" issue = "none"
)] )]
#[const_trait] #[const_trait]
pub trait ZeroablePrimitive: Sized + Copy + private::Sealed { pub trait ZeroablePrimitive: Sized + Copy + private::Sealed {}
type NonZero;
}
macro_rules! impl_zeroable_primitive { macro_rules! impl_zeroable_primitive {
($NonZero:ident ( $primitive:ty )) => { ($NonZero:ident ( $primitive:ty )) => {
@ -48,9 +48,7 @@ macro_rules! impl_zeroable_primitive {
reason = "implementation detail which may disappear or be replaced at any time", reason = "implementation detail which may disappear or be replaced at any time",
issue = "none" issue = "none"
)] )]
impl const ZeroablePrimitive for $primitive { impl const ZeroablePrimitive for $primitive {}
type NonZero = $NonZero;
}
}; };
} }
@ -67,12 +65,23 @@ impl_zeroable_primitive!(NonZeroI64(i64));
impl_zeroable_primitive!(NonZeroI128(i128)); impl_zeroable_primitive!(NonZeroI128(i128));
impl_zeroable_primitive!(NonZeroIsize(isize)); impl_zeroable_primitive!(NonZeroIsize(isize));
#[unstable( /// A value that is known not to equal zero.
feature = "nonzero_internals", ///
reason = "implementation detail which may disappear or be replaced at any time", /// This enables some memory layout optimization.
issue = "none" /// For example, `Option<NonZero<u32>>` is the same size as `u32`:
)] ///
pub(crate) type NonZero<T> = <T as ZeroablePrimitive>::NonZero; /// ```
/// #![feature(generic_nonzero)]
/// use core::mem::size_of;
///
/// assert_eq!(size_of::<Option<core::num::NonZero<u32>>>(), size_of::<u32>());
/// ```
#[unstable(feature = "generic_nonzero", issue = "120257")]
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
#[rustc_nonnull_optimization_guaranteed]
#[rustc_diagnostic_item = "NonZero"]
pub struct NonZero<T: ZeroablePrimitive>(T);
macro_rules! impl_nonzero_fmt { macro_rules! impl_nonzero_fmt {
( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => { ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
@ -131,12 +140,7 @@ macro_rules! nonzero_integer {
/// ///
/// [null pointer optimization]: crate::option#representation /// [null pointer optimization]: crate::option#representation
#[$stability] #[$stability]
#[derive(Copy, Eq)] pub type $Ty = NonZero<$Int>;
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
#[rustc_nonnull_optimization_guaranteed]
#[rustc_diagnostic_item = stringify!($Ty)]
pub struct $Ty($Int);
impl $Ty { impl $Ty {
/// Creates a non-zero without checking whether the value is non-zero. /// Creates a non-zero without checking whether the value is non-zero.
@ -543,6 +547,9 @@ macro_rules! nonzero_integer {
} }
} }
#[$stability]
impl Copy for $Ty {}
#[$stability] #[$stability]
impl PartialEq for $Ty { impl PartialEq for $Ty {
#[inline] #[inline]
@ -559,6 +566,13 @@ macro_rules! nonzero_integer {
#[unstable(feature = "structural_match", issue = "31434")] #[unstable(feature = "structural_match", issue = "31434")]
impl StructuralPartialEq for $Ty {} impl StructuralPartialEq for $Ty {}
#[$stability]
impl Eq for $Ty {}
#[unstable(feature = "structural_match", issue = "31434")]
#[cfg(bootstrap)]
impl StructuralEq for $Ty {}
#[$stability] #[$stability]
impl PartialOrd for $Ty { impl PartialOrd for $Ty {
#[inline] #[inline]

View file

@ -323,6 +323,7 @@
#![feature(float_gamma)] #![feature(float_gamma)]
#![feature(float_minimum_maximum)] #![feature(float_minimum_maximum)]
#![feature(float_next_up_down)] #![feature(float_next_up_down)]
#![feature(generic_nonzero)]
#![feature(hasher_prefixfree_extras)] #![feature(hasher_prefixfree_extras)]
#![feature(hashmap_internals)] #![feature(hashmap_internals)]
#![feature(hint_assert_unchecked)] #![feature(hint_assert_unchecked)]

View file

@ -16,6 +16,16 @@ pub use core::num::Wrapping;
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError}; pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError};
#[unstable(
feature = "nonzero_internals",
reason = "implementation detail which may disappear or be replaced at any time",
issue = "none"
)]
pub use core::num::ZeroablePrimitive;
#[unstable(feature = "generic_nonzero", issue = "120257")]
pub use core::num::NonZero;
#[stable(feature = "signed_nonzero", since = "1.34.0")] #[stable(feature = "signed_nonzero", since = "1.34.0")]
pub use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize}; pub use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
#[stable(feature = "nonzero", since = "1.28.0")] #[stable(feature = "nonzero", since = "1.28.0")]

View file

@ -41,40 +41,7 @@
</Expand> </Expand>
</Type> </Type>
<Type Name="core::num::nonzero::NonZeroI8"> <Type Name="core::num::nonzero::NonZero&lt;*&gt;">
<DisplayString>{__0}</DisplayString>
</Type>
<Type Name="core::num::nonzero::NonZeroI16">
<DisplayString>{__0}</DisplayString>
</Type>
<Type Name="core::num::nonzero::NonZeroI32">
<DisplayString>{__0}</DisplayString>
</Type>
<Type Name="core::num::nonzero::NonZeroI64">
<DisplayString>{__0}</DisplayString>
</Type>
<Type Name="core::num::nonzero::NonZeroI128">
<DisplayString>{__0}</DisplayString>
</Type>
<Type Name="core::num::nonzero::NonZeroIsize">
<DisplayString>{__0}</DisplayString>
</Type>
<Type Name="core::num::nonzero::NonZeroU8">
<DisplayString>{__0}</DisplayString>
</Type>
<Type Name="core::num::nonzero::NonZeroU16">
<DisplayString>{__0}</DisplayString>
</Type>
<Type Name="core::num::nonzero::NonZeroU32">
<DisplayString>{__0}</DisplayString>
</Type>
<Type Name="core::num::nonzero::NonZeroU64">
<DisplayString>{__0}</DisplayString>
</Type>
<Type Name="core::num::nonzero::NonZeroU128">
<DisplayString>{__0}</DisplayString>
</Type>
<Type Name="core::num::nonzero::NonZeroUsize">
<DisplayString>{__0}</DisplayString> <DisplayString>{__0}</DisplayString>
</Type> </Type>

View file

@ -1,11 +1,11 @@
use super::ARITHMETIC_SIDE_EFFECTS; use super::ARITHMETIC_SIDE_EFFECTS;
use clippy_utils::consts::{constant, constant_simple, Constant}; use clippy_utils::consts::{constant, constant_simple, Constant};
use clippy_utils::diagnostics::span_lint; use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::type_diagnostic_name; use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{expr_or_init, is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary}; use clippy_utils::{expr_or_init, is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary};
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Ty; use rustc_middle::ty::{self, Ty};
use rustc_session::impl_lint_pass; use rustc_session::impl_lint_pass;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
@ -88,37 +88,44 @@ impl ArithmeticSideEffects {
} }
/// Verifies built-in types that have specific allowed operations /// Verifies built-in types that have specific allowed operations
fn has_specific_allowed_type_and_operation( fn has_specific_allowed_type_and_operation<'tcx>(
cx: &LateContext<'_>, cx: &LateContext<'tcx>,
lhs_ty: Ty<'_>, lhs_ty: Ty<'tcx>,
op: &Spanned<hir::BinOpKind>, op: &Spanned<hir::BinOpKind>,
rhs_ty: Ty<'_>, rhs_ty: Ty<'tcx>,
) -> bool { ) -> bool {
let is_div_or_rem = matches!(op.node, hir::BinOpKind::Div | hir::BinOpKind::Rem); let is_div_or_rem = matches!(op.node, hir::BinOpKind::Div | hir::BinOpKind::Rem);
let is_non_zero_u = |symbol: Option<Symbol>| { let is_non_zero_u = |cx: &LateContext<'tcx>, ty: Ty<'tcx>| {
matches!( let tcx = cx.tcx;
symbol,
Some( let ty::Adt(adt, substs) = ty.kind() else { return false };
sym::NonZeroU128
| sym::NonZeroU16 if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
| sym::NonZeroU32 return false;
| sym::NonZeroU64 };
| sym::NonZeroU8
| sym::NonZeroUsize let int_type = substs.type_at(0);
) let unsigned_int_types = [
) tcx.types.u8,
tcx.types.u16,
tcx.types.u32,
tcx.types.u64,
tcx.types.u128,
tcx.types.usize,
];
unsigned_int_types.contains(&int_type)
}; };
let is_sat_or_wrap = |ty: Ty<'_>| { let is_sat_or_wrap = |ty: Ty<'_>| {
let is_sat = type_diagnostic_name(cx, ty) == Some(sym::Saturating); is_type_diagnostic_item(cx, ty, sym::Saturating) || is_type_diagnostic_item(cx, ty, sym::Wrapping)
let is_wrap = type_diagnostic_name(cx, ty) == Some(sym::Wrapping);
is_sat || is_wrap
}; };
// If the RHS is NonZeroU*, then division or module by zero will never occur // If the RHS is `NonZero<u*>`, then division or module by zero will never occur.
if is_non_zero_u(type_diagnostic_name(cx, rhs_ty)) && is_div_or_rem { if is_non_zero_u(cx, rhs_ty) && is_div_or_rem {
return true; return true;
} }
// `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module
// `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module.
if is_sat_or_wrap(lhs_ty) { if is_sat_or_wrap(lhs_ty) {
return !is_div_or_rem; return !is_div_or_rem;
} }

View file

@ -16,40 +16,55 @@ pub(super) fn check<'tcx>(
to_ty: Ty<'tcx>, to_ty: Ty<'tcx>,
arg: &'tcx Expr<'_>, arg: &'tcx Expr<'_>,
) -> bool { ) -> bool {
let (ty::Int(_) | ty::Uint(_), Some(to_ty_adt)) = (&from_ty.kind(), to_ty.ty_adt_def()) else { let tcx = cx.tcx;
return false;
}; let (ty::Int(_) | ty::Uint(_), ty::Adt(adt, substs)) = (&from_ty.kind(), to_ty.kind()) else {
let Some(to_type_sym) = cx.tcx.get_diagnostic_name(to_ty_adt.did()) else {
return false; return false;
}; };
if !matches!( if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
to_type_sym,
sym::NonZeroU8
| sym::NonZeroU16
| sym::NonZeroU32
| sym::NonZeroU64
| sym::NonZeroU128
| sym::NonZeroI8
| sym::NonZeroI16
| sym::NonZeroI32
| sym::NonZeroI64
| sym::NonZeroI128
) {
return false; return false;
} };
// FIXME: This can be simplified once `NonZero<T>` is stable.
let coercable_types = [
("NonZeroU8", tcx.types.u8),
("NonZeroU16", tcx.types.u16),
("NonZeroU32", tcx.types.u32),
("NonZeroU64", tcx.types.u64),
("NonZeroU128", tcx.types.u128),
("NonZeroUsize", tcx.types.usize),
("NonZeroI8", tcx.types.i8),
("NonZeroI16", tcx.types.i16),
("NonZeroI32", tcx.types.i32),
("NonZeroI64", tcx.types.i64),
("NonZeroI128", tcx.types.i128),
("NonZeroIsize", tcx.types.isize),
];
let int_type = substs.type_at(0);
let Some(nonzero_alias) = coercable_types.iter().find_map(|(nonzero_alias, t)| {
if *t == int_type && *t == from_ty {
Some(nonzero_alias)
} else {
None
}
}) else {
return false;
};
span_lint_and_then( span_lint_and_then(
cx, cx,
TRANSMUTE_INT_TO_NON_ZERO, TRANSMUTE_INT_TO_NON_ZERO,
e.span, e.span,
&format!("transmute from a `{from_ty}` to a `{to_type_sym}`"), &format!("transmute from a `{from_ty}` to a `{nonzero_alias}`"),
|diag| { |diag| {
let arg = sugg::Sugg::hir(cx, arg, ".."); let arg = sugg::Sugg::hir(cx, arg, "..");
diag.span_suggestion( diag.span_suggestion(
e.span, e.span,
"consider using", "consider using",
format!("{to_type_sym}::{}({arg})", sym::new_unchecked), format!("{nonzero_alias}::{}({arg})", sym::new_unchecked),
Applicability::Unspecified, Applicability::Unspecified,
); );
}, },

View file

@ -46,12 +46,12 @@
// cdb-check: [+0x000] __0 : 0x2a [Type: unsigned int] // cdb-check: [+0x000] __0 : 0x2a [Type: unsigned int]
// cdb-command: dx niche128_some // cdb-command: dx niche128_some
// cdb-check: niche128_some : Some [Type: enum2$<core::option::Option<core::num::nonzero::NonZeroI128> >] // cdb-check: niche128_some : Some [Type: enum2$<core::option::Option<core::num::nonzero::NonZero<i128> > >]
// Note: we can't actually read the value of the field because CDB cannot handle 128 bit integers. // Note: we can't actually read the value of the field because CDB cannot handle 128 bit integers.
// cdb-check: [+0x000] __0 [...] [Type: core::num::nonzero::NonZeroI128] // cdb-check: [+0x000] __0 [...] [Type: core::num::nonzero::NonZero<i128>]
// cdb-command: dx niche128_none // cdb-command: dx niche128_none
// cdb-check: niche128_none : None [Type: enum2$<core::option::Option<core::num::nonzero::NonZeroI128> >] // cdb-check: niche128_none : None [Type: enum2$<core::option::Option<core::num::nonzero::NonZero<i128> > >]
// cdb-command: dx wrapping_niche128_untagged // cdb-command: dx wrapping_niche128_untagged
// cdb-check: wrapping_niche128_untagged : X [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>] // cdb-check: wrapping_niche128_untagged : X [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
@ -84,7 +84,7 @@
// cdb-command: dx niche_w_fields_2_some,d // cdb-command: dx niche_w_fields_2_some,d
// cdb-check: niche_w_fields_2_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields2>] // cdb-check: niche_w_fields_2_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields2>]
// cdb-check: [+0x[...]] __0 : 800 [Type: core::num::nonzero::NonZeroU32] // cdb-check: [+0x[...]] __0 : 800 [Type: core::num::nonzero::NonZero<u32>]
// cdb-check: [+0x[...]] __1 : 900 [Type: unsigned __int64] // cdb-check: [+0x[...]] __1 : 900 [Type: unsigned __int64]
// cdb-command: dx niche_w_fields_2_none,d // cdb-command: dx niche_w_fields_2_none,d

View file

@ -3,59 +3,59 @@
// min-gdb-version: 8.1 // min-gdb-version: 8.1
// ignore-windows-gnu // emit_debug_gdb_scripts is disabled on Windows // ignore-windows-gnu // emit_debug_gdb_scripts is disabled on Windows
// Tests the visualizations for `NonZero{I,U}{8,16,32,64,128,size}`, `Wrapping<T>` and // Tests the visualizations for `NonZero<T>`, `Wrapping<T>` and
// `Atomic{Bool,I8,I16,I32,I64,Isize,U8,U16,U32,U64,Usize}` located in `libcore.natvis`. // `Atomic{Bool,I8,I16,I32,I64,Isize,U8,U16,U32,U64,Usize}` located in `libcore.natvis`.
// === CDB TESTS ================================================================================== // === CDB TESTS ==================================================================================
// cdb-command: g // cdb-command: g
// cdb-command: dx nz_i8 // cdb-command: dx nz_i8
// cdb-check:nz_i8 : 11 [Type: core::num::nonzero::NonZeroI8] // cdb-check:nz_i8 : 11 [Type: core::num::nonzero::NonZero<i8>]
// cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZeroI8] // cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZero<i8>]
// cdb-command: dx nz_i16 // cdb-command: dx nz_i16
// cdb-check:nz_i16 : 22 [Type: core::num::nonzero::NonZeroI16] // cdb-check:nz_i16 : 22 [Type: core::num::nonzero::NonZero<i16>]
// cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZeroI16] // cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZero<i16>]
// cdb-command: dx nz_i32 // cdb-command: dx nz_i32
// cdb-check:nz_i32 : 33 [Type: core::num::nonzero::NonZeroI32] // cdb-check:nz_i32 : 33 [Type: core::num::nonzero::NonZero<i32>]
// cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZeroI32] // cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZero<i32>]
// cdb-command: dx nz_i64 // cdb-command: dx nz_i64
// cdb-check:nz_i64 : 44 [Type: core::num::nonzero::NonZeroI64] // cdb-check:nz_i64 : 44 [Type: core::num::nonzero::NonZero<i64>]
// cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZeroI64] // cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZero<i64>]
// 128-bit integers don't seem to work in CDB // 128-bit integers don't seem to work in CDB
// cdb-command: dx nz_i128 // cdb-command: dx nz_i128
// cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZeroI128] // cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZero<i128>]
// cdb-command: dx nz_isize // cdb-command: dx nz_isize
// cdb-check:nz_isize : 66 [Type: core::num::nonzero::NonZeroIsize] // cdb-check:nz_isize : 66 [Type: core::num::nonzero::NonZero<isize>]
// cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZeroIsize] // cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZero<isize>]
// cdb-command: dx nz_u8 // cdb-command: dx nz_u8
// cdb-check:nz_u8 : 0x4d [Type: core::num::nonzero::NonZeroU8] // cdb-check:nz_u8 : 0x4d [Type: core::num::nonzero::NonZero<u8>]
// cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZeroU8] // cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZero<u8>]
// cdb-command: dx nz_u16 // cdb-command: dx nz_u16
// cdb-check:nz_u16 : 0x58 [Type: core::num::nonzero::NonZeroU16] // cdb-check:nz_u16 : 0x58 [Type: core::num::nonzero::NonZero<u16>]
// cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZeroU16] // cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZero<u16>]
// cdb-command: dx nz_u32 // cdb-command: dx nz_u32
// cdb-check:nz_u32 : 0x63 [Type: core::num::nonzero::NonZeroU32] // cdb-check:nz_u32 : 0x63 [Type: core::num::nonzero::NonZero<u32>]
// cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZeroU32] // cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZero<u32>]
// cdb-command: dx nz_u64 // cdb-command: dx nz_u64
// cdb-check:nz_u64 : 0x64 [Type: core::num::nonzero::NonZeroU64] // cdb-check:nz_u64 : 0x64 [Type: core::num::nonzero::NonZero<u64>]
// cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZeroU64] // cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZero<u64>]
// 128-bit integers don't seem to work in CDB // 128-bit integers don't seem to work in CDB
// cdb-command: dx nz_u128 // cdb-command: dx nz_u128
// cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZeroU128] // cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZero<u128>]
// cdb-command: dx nz_usize // cdb-command: dx nz_usize
// cdb-check:nz_usize : 0x7a [Type: core::num::nonzero::NonZeroUsize] // cdb-check:nz_usize : 0x7a [Type: core::num::nonzero::NonZero<usize>]
// cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZeroUsize] // cdb-check: [<Raw View>] [Type: core::num::nonzero::NonZero<usize>]
// cdb-command: dx w_i8 // cdb-command: dx w_i8
// cdb-check:w_i8 : 10 [Type: core::num::wrapping::Wrapping<i8>] // cdb-check:w_i8 : 10 [Type: core::num::wrapping::Wrapping<i8>]

View file

@ -4,7 +4,7 @@
fn adt_transmutes() -> () { fn adt_transmutes() -> () {
let mut _0: (); let mut _0: ();
let _1: u8; let _1: u8;
let mut _2: std::option::Option<std::num::NonZeroU8>; let mut _2: std::option::Option<std::num::NonZero<u8>>;
let mut _4: std::num::Wrapping<i16>; let mut _4: std::num::Wrapping<i16>;
let mut _6: std::num::Wrapping<i16>; let mut _6: std::num::Wrapping<i16>;
let mut _8: Union32; let mut _8: Union32;
@ -37,7 +37,7 @@
bb0: { bb0: {
StorageLive(_1); StorageLive(_1);
StorageLive(_2); StorageLive(_2);
_2 = Option::<NonZeroU8>::Some(const _); _2 = Option::<NonZero<u8>>::Some(const _);
_1 = move _2 as u8 (Transmute); _1 = move _2 as u8 (Transmute);
StorageDead(_2); StorageDead(_2);
StorageLive(_3); StorageLive(_3);

View file

@ -232,7 +232,7 @@ error: layout_of(MultipleAlignments) = Layout {
LL | enum MultipleAlignments { LL | enum MultipleAlignments {
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
error: layout_of(Result<[u32; 0], Packed<NonZeroU16>>) = Layout { error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
size: Size(4 bytes), size: Size(4 bytes),
align: AbiAndPrefAlign { align: AbiAndPrefAlign {
abi: Align(4 bytes), abi: Align(4 bytes),

View file

@ -436,7 +436,7 @@ mod hidden_niche {
fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>; fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
//~^ WARN redeclared with a different signature //~^ WARN redeclared with a different signature
//~| WARN block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe //~| WARN block uses type `Option<UnsafeCell<NonZero<usize>>>`, which is not FFI-safe
} }
} }
} }

View file

@ -8,7 +8,7 @@ LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
= note: enum has no representation hint = note: enum has no representation hint
= note: `#[warn(improper_ctypes)]` on by default = note: `#[warn(improper_ctypes)]` on by default
warning: `extern` block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe warning: `extern` block uses type `Option<UnsafeCell<NonZero<usize>>>`, which is not FFI-safe
--> $DIR/clashing-extern-fn.rs:437:46 --> $DIR/clashing-extern-fn.rs:437:46
| |
LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>; LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
@ -163,7 +163,7 @@ LL | fn non_zero_usize() -> core::num::NonZeroUsize;
LL | fn non_zero_usize() -> usize; LL | fn non_zero_usize() -> usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
| |
= note: expected `unsafe extern "C" fn() -> NonZeroUsize` = note: expected `unsafe extern "C" fn() -> NonZero<usize>`
found `unsafe extern "C" fn() -> usize` found `unsafe extern "C" fn() -> usize`
warning: `non_null_ptr` redeclared with a different signature warning: `non_null_ptr` redeclared with a different signature
@ -224,7 +224,7 @@ LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
| |
= note: expected `unsafe extern "C" fn() -> usize` = note: expected `unsafe extern "C" fn() -> usize`
found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZeroUsize>>` found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZero<usize>>>`
warning: 19 warnings emitted warning: 19 warnings emitted

View file

@ -316,7 +316,7 @@ LL | let _val: NonNull<i32> = mem::uninitialized();
= note: `std::ptr::NonNull<i32>` must be non-null = note: `std::ptr::NonNull<i32>` must be non-null
= note: raw pointers must be initialized = note: raw pointers must be initialized
error: the type `(NonZeroU32, i32)` does not permit zero-initialization error: the type `(NonZero<u32>, i32)` does not permit zero-initialization
--> $DIR/invalid_value.rs:95:39 --> $DIR/invalid_value.rs:95:39
| |
LL | let _val: (NonZeroU32, i32) = mem::zeroed(); LL | let _val: (NonZeroU32, i32) = mem::zeroed();
@ -325,9 +325,9 @@ LL | let _val: (NonZeroU32, i32) = mem::zeroed();
| this code causes undefined behavior when executed | this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
= note: `std::num::NonZeroU32` must be non-null = note: `std::num::NonZero<u32>` must be non-null
error: the type `(NonZeroU32, i32)` does not permit being left uninitialized error: the type `(NonZero<u32>, i32)` does not permit being left uninitialized
--> $DIR/invalid_value.rs:96:39 --> $DIR/invalid_value.rs:96:39
| |
LL | let _val: (NonZeroU32, i32) = mem::uninitialized(); LL | let _val: (NonZeroU32, i32) = mem::uninitialized();
@ -336,7 +336,7 @@ LL | let _val: (NonZeroU32, i32) = mem::uninitialized();
| this code causes undefined behavior when executed | this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
= note: `std::num::NonZeroU32` must be non-null = note: `std::num::NonZero<u32>` must be non-null
= note: integers must be initialized = note: integers must be initialized
error: the type `*const dyn Send` does not permit zero-initialization error: the type `*const dyn Send` does not permit zero-initialization
@ -417,7 +417,7 @@ LL | let _val: OneFruitNonZero = mem::zeroed();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
= note: `OneFruitNonZero` must be non-null = note: `OneFruitNonZero` must be non-null
note: because `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant) note: because `std::num::NonZero<u32>` must be non-null (in this field of the only potentially inhabited enum variant)
--> $DIR/invalid_value.rs:39:12 --> $DIR/invalid_value.rs:39:12
| |
LL | Banana(NonZeroU32), LL | Banana(NonZeroU32),
@ -433,7 +433,7 @@ LL | let _val: OneFruitNonZero = mem::uninitialized();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
= note: `OneFruitNonZero` must be non-null = note: `OneFruitNonZero` must be non-null
note: because `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant) note: because `std::num::NonZero<u32>` must be non-null (in this field of the only potentially inhabited enum variant)
--> $DIR/invalid_value.rs:39:12 --> $DIR/invalid_value.rs:39:12
| |
LL | Banana(NonZeroU32), LL | Banana(NonZeroU32),
@ -603,7 +603,7 @@ LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize));
| |
= note: references must be non-null = note: references must be non-null
error: the type `NonZeroU32` does not permit zero-initialization error: the type `NonZero<u32>` does not permit zero-initialization
--> $DIR/invalid_value.rs:154:32 --> $DIR/invalid_value.rs:154:32
| |
LL | let _val: NonZeroU32 = mem::transmute(0); LL | let _val: NonZeroU32 = mem::transmute(0);
@ -612,7 +612,7 @@ LL | let _val: NonZeroU32 = mem::transmute(0);
| this code causes undefined behavior when executed | this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
| |
= note: `std::num::NonZeroU32` must be non-null = note: `std::num::NonZero<u32>` must be non-null
error: the type `NonNull<i32>` does not permit zero-initialization error: the type `NonNull<i32>` does not permit zero-initialization
--> $DIR/invalid_value.rs:157:34 --> $DIR/invalid_value.rs:157:34

View file

@ -61,7 +61,7 @@ LL | fn nonzero_i128(x: Option<num::NonZeroI128>);
| |
= note: 128-bit integers don't currently have a known stable ABI = note: 128-bit integers don't currently have a known stable ABI
error: `extern` block uses type `Option<TransparentUnion<NonZeroU8>>`, which is not FFI-safe error: `extern` block uses type `Option<TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
--> $DIR/lint-ctypes-enum.rs:86:28 --> $DIR/lint-ctypes-enum.rs:86:28
| |
LL | fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>); LL | fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
@ -70,7 +70,7 @@ LL | fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Option<Rust<NonZeroU8>>`, which is not FFI-safe error: `extern` block uses type `Option<Rust<NonZero<u8>>>`, which is not FFI-safe
--> $DIR/lint-ctypes-enum.rs:88:20 --> $DIR/lint-ctypes-enum.rs:88:20
| |
LL | fn repr_rust(x: Option<Rust<num::NonZeroU8>>); LL | fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
@ -79,7 +79,7 @@ LL | fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Result<(), NonZeroI32>`, which is not FFI-safe error: `extern` block uses type `Result<(), NonZero<i32>>`, which is not FFI-safe
--> $DIR/lint-ctypes-enum.rs:89:20 --> $DIR/lint-ctypes-enum.rs:89:20
| |
LL | fn no_result(x: Result<(), num::NonZeroI32>); LL | fn no_result(x: Result<(), num::NonZeroI32>);

View file

@ -2,10 +2,12 @@ error[E0308]: mismatched types
--> $DIR/non_zero_assigned_something.rs:2:35 --> $DIR/non_zero_assigned_something.rs:2:35
| |
LL | let _: std::num::NonZeroU64 = 1; LL | let _: std::num::NonZeroU64 = 1;
| -------------------- ^ expected `NonZeroU64`, found integer | -------------------- ^ expected `NonZero<u64>`, found integer
| | | |
| expected due to this | expected due to this
| |
= note: expected struct `NonZero<u64>`
found type `{integer}`
help: consider calling `NonZeroU64::new` help: consider calling `NonZeroU64::new`
| |
LL | let _: std::num::NonZeroU64 = NonZeroU64::new(1).unwrap(); LL | let _: std::num::NonZeroU64 = NonZeroU64::new(1).unwrap();
@ -15,11 +17,11 @@ error[E0308]: mismatched types
--> $DIR/non_zero_assigned_something.rs:6:43 --> $DIR/non_zero_assigned_something.rs:6:43
| |
LL | let _: Option<std::num::NonZeroU64> = 1; LL | let _: Option<std::num::NonZeroU64> = 1;
| ---------------------------- ^ expected `Option<NonZeroU64>`, found integer | ---------------------------- ^ expected `Option<NonZero<u64>>`, found integer
| | | |
| expected due to this | expected due to this
| |
= note: expected enum `Option<NonZeroU64>` = note: expected enum `Option<NonZero<u64>>`
found type `{integer}` found type `{integer}`
help: consider calling `NonZeroU64::new` help: consider calling `NonZeroU64::new`
| |

View file

@ -124,7 +124,7 @@ LL | x / 100.0
= help: the trait `Div<{float}>` is not implemented for `u8` = help: the trait `Div<{float}>` is not implemented for `u8`
= help: the following other types implement trait `Div<Rhs>`: = help: the following other types implement trait `Div<Rhs>`:
<u8 as Div> <u8 as Div>
<u8 as Div<NonZeroU8>> <u8 as Div<NonZero<u8>>>
<u8 as Div<&u8>> <u8 as Div<&u8>>
<&'a u8 as Div<u8>> <&'a u8 as Div<u8>>
<&u8 as Div<&u8>> <&u8 as Div<&u8>>

View file

@ -14,17 +14,17 @@ print-type-size field `.pre`: 1 bytes
print-type-size field `.post`: 2 bytes print-type-size field `.post`: 2 bytes
print-type-size field `.val`: 4 bytes print-type-size field `.val`: 4 bytes
print-type-size variant `None`: 0 bytes print-type-size variant `None`: 0 bytes
print-type-size type: `MyOption<Union1<std::num::NonZeroU32>>`: 8 bytes, alignment: 4 bytes print-type-size type: `MyOption<Union1<std::num::NonZero<u32>>>`: 8 bytes, alignment: 4 bytes
print-type-size discriminant: 4 bytes print-type-size discriminant: 4 bytes
print-type-size variant `Some`: 4 bytes print-type-size variant `Some`: 4 bytes
print-type-size field `.0`: 4 bytes print-type-size field `.0`: 4 bytes
print-type-size variant `None`: 0 bytes print-type-size variant `None`: 0 bytes
print-type-size type: `MyOption<Union2<std::num::NonZeroU32, std::num::NonZeroU32>>`: 8 bytes, alignment: 4 bytes print-type-size type: `MyOption<Union2<std::num::NonZero<u32>, std::num::NonZero<u32>>>`: 8 bytes, alignment: 4 bytes
print-type-size discriminant: 4 bytes print-type-size discriminant: 4 bytes
print-type-size variant `Some`: 4 bytes print-type-size variant `Some`: 4 bytes
print-type-size field `.0`: 4 bytes print-type-size field `.0`: 4 bytes
print-type-size variant `None`: 0 bytes print-type-size variant `None`: 0 bytes
print-type-size type: `MyOption<Union2<std::num::NonZeroU32, u32>>`: 8 bytes, alignment: 4 bytes print-type-size type: `MyOption<Union2<std::num::NonZero<u32>, u32>>`: 8 bytes, alignment: 4 bytes
print-type-size discriminant: 4 bytes print-type-size discriminant: 4 bytes
print-type-size variant `Some`: 4 bytes print-type-size variant `Some`: 4 bytes
print-type-size field `.0`: 4 bytes print-type-size field `.0`: 4 bytes
@ -53,22 +53,22 @@ print-type-size type: `MyOption<char>`: 4 bytes, alignment: 4 bytes
print-type-size variant `Some`: 4 bytes print-type-size variant `Some`: 4 bytes
print-type-size field `.0`: 4 bytes print-type-size field `.0`: 4 bytes
print-type-size variant `None`: 0 bytes print-type-size variant `None`: 0 bytes
print-type-size type: `MyOption<std::num::NonZeroU32>`: 4 bytes, alignment: 4 bytes print-type-size type: `MyOption<std::num::NonZero<u32>>`: 4 bytes, alignment: 4 bytes
print-type-size variant `Some`: 4 bytes print-type-size variant `Some`: 4 bytes
print-type-size field `.0`: 4 bytes print-type-size field `.0`: 4 bytes
print-type-size variant `None`: 0 bytes print-type-size variant `None`: 0 bytes
print-type-size type: `Union1<std::num::NonZeroU32>`: 4 bytes, alignment: 4 bytes print-type-size type: `Union1<std::num::NonZero<u32>>`: 4 bytes, alignment: 4 bytes
print-type-size variant `Union1`: 4 bytes print-type-size variant `Union1`: 4 bytes
print-type-size field `.a`: 4 bytes print-type-size field `.a`: 4 bytes
print-type-size type: `Union2<std::num::NonZeroU32, std::num::NonZeroU32>`: 4 bytes, alignment: 4 bytes print-type-size type: `Union2<std::num::NonZero<u32>, std::num::NonZero<u32>>`: 4 bytes, alignment: 4 bytes
print-type-size variant `Union2`: 4 bytes print-type-size variant `Union2`: 4 bytes
print-type-size field `.a`: 4 bytes print-type-size field `.a`: 4 bytes
print-type-size field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes print-type-size field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes
print-type-size type: `Union2<std::num::NonZeroU32, u32>`: 4 bytes, alignment: 4 bytes print-type-size type: `Union2<std::num::NonZero<u32>, u32>`: 4 bytes, alignment: 4 bytes
print-type-size variant `Union2`: 4 bytes print-type-size variant `Union2`: 4 bytes
print-type-size field `.a`: 4 bytes print-type-size field `.a`: 4 bytes
print-type-size field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes print-type-size field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes
print-type-size type: `std::num::NonZeroU32`: 4 bytes, alignment: 4 bytes print-type-size type: `std::num::NonZero<u32>`: 4 bytes, alignment: 4 bytes
print-type-size field `.0`: 4 bytes print-type-size field `.0`: 4 bytes
print-type-size type: `Enum4<(), (), (), MyOption<u8>>`: 2 bytes, alignment: 1 bytes print-type-size type: `Enum4<(), (), (), MyOption<u8>>`: 2 bytes, alignment: 1 bytes
print-type-size variant `Four`: 2 bytes print-type-size variant `Four`: 2 bytes

View file

@ -46,7 +46,7 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(
= note: multiple `impl`s satisfying `u32: From<_>` found in the `core` crate: = note: multiple `impl`s satisfying `u32: From<_>` found in the `core` crate:
- impl From<Char> for u32; - impl From<Char> for u32;
- impl From<Ipv4Addr> for u32; - impl From<Ipv4Addr> for u32;
- impl From<NonZeroU32> for u32; - impl From<NonZero<u32>> for u32;
- impl From<bool> for u32; - impl From<bool> for u32;
- impl From<char> for u32; - impl From<char> for u32;
- impl From<u16> for u32; - impl From<u16> for u32;

View file

@ -11,7 +11,7 @@ LL | Ok(Err(123_i32)?)
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the following other types implement trait `From<T>`: = help: the following other types implement trait `From<T>`:
<u8 as From<bool>> <u8 as From<bool>>
<u8 as From<NonZeroU8>> <u8 as From<NonZero<u8>>>
<u8 as From<Char>> <u8 as From<Char>>
= note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>` = note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`