Skip to content

Add generic NonZero type. #100428

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
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
57 changes: 33 additions & 24 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
@@ -980,43 +980,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr_ty: Ty<'tcx>,
) -> bool {
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
ty::Adt(adt, substs) if tcx.is_diagnostic_item(sym::Option, adt.did()) => {
// Unwrap option
let ty::Adt(adt, _) = substs.type_at(0).kind() else { return false; };

(adt, "")
let nonzero_type = substs.type_at(0); // Unwrap option type.
let ty::Adt(adt, substs) = nonzero_type.kind() else { return false; };
(adt, substs, "")
}
// In case NonZero* is wanted, but * is provided also add `.unwrap()` to satisfy types
ty::Adt(adt, _) => (adt, ".unwrap()"),
// In case `NonZero<*>` is wanted but `*` is provided, also add `.unwrap()` to satisfy types.
ty::Adt(adt, substs) => (adt, substs, ".unwrap()"),
_ => return false,
};

let map = [
(sym::NonZeroU8, tcx.types.u8),
(sym::NonZeroU16, tcx.types.u16),
(sym::NonZeroU32, tcx.types.u32),
(sym::NonZeroU64, tcx.types.u64),
(sym::NonZeroU128, tcx.types.u128),
(sym::NonZeroI8, tcx.types.i8),
(sym::NonZeroI16, tcx.types.i16),
(sym::NonZeroI32, tcx.types.i32),
(sym::NonZeroI64, tcx.types.i64),
(sym::NonZeroI128, tcx.types.i128),
if !self.tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
return false;
}

let coercable_types = [
("NonZeroU8", tcx.types.u8),
("NonZeroU16", tcx.types.u16),
("NonZeroU32", tcx.types.u32),
("NonZeroU64", tcx.types.u64),
("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
let int_type = substs.type_at(0);

let Some(nonzero_alias) = coercable_types
.iter()
.find(|&&(s, t)| self.tcx.is_diagnostic_item(s, adt.did()) && self.can_coerce(expr_ty, t))
.find_map(|(nonzero_alias, t)| {
if *t == int_type && self.can_coerce(expr_ty, *t) {
Some(nonzero_alias)
} else {
None
}
})
else { return false; };

let path = self.tcx.def_path_str(adt.non_enum_variant().def_id);

err.multipart_suggestion(
format!("consider calling `{s}::new`"),
format!("consider calling `{nonzero_alias}::new`"),
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}")),
],
Applicability::MaybeIncorrect,
11 changes: 1 addition & 10 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
@@ -226,16 +226,7 @@ symbols! {
Mutex,
MutexGuard,
N,
NonZeroI128,
NonZeroI16,
NonZeroI32,
NonZeroI64,
NonZeroI8,
NonZeroU128,
NonZeroU16,
NonZeroU32,
NonZeroU64,
NonZeroU8,
NonZero,
None,
Ok,
Option,
51 changes: 25 additions & 26 deletions library/core/src/cmp/bytewise.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
use crate::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
use crate::num::NonZero;

/// Types where `==` & `!=` are equivalent to comparing their underlying bytes.
///
@@ -36,37 +35,37 @@ is_bytewise_comparable!(bool, char, super::Ordering);
// SAFETY: Similarly, the non-zero types have a niche, but no undef and no pointers,
// and they compare like their underlying numeric type.
is_bytewise_comparable!(
NonZeroU8,
NonZeroU16,
NonZeroU32,
NonZeroU64,
NonZeroU128,
NonZeroUsize,
NonZeroI8,
NonZeroI16,
NonZeroI32,
NonZeroI64,
NonZeroI128,
NonZeroIsize,
NonZero<u8>,
NonZero<u16>,
NonZero<u32>,
NonZero<u64>,
NonZero<u128>,
NonZero<usize>,
NonZero<i8>,
NonZero<i16>,
NonZero<i32>,
NonZero<i64>,
NonZero<i128>,
NonZero<isize>,
);

// SAFETY: The NonZero types have the "null" optimization guaranteed, and thus
// are also safe to equality-compare bitwise inside an `Option`.
// The way `PartialOrd` is defined for `Option` means that this wouldn't work
// for `<` or `>` on the signed types, but since we only do `==` it's fine.
is_bytewise_comparable!(
Option<NonZeroU8>,
Option<NonZeroU16>,
Option<NonZeroU32>,
Option<NonZeroU64>,
Option<NonZeroU128>,
Option<NonZeroUsize>,
Option<NonZeroI8>,
Option<NonZeroI16>,
Option<NonZeroI32>,
Option<NonZeroI64>,
Option<NonZeroI128>,
Option<NonZeroIsize>,
Option<NonZero<u8>>,
Option<NonZero<u16>>,
Option<NonZero<u32>>,
Option<NonZero<u64>>,
Option<NonZero<u128>>,
Option<NonZero<usize>>,
Option<NonZero<i8>>,
Option<NonZero<i16>>,
Option<NonZero<i32>>,
Option<NonZero<i64>>,
Option<NonZero<i128>>,
Option<NonZero<isize>>,
);

macro_rules! is_bytewise_comparable_array_length {
155 changes: 84 additions & 71 deletions library/core/src/convert/num.rs
Original file line number Diff line number Diff line change
@@ -408,18 +408,7 @@ mod ptr_try_from_impls {
}

// Conversion traits for non-zero integer types
use crate::num::NonZeroI128;
use crate::num::NonZeroI16;
use crate::num::NonZeroI32;
use crate::num::NonZeroI64;
use crate::num::NonZeroI8;
use crate::num::NonZeroIsize;
use crate::num::NonZeroU128;
use crate::num::NonZeroU16;
use crate::num::NonZeroU32;
use crate::num::NonZeroU64;
use crate::num::NonZeroU8;
use crate::num::NonZeroUsize;
use crate::num::NonZero;

macro_rules! nzint_impl_from {
($Small: ty, $Large: ty, #[$attr:meta], $doc: expr) => {
@@ -450,45 +439,45 @@ macro_rules! nzint_impl_from {
}

// Non-zero Unsigned -> Non-zero Unsigned
nzint_impl_from! { NonZeroU8, NonZeroU16, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU8, NonZeroU32, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU8, NonZeroU64, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU8, NonZeroU128, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU8, NonZeroUsize, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU16, NonZeroU32, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU16, NonZeroU64, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU16, NonZeroU128, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU16, NonZeroUsize, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU32, NonZeroU64, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU32, NonZeroU128, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU64, NonZeroU128, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u8>, NonZero<u16>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u8>, NonZero<u32>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u8>, NonZero<u64>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u8>, NonZero<u128>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u8>, NonZero<usize>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u16>, NonZero<u32>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u16>, NonZero<u64>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u16>, NonZero<u128>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u16>, NonZero<usize>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u32>, NonZero<u64>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u32>, NonZero<u128>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u64>, NonZero<u128>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }

// Non-zero Signed -> Non-zero Signed
nzint_impl_from! { NonZeroI8, NonZeroI16, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroI8, NonZeroI32, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroI8, NonZeroI64, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroI8, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroI8, NonZeroIsize, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroI16, NonZeroI32, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroI16, NonZeroI64, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroI16, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroI16, NonZeroIsize, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroI32, NonZeroI64, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroI32, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroI64, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<i8>, NonZero<i16>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<i8>, NonZero<i32>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<i8>, NonZero<i64>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<i8>, NonZero<i128>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<i8>, NonZero<isize>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<i16>, NonZero<i32>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<i16>, NonZero<i64>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<i16>, NonZero<i128>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<i16>, NonZero<isize>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<i32>, NonZero<i64>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<i32>, NonZero<i128>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<i64>, NonZero<i128>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }

// NonZero UnSigned -> Non-zero Signed
nzint_impl_from! { NonZeroU8, NonZeroI16, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU8, NonZeroI32, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU8, NonZeroI64, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU8, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU8, NonZeroIsize, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU16, NonZeroI32, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU16, NonZeroI64, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU16, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU32, NonZeroI64, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU32, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZeroU64, NonZeroI128, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u8>, NonZero<i16>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u8>, NonZero<i32>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u8>, NonZero<i64>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u8>, NonZero<i128>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u8>, NonZero<isize>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u16>, NonZero<i32>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u16>, NonZero<i64>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u16>, NonZero<i128>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u32>, NonZero<i64>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u32>, NonZero<i128>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }
nzint_impl_from! { NonZero<u64>, NonZero<i128>, #[stable(feature = "nz_int_conv", since = "1.41.0")] }

macro_rules! nzint_impl_try_from_int {
($Int: ty, $NonZeroInt: ty, #[$attr:meta], $doc: expr) => {
@@ -518,18 +507,18 @@ macro_rules! nzint_impl_try_from_int {
}

// Int -> Non-zero Int
nzint_impl_try_from_int! { u8, NonZeroU8, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { u16, NonZeroU16, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { u32, NonZeroU32, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { u64, NonZeroU64, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { u128, NonZeroU128, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { usize, NonZeroUsize, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { i8, NonZeroI8, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { i16, NonZeroI16, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { i32, NonZeroI32, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { i64, NonZeroI64, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { i128, NonZeroI128, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { isize, NonZeroIsize, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { u8, NonZero<u8>, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { u16, NonZero<u16>, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { u32, NonZero<u32>, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { u64, NonZero<u64>, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { u128, NonZero<u128>, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { usize, NonZero<usize>, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { i8, NonZero<i8>, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { i16, NonZero<i16>, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { i32, NonZero<i32>, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { i64, NonZero<i64>, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { i128, NonZero<i128>, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { isize, NonZero<isize>, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }

macro_rules! nzint_impl_try_from_nzint {
($From:ty => $To:ty, $doc: expr) => {
@@ -564,17 +553,41 @@ macro_rules! nzint_impl_try_from_nzint {
}

// Non-zero int -> non-zero unsigned int
nzint_impl_try_from_nzint! { NonZeroU8: NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroU16: NonZeroI8, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroU32: NonZeroI8, NonZeroI16, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroU64: NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroU128: NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroUsize: NonZeroI8, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroIsize }
nzint_impl_try_from_nzint! {
NonZero<u8>: NonZero<i8>, NonZero<u16>, NonZero<i16>, NonZero<u32>, NonZero<i32>, NonZero<u64>, NonZero<i64>, NonZero<u128>, NonZero<i128>, NonZero<usize>, NonZero<isize>
}
nzint_impl_try_from_nzint! {
NonZero<u16>: NonZero<i8>, NonZero<i16>, NonZero<u32>, NonZero<i32>, NonZero<u64>, NonZero<i64>, NonZero<u128>, NonZero<i128>, NonZero<usize>, NonZero<isize>
}
nzint_impl_try_from_nzint! {
NonZero<u32>: NonZero<i8>, NonZero<i16>, NonZero<i32>, NonZero<u64>, NonZero<i64>, NonZero<u128>, NonZero<i128>, NonZero<usize>, NonZero<isize>
}
nzint_impl_try_from_nzint! {
NonZero<u64>: NonZero<i8>, NonZero<i16>, NonZero<i32>, NonZero<i64>, NonZero<u128>, NonZero<i128>, NonZero<usize>, NonZero<isize>
}
nzint_impl_try_from_nzint! {
NonZero<u128>: NonZero<i8>, NonZero<i16>, NonZero<i32>, NonZero<i64>, NonZero<i128>, NonZero<usize>, NonZero<isize>
}
nzint_impl_try_from_nzint! {
NonZero<usize>: NonZero<i8>, NonZero<i16>, NonZero<u32>, NonZero<i32>, NonZero<u64>, NonZero<i64>, NonZero<u128>, NonZero<i128>, NonZero<isize>
}

// Non-zero int -> non-zero signed int
nzint_impl_try_from_nzint! { NonZeroI8: NonZeroU8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroI16: NonZeroU16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroI32: NonZeroU32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroI64: NonZeroU64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroI128: NonZeroU128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroIsize: NonZeroU16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize }
nzint_impl_try_from_nzint! {
NonZero<i8>: NonZero<u8>, NonZero<u16>, NonZero<i16>, NonZero<u32>, NonZero<i32>, NonZero<u64>, NonZero<i64>, NonZero<u128>, NonZero<i128>, NonZero<usize>, NonZero<isize>
}
nzint_impl_try_from_nzint! {
NonZero<i16>: NonZero<u16>, NonZero<u32>, NonZero<i32>, NonZero<u64>, NonZero<i64>, NonZero<u128>, NonZero<i128>, NonZero<usize>, NonZero<isize>
}
nzint_impl_try_from_nzint! {
NonZero<i32>: NonZero<u32>, NonZero<u64>, NonZero<i64>, NonZero<u128>, NonZero<i128>, NonZero<usize>, NonZero<isize>
}
nzint_impl_try_from_nzint! {
NonZero<i64>: NonZero<u64>, NonZero<u128>, NonZero<i128>, NonZero<usize>, NonZero<isize>
}
nzint_impl_try_from_nzint! {
NonZero<i128>: NonZero<u128>, NonZero<usize>, NonZero<isize>
}
nzint_impl_try_from_nzint! {
NonZero<isize>: NonZero<u16>, NonZero<u32>, NonZero<i32>, NonZero<u64>, NonZero<i64>, NonZero<u128>, NonZero<i128>, NonZero<usize>
}
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -189,6 +189,7 @@
#![feature(allow_internal_unstable)]
#![feature(asm_const)]
#![feature(associated_type_bounds)]
#![feature(associated_type_defaults)]
#![feature(auto_traits)]
#![feature(c_unwind)]
#![feature(cfg_sanitize)]
2 changes: 1 addition & 1 deletion library/core/src/mem/mod.rs
Original file line number Diff line number Diff line change
@@ -1168,7 +1168,7 @@ impl<T> fmt::Debug for Discriminant<T> {
/// [`as`]: ../../std/keyword.as.html
/// [primitive representation]: ../../reference/type-layout.html#primitive-representations
/// [default representation]: ../../reference/type-layout.html#the-default-representation
/// ```
/// ```ignore (FIXME: *const _ cannot be resolved anymore for some reason.)
/// #[repr(u8)]
/// enum Enum {
/// Unit,
13 changes: 11 additions & 2 deletions library/core/src/num/mod.rs
Original file line number Diff line number Diff line change
@@ -61,11 +61,20 @@ pub use dec2flt::ParseFloatError;
#[stable(feature = "rust1", since = "1.0.0")]
pub use error::ParseIntError;

#[stable(feature = "nonzero", since = "1.28.0")]
pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
#[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 = "82363")]
pub use nonzero::NonZero;

#[stable(feature = "signed_nonzero", since = "1.34.0")]
pub use nonzero::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
#[stable(feature = "nonzero", since = "1.28.0")]
pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};

#[stable(feature = "try_from", since = "1.34.0")]
pub use error::TryFromIntError;
1,192 changes: 753 additions & 439 deletions library/core/src/num/nonzero.rs

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
@@ -2132,18 +2132,18 @@ macro_rules! non_zero_option {
}

non_zero_option! {
#[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZeroU8;
#[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZeroU16;
#[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZeroU32;
#[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZeroU64;
#[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZeroU128;
#[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZeroUsize;
#[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZeroI8;
#[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZeroI16;
#[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZeroI32;
#[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZeroI64;
#[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZeroI128;
#[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZeroIsize;
#[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZero<u8>;
#[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZero<u16>;
#[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZero<u32>;
#[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZero<u64>;
#[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZero<u128>;
#[stable(feature = "nonzero", since = "1.28.0")] crate::num::NonZero<usize>;
#[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZero<i8>;
#[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZero<i16>;
#[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZero<i32>;
#[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZero<i64>;
#[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZero<i128>;
#[stable(feature = "signed_nonzero", since = "1.34.0")] crate::num::NonZero<isize>;
}

#[stable(feature = "nonnull", since = "1.25.0")]
3 changes: 3 additions & 0 deletions library/std/src/num.rs
Original file line number Diff line number Diff line change
@@ -19,6 +19,9 @@ pub use core::num::Wrapping;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError};

#[unstable(feature = "generic_nonzero", issue = "82363")]
pub use core::num::NonZero;

#[stable(feature = "signed_nonzero", since = "1.34.0")]
pub use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
#[stable(feature = "nonzero", since = "1.28.0")]
Original file line number Diff line number Diff line change
@@ -4,10 +4,7 @@ use clippy_utils::sugg;
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_middle::{
query::Key,
ty::{self, Ty},
};
use rustc_middle::ty::{self, Ty};
use rustc_span::symbol::sym;

/// Checks for `transmute_int_to_non_zero` lint.
@@ -19,40 +16,53 @@ pub(super) fn check<'tcx>(
to_ty: Ty<'tcx>,
arg: &'tcx Expr<'_>,
) -> bool {
let (ty::Int(_) | ty::Uint(_), Some(to_ty_id)) = (&from_ty.kind(), to_ty.ty_adt_id()) else {
let tcx = cx.tcx;

let (ty::Int(_) | ty::Uint(_), ty::Adt(adt, substs)) = (&from_ty.kind(), to_ty.kind()) else {
return false;
};
let Some(to_type_sym) = cx.tcx.get_diagnostic_name(to_ty_id) else {

if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
return false;
};

if !matches!(
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;
}
let coercable_types = [
("NonZeroU8", tcx.types.u8),
("NonZeroU16", tcx.types.u16),
("NonZeroU32", tcx.types.u32),
("NonZeroU64", tcx.types.u64),
("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 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(
cx,
TRANSMUTE_INT_TO_NON_ZERO,
e.span,
&format!("transmute from a `{from_ty}` to a `{to_type_sym}`"),
&format!("transmute from a `{from_ty}` to a `{nonzero_alias}`"),
|diag| {
let arg = sugg::Sugg::hir(cx, arg, "..");
diag.span_suggestion(
e.span,
"consider using",
format!("{to_type_sym}::{}({arg})", sym::new_unchecked),
format!("{nonzero_alias}::{}({arg})", sym::new_unchecked),
Applicability::Unspecified,
);
},
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
let mut _8: EnumReprIsize; // in scope 0 at $DIR/combine_transmutes.rs:+4:31: +4:47
let mut _10: std::cmp::Ordering; // in scope 0 at $DIR/combine_transmutes.rs:+5:28: +5:52
let mut _12: std::cmp::Ordering; // in scope 0 at $DIR/combine_transmutes.rs:+6:28: +6:52
let mut _14: std::option::Option<std::num::NonZeroU8>; // in scope 0 at $DIR/combine_transmutes.rs:+7:28: +7:58
let mut _14: std::option::Option<std::num::NonZero<u8>>; // in scope 0 at $DIR/combine_transmutes.rs:+7:28: +7:58
let mut _16: std::num::Wrapping<i16>; // in scope 0 at $DIR/combine_transmutes.rs:+8:29: +8:54
let mut _18: std::num::Wrapping<i16>; // in scope 0 at $DIR/combine_transmutes.rs:+9:29: +9:54
let mut _20: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+10:29: +10:47
@@ -99,10 +99,10 @@
StorageDead(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:52: +6:53
StorageLive(_13); // scope 6 at $DIR/combine_transmutes.rs:+7:9: +7:11
StorageLive(_14); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58
_14 = Option::<NonZeroU8>::Some(const _); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58
_14 = Option::<NonZero<u8>>::Some(const _); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58
// mir::Constant
// + span: $DIR/combine_transmutes.rs:41:33: 41:57
// + literal: Const { ty: NonZeroU8, val: Unevaluated(NonZeroU8::MAX, [], None) }
// + literal: Const { ty: NonZero<u8>, val: Unevaluated(NonZero::<u8>::MAX, [], None) }
_13 = move _14 as u8 (Transmute); // scope 6 at $DIR/combine_transmutes.rs:+7:18: +7:59
StorageDead(_14); // scope 6 at $DIR/combine_transmutes.rs:+7:58: +7:59
StorageLive(_15); // scope 7 at $DIR/combine_transmutes.rs:+8:9: +8:11
3 changes: 2 additions & 1 deletion tests/ui/binop/issue-28837.rs
Original file line number Diff line number Diff line change
@@ -15,7 +15,8 @@ fn main() {

a & a; //~ ERROR no implementation for `A & A`

a | a; //~ ERROR no implementation for `A | A`
a | a;
//~^ ERROR no implementation for `A | A`

a << a; //~ ERROR no implementation for `A << A`

16 changes: 8 additions & 8 deletions tests/ui/binop/issue-28837.stderr
Original file line number Diff line number Diff line change
@@ -111,7 +111,7 @@ note: the trait `BitOr` must be implemented
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL

error[E0369]: no implementation for `A << A`
--> $DIR/issue-28837.rs:20:7
--> $DIR/issue-28837.rs:21:7
|
LL | a << a;
| - ^^ - A
@@ -127,7 +127,7 @@ note: the trait `Shl` must be implemented
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL

error[E0369]: no implementation for `A >> A`
--> $DIR/issue-28837.rs:22:7
--> $DIR/issue-28837.rs:23:7
|
LL | a >> a;
| - ^^ - A
@@ -143,7 +143,7 @@ note: the trait `Shr` must be implemented
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL

error[E0369]: binary operation `==` cannot be applied to type `A`
--> $DIR/issue-28837.rs:24:7
--> $DIR/issue-28837.rs:25:7
|
LL | a == a;
| - ^^ - A
@@ -162,7 +162,7 @@ LL | struct A;
|

error[E0369]: binary operation `!=` cannot be applied to type `A`
--> $DIR/issue-28837.rs:26:7
--> $DIR/issue-28837.rs:27:7
|
LL | a != a;
| - ^^ - A
@@ -181,7 +181,7 @@ LL | struct A;
|

error[E0369]: binary operation `<` cannot be applied to type `A`
--> $DIR/issue-28837.rs:28:7
--> $DIR/issue-28837.rs:29:7
|
LL | a < a;
| - ^ - A
@@ -200,7 +200,7 @@ LL | struct A;
|

error[E0369]: binary operation `<=` cannot be applied to type `A`
--> $DIR/issue-28837.rs:30:7
--> $DIR/issue-28837.rs:31:7
|
LL | a <= a;
| - ^^ - A
@@ -219,7 +219,7 @@ LL | struct A;
|

error[E0369]: binary operation `>` cannot be applied to type `A`
--> $DIR/issue-28837.rs:32:7
--> $DIR/issue-28837.rs:33:7
|
LL | a > a;
| - ^ - A
@@ -238,7 +238,7 @@ LL | struct A;
|

error[E0369]: binary operation `>=` cannot be applied to type `A`
--> $DIR/issue-28837.rs:34:7
--> $DIR/issue-28837.rs:35:7
|
LL | a >= a;
| - ^^ - A
9 changes: 8 additions & 1 deletion tests/ui/did_you_mean/bad-assoc-ty.stderr
Original file line number Diff line number Diff line change
@@ -147,7 +147,14 @@ error[E0223]: ambiguous associated type
--> $DIR/bad-assoc-ty.rs:33:10
|
LL | type H = Fn(u8) -> (u8)::Output;
| ^^^^^^^^^^^^^^^^^^^^^^ help: use the fully-qualified path: `<(dyn Fn(u8) -> u8 + 'static) as IntoFuture>::Output`
| ^^^^^^^^^^^^^^^^^^^^^^
|
help: use the fully-qualified path
|
LL | type H = <(dyn Fn(u8) -> u8 + 'static) as BitOr>::Output;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | type H = <(dyn Fn(u8) -> u8 + 'static) as IntoFuture>::Output;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

error[E0223]: ambiguous associated type
--> $DIR/bad-assoc-ty.rs:39:19
14 changes: 7 additions & 7 deletions tests/ui/fmt/ifmt-unimpl.stderr
Original file line number Diff line number Diff line change
@@ -9,13 +9,13 @@ LL | format!("{:X}", "3");
= help: the following other types implement trait `UpperHex`:
&T
&mut T
NonZeroI128
NonZeroI16
NonZeroI32
NonZeroI64
NonZeroI8
NonZeroIsize
and 20 others
NonZero<T>
Saturating<T>
Wrapping<T>
i128
i16
i32
and 9 others
= note: required for `&str` to implement `UpperHex`
note: required by a bound in `core::fmt::rt::Argument::<'a>::new_upper_hex`
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
4 changes: 2 additions & 2 deletions tests/ui/layout/zero-sized-array-enum-niche.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN"
#![feature(rustc_attrs)]
#![feature(rustc_attrs, generic_nonzero)]
#![crate_type = "lib"]

// Various tests around the behavior of zero-sized arrays and
@@ -34,7 +34,7 @@ enum MultipleAlignments { //~ ERROR: layout_of
struct Packed<T>(T);

#[rustc_layout(debug)]
type NicheLosesToTagged = Result<[u32; 0], Packed<std::num::NonZeroU16>>; //~ ERROR: layout_of
type NicheLosesToTagged = Result<[u32; 0], Packed<std::num::NonZero<u16>>>; //~ ERROR: layout_of
// Should get tag_encoding: Direct, size == align == 4.

#[repr(u16)]
4 changes: 2 additions & 2 deletions tests/ui/layout/zero-sized-array-enum-niche.stderr
Original file line number Diff line number Diff line change
@@ -218,7 +218,7 @@ error: layout_of(MultipleAlignments) = Layout {
LL | enum MultipleAlignments {
| ^^^^^^^^^^^^^^^^^^^^^^^

error: layout_of(std::result::Result<[u32; 0], Packed<std::num::NonZeroU16>>) = Layout {
error: layout_of(std::result::Result<[u32; 0], Packed<std::num::NonZero<u16>>>) = Layout {
size: Size(4 bytes),
align: AbiAndPrefAlign {
abi: Align(4 bytes),
@@ -314,7 +314,7 @@ error: layout_of(std::result::Result<[u32; 0], Packed<std::num::NonZeroU16>>) =
}
--> $DIR/zero-sized-array-enum-niche.rs:37:1
|
LL | type NicheLosesToTagged = Result<[u32; 0], Packed<std::num::NonZeroU16>>;
LL | type NicheLosesToTagged = Result<[u32; 0], Packed<std::num::NonZero<u16>>>;
| ^^^^^^^^^^^^^^^^^^^^^^^

error: layout_of(std::result::Result<[u32; 0], Packed<U16IsZero>>) = Layout {
39 changes: 20 additions & 19 deletions tests/ui/lint/clashing-extern-fn.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// check-pass
// aux-build:external_extern_fn.rs
#![feature(generic_nonzero)]
#![crate_type = "lib"]
#![warn(clashing_extern_declarations)]

@@ -265,7 +266,7 @@ mod missing_return_type {
mod non_zero_and_non_null {
mod a {
extern "C" {
fn non_zero_usize() -> core::num::NonZeroUsize;
fn non_zero_usize() -> core::num::NonZero<usize>;
fn non_null_ptr() -> core::ptr::NonNull<usize>;
}
}
@@ -285,36 +286,36 @@ mod non_zero_and_non_null {
// See #75739
mod non_zero_transparent {
mod a1 {
use std::num::NonZeroUsize;
use std::num::NonZero;
extern "C" {
fn f1() -> NonZeroUsize;
fn f1() -> NonZero<usize>;
}
}

mod b1 {
#[repr(transparent)]
struct X(NonZeroUsize);
use std::num::NonZeroUsize;
struct X(NonZero<usize>);
use std::num::NonZero;
extern "C" {
fn f1() -> X;
}
}

mod a2 {
use std::num::NonZeroUsize;
use std::num::NonZero;
extern "C" {
fn f2() -> NonZeroUsize;
fn f2() -> NonZero<usize>;
}
}

mod b2 {
#[repr(transparent)]
struct X1(NonZeroUsize);
struct X1(NonZero<usize>);

#[repr(transparent)]
struct X(X1);

use std::num::NonZeroUsize;
use std::num::NonZero;
extern "C" {
// Same case as above, but with two layers of newtyping.
fn f2() -> X;
@@ -325,7 +326,7 @@ mod non_zero_transparent {
#[repr(transparent)]
struct X(core::ptr::NonNull<i32>);

use std::num::NonZeroUsize;
use std::num::NonZero;
extern "C" {
fn f3() -> X;
}
@@ -340,7 +341,7 @@ mod non_zero_transparent {
mod a4 {
#[repr(transparent)]
enum E {
X(std::num::NonZeroUsize),
X(std::num::NonZero<usize>),
}
extern "C" {
fn f4() -> E;
@@ -349,7 +350,7 @@ mod non_zero_transparent {

mod b4 {
extern "C" {
fn f4() -> std::num::NonZeroUsize;
fn f4() -> std::num::NonZero<usize>;
}
}
}
@@ -369,8 +370,8 @@ mod null_optimised_enums {
extern "C" {
// This should be allowed, because these conversions are guaranteed to be FFI-safe (see
// #60300)
fn option_non_zero_usize() -> Option<core::num::NonZeroUsize>;
fn option_non_zero_isize() -> Option<core::num::NonZeroIsize>;
fn option_non_zero_usize() -> Option<core::num::NonZero<usize>>;
fn option_non_zero_isize() -> Option<core::num::NonZero<isize>>;
fn option_non_null_ptr() -> Option<core::ptr::NonNull<usize>>;

// However, these should be incorrect (note isize instead of usize)
@@ -415,16 +416,16 @@ mod hidden_niche {
}
mod b {
use std::cell::UnsafeCell;
use std::num::NonZeroUsize;
use std::num::NonZero;

#[repr(transparent)]
struct Transparent {
x: NonZeroUsize,
x: NonZero<usize>
}

#[repr(transparent)]
struct TransparentNoNiche {
y: UnsafeCell<NonZeroUsize>,
y: UnsafeCell<NonZero<usize>>
}

extern "C" {
@@ -434,9 +435,9 @@ mod hidden_niche {
//~^ WARN redeclared with a different signature
//~| WARN block uses type `Option<TransparentNoNiche>`, which is not FFI-safe

fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usize>>>;
//~^ 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
}
}
}
58 changes: 29 additions & 29 deletions tests/ui/lint/clashing-extern-fn.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
warning: `clash` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:14:13
--> $DIR/clashing-extern-fn.rs:15:13
|
LL | fn clash(x: u8);
| ---------------- `clash` previously declared here
@@ -10,13 +10,13 @@ LL | fn clash(x: u64);
= note: expected `unsafe extern "C" fn(u8)`
found `unsafe extern "C" fn(u64)`
note: the lint level is defined here
--> $DIR/clashing-extern-fn.rs:4:9
--> $DIR/clashing-extern-fn.rs:5:9
|
LL | #![warn(clashing_extern_declarations)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: `extern_link_name` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:52:9
--> $DIR/clashing-extern-fn.rs:53:9
|
LL | / #[link_name = "extern_link_name"]
LL | | fn some_new_name(x: i16);
@@ -29,7 +29,7 @@ LL | fn extern_link_name(x: u32);
found `unsafe extern "C" fn(u32)`

warning: `some_other_extern_link_name` redeclares `some_other_new_name` with a different signature
--> $DIR/clashing-extern-fn.rs:55:9
--> $DIR/clashing-extern-fn.rs:56:9
|
LL | fn some_other_new_name(x: i16);
| ------------------------------- `some_other_new_name` previously declared here
@@ -43,7 +43,7 @@ LL | | fn some_other_extern_link_name(x: u32);
found `unsafe extern "C" fn(u32)`

warning: `other_both_names_different` redeclares `link_name_same` with a different signature
--> $DIR/clashing-extern-fn.rs:59:9
--> $DIR/clashing-extern-fn.rs:60:9
|
LL | / #[link_name = "link_name_same"]
LL | | fn both_names_different(x: i16);
@@ -58,7 +58,7 @@ LL | | fn other_both_names_different(x: u32);
found `unsafe extern "C" fn(u32)`

warning: `different_mod` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:72:9
--> $DIR/clashing-extern-fn.rs:73:9
|
LL | fn different_mod(x: u8);
| ------------------------ `different_mod` previously declared here
@@ -70,7 +70,7 @@ LL | fn different_mod(x: u64);
found `unsafe extern "C" fn(u64)`

warning: `variadic_decl` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:82:9
--> $DIR/clashing-extern-fn.rs:83:9
|
LL | fn variadic_decl(x: u8, ...);
| ----------------------------- `variadic_decl` previously declared here
@@ -82,7 +82,7 @@ LL | fn variadic_decl(x: u8);
found `unsafe extern "C" fn(u8)`

warning: `weigh_banana` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:142:13
--> $DIR/clashing-extern-fn.rs:143:13
|
LL | fn weigh_banana(count: *const Banana) -> u64;
| --------------------------------------------- `weigh_banana` previously declared here
@@ -94,7 +94,7 @@ LL | fn weigh_banana(count: *const Banana) -> u64;
found `unsafe extern "C" fn(*const three::Banana) -> u64`

warning: `draw_point` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:171:13
--> $DIR/clashing-extern-fn.rs:172:13
|
LL | fn draw_point(p: Point);
| ------------------------ `draw_point` previously declared here
@@ -106,7 +106,7 @@ LL | fn draw_point(p: Point);
found `unsafe extern "C" fn(sameish_members::b::Point)`

warning: `origin` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:197:13
--> $DIR/clashing-extern-fn.rs:198:13
|
LL | fn origin() -> Point3;
| ---------------------- `origin` previously declared here
@@ -118,7 +118,7 @@ LL | fn origin() -> Point3;
found `unsafe extern "C" fn() -> same_sized_members_clash::b::Point3`

warning: `transparent_incorrect` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:220:13
--> $DIR/clashing-extern-fn.rs:221:13
|
LL | fn transparent_incorrect() -> T;
| -------------------------------- `transparent_incorrect` previously declared here
@@ -130,7 +130,7 @@ LL | fn transparent_incorrect() -> isize;
found `unsafe extern "C" fn() -> isize`

warning: `missing_return_type` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:259:13
--> $DIR/clashing-extern-fn.rs:260:13
|
LL | fn missing_return_type() -> usize;
| ---------------------------------- `missing_return_type` previously declared here
@@ -142,19 +142,19 @@ LL | fn missing_return_type();
found `unsafe extern "C" fn()`

warning: `non_zero_usize` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:277:13
--> $DIR/clashing-extern-fn.rs:278:13
|
LL | fn non_zero_usize() -> core::num::NonZeroUsize;
| ----------------------------------------------- `non_zero_usize` previously declared here
LL | fn non_zero_usize() -> core::num::NonZero<usize>;
| ------------------------------------------------- `non_zero_usize` previously declared here
...
LL | fn non_zero_usize() -> usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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`

warning: `non_null_ptr` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:279:13
--> $DIR/clashing-extern-fn.rs:280:13
|
LL | fn non_null_ptr() -> core::ptr::NonNull<usize>;
| ----------------------------------------------- `non_null_ptr` previously declared here
@@ -166,7 +166,7 @@ LL | fn non_null_ptr() -> *const usize;
found `unsafe extern "C" fn() -> *const usize`

warning: `option_non_zero_usize_incorrect` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:377:13
--> $DIR/clashing-extern-fn.rs:378:13
|
LL | fn option_non_zero_usize_incorrect() -> usize;
| ---------------------------------------------- `option_non_zero_usize_incorrect` previously declared here
@@ -178,7 +178,7 @@ LL | fn option_non_zero_usize_incorrect() -> isize;
found `unsafe extern "C" fn() -> isize`

warning: `option_non_null_ptr_incorrect` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:379:13
--> $DIR/clashing-extern-fn.rs:380:13
|
LL | fn option_non_null_ptr_incorrect() -> *const usize;
| --------------------------------------------------- `option_non_null_ptr_incorrect` previously declared here
@@ -190,7 +190,7 @@ LL | fn option_non_null_ptr_incorrect() -> *const isize;
found `unsafe extern "C" fn() -> *const isize`

warning: `hidden_niche_transparent_no_niche` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:433:13
--> $DIR/clashing-extern-fn.rs:434:13
|
LL | fn hidden_niche_transparent_no_niche() -> usize;
| ------------------------------------------------ `hidden_niche_transparent_no_niche` previously declared here
@@ -202,19 +202,19 @@ LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
found `unsafe extern "C" fn() -> Option<TransparentNoNiche>`

warning: `hidden_niche_unsafe_cell` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:437:13
--> $DIR/clashing-extern-fn.rs:438:13
|
LL | fn hidden_niche_unsafe_cell() -> usize;
| --------------------------------------- `hidden_niche_unsafe_cell` previously declared here
...
LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usize>>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
|
= 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: `extern` block uses type `Option<TransparentNoNiche>`, which is not FFI-safe
--> $DIR/clashing-extern-fn.rs:433:55
--> $DIR/clashing-extern-fn.rs:434:55
|
LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoNiche>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -223,11 +223,11 @@ LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
= note: enum has no representation hint
= note: `#[warn(improper_ctypes)]` on by default

warning: `extern` block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe
--> $DIR/clashing-extern-fn.rs:437:46
warning: `extern` block uses type `Option<UnsafeCell<NonZero<usize>>>`, which is not FFI-safe
--> $DIR/clashing-extern-fn.rs:438:46
|
LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usize>>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
= note: enum has no representation hint
12 changes: 6 additions & 6 deletions tests/ui/lint/invalid_value.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// This test checks that calling `mem::{uninitialized,zeroed}` with certain types results
// in a lint.

#![feature(never_type, rustc_attrs)]
#![feature(never_type, rustc_attrs, generic_nonzero)]
#![allow(deprecated)]
#![deny(invalid_value)]

use std::mem::{self, MaybeUninit};
use std::ptr::NonNull;
use std::num::NonZeroU32;
use std::num::NonZero;

enum Void {}

@@ -36,7 +36,7 @@ enum OneFruit {

enum OneFruitNonZero {
Apple(!),
Banana(NonZeroU32),
Banana(NonZero<u32>),
}

enum TwoUninhabited {
@@ -92,8 +92,8 @@ fn main() {
let _val: NonNull<i32> = mem::zeroed(); //~ ERROR: does not permit zero-initialization
let _val: NonNull<i32> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized

let _val: (NonZeroU32, i32) = mem::zeroed(); //~ ERROR: does not permit zero-initialization
let _val: (NonZeroU32, i32) = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
let _val: (NonZero<u32>, i32) = mem::zeroed(); //~ ERROR: does not permit zero-initialization
let _val: (NonZero<u32>, i32) = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized

let _val: *const dyn Send = mem::zeroed(); //~ ERROR: does not permit zero-initialization
let _val: *const dyn Send = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
@@ -151,7 +151,7 @@ fn main() {
// Transmute-from-0
let _val: &'static i32 = mem::transmute(0usize); //~ ERROR: does not permit zero-initialization
let _val: &'static [i32] = mem::transmute((0usize, 0usize)); //~ ERROR: does not permit zero-initialization
let _val: NonZeroU32 = mem::transmute(0); //~ ERROR: does not permit zero-initialization
let _val: NonZero<u32> = mem::transmute(0); //~ ERROR: does not permit zero-initialization

// `MaybeUninit` cases
let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init(); //~ ERROR: does not permit zero-initialization
60 changes: 30 additions & 30 deletions tests/ui/lint/invalid_value.stderr
Original file line number Diff line number Diff line change
@@ -316,27 +316,27 @@ LL | let _val: NonNull<i32> = mem::uninitialized();
= note: `std::ptr::NonNull<i32>` must be non-null
= note: raw pointers must be initialized

error: the type `(NonZeroU32, i32)` does not permit zero-initialization
--> $DIR/invalid_value.rs:95:39
error: the type `(NonZero<u32>, i32)` does not permit zero-initialization
--> $DIR/invalid_value.rs:95:41
|
LL | let _val: (NonZeroU32, i32) = mem::zeroed();
| ^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
LL | let _val: (NonZero<u32>, i32) = mem::zeroed();
| ^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| 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
--> $DIR/invalid_value.rs:96:39
error: the type `(NonZero<u32>, i32)` does not permit being left uninitialized
--> $DIR/invalid_value.rs:96:41
|
LL | let _val: (NonZeroU32, i32) = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
LL | let _val: (NonZero<u32>, i32) = mem::uninitialized();
| ^^^^^^^^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| 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

error: the type `*const dyn Send` does not permit zero-initialization
@@ -417,11 +417,11 @@ LL | let _val: OneFruitNonZero = mem::zeroed();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
= 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
|
LL | Banana(NonZeroU32),
| ^^^^^^^^^^
LL | Banana(NonZero<u32>),
| ^^^^^^^^^^^^

error: the type `OneFruitNonZero` does not permit being left uninitialized
--> $DIR/invalid_value.rs:108:37
@@ -433,11 +433,11 @@ LL | let _val: OneFruitNonZero = mem::uninitialized();
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
|
= 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
|
LL | Banana(NonZeroU32),
| ^^^^^^^^^^
LL | Banana(NonZero<u32>),
| ^^^^^^^^^^^^
= note: integers must be initialized

error: the type `bool` does not permit being left uninitialized
@@ -603,16 +603,16 @@ LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize));
|
= note: references must be non-null

error: the type `NonZeroU32` does not permit zero-initialization
--> $DIR/invalid_value.rs:154:32
error: the type `NonZero<u32>` does not permit zero-initialization
--> $DIR/invalid_value.rs:154:34
|
LL | let _val: NonZeroU32 = mem::transmute(0);
| ^^^^^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
LL | let _val: NonZero<u32> = mem::transmute(0);
| ^^^^^^^^^^^^^^^^^
| |
| this code causes undefined behavior when executed
| 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
--> $DIR/invalid_value.rs:157:34
38 changes: 19 additions & 19 deletions tests/ui/lint/lint-ctypes-enum.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#![feature(transparent_unions)]
#![feature(ptr_internals)]
#![feature(ptr_internals, generic_nonzero)]
#![deny(improper_ctypes)]
#![allow(dead_code)]

use std::num;
use std::num::NonZero;

enum Z {}
enum U {
@@ -67,26 +67,26 @@ extern "C" {
fn option_fn(x: Option<extern "C" fn()>);
fn nonnull(x: Option<std::ptr::NonNull<u8>>);
fn unique(x: Option<std::ptr::Unique<u8>>);
fn nonzero_u8(x: Option<num::NonZeroU8>);
fn nonzero_u16(x: Option<num::NonZeroU16>);
fn nonzero_u32(x: Option<num::NonZeroU32>);
fn nonzero_u64(x: Option<num::NonZeroU64>);
fn nonzero_u128(x: Option<num::NonZeroU128>);
fn nonzero_u8(x: Option<NonZero<u8>>);
fn nonzero_u16(x: Option<NonZero<u16>>);
fn nonzero_u32(x: Option<NonZero<u32>>);
fn nonzero_u64(x: Option<NonZero<u64>>);
fn nonzero_u128(x: Option<NonZero<u128>>);
//~^ ERROR `extern` block uses type `u128`
fn nonzero_usize(x: Option<num::NonZeroUsize>);
fn nonzero_i8(x: Option<num::NonZeroI8>);
fn nonzero_i16(x: Option<num::NonZeroI16>);
fn nonzero_i32(x: Option<num::NonZeroI32>);
fn nonzero_i64(x: Option<num::NonZeroI64>);
fn nonzero_i128(x: Option<num::NonZeroI128>);
fn nonzero_usize(x: Option<NonZero<usize>>);
fn nonzero_i8(x: Option<NonZero<i8>>);
fn nonzero_i16(x: Option<NonZero<i16>>);
fn nonzero_i32(x: Option<NonZero<i32>>);
fn nonzero_i64(x: Option<NonZero<i64>>);
fn nonzero_i128(x: Option<NonZero<i128>>);
//~^ ERROR `extern` block uses type `i128`
fn nonzero_isize(x: Option<num::NonZeroIsize>);
fn transparent_struct(x: Option<TransparentStruct<num::NonZeroU8>>);
fn transparent_enum(x: Option<TransparentEnum<num::NonZeroU8>>);
fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
fn nonzero_isize(x: Option<NonZero<isize>>);
fn transparent_struct(x: Option<TransparentStruct<NonZero<u8>>>);
fn transparent_enum(x: Option<TransparentEnum<NonZero<u8>>>);
fn transparent_union(x: Option<TransparentUnion<NonZero<u8>>>);
//~^ ERROR `extern` block uses type
fn repr_rust(x: Option<Rust<num::NonZeroU8>>); //~ ERROR `extern` block uses type
fn no_result(x: Result<(), num::NonZeroI32>); //~ ERROR `extern` block uses type
fn repr_rust(x: Option<Rust<NonZero<u8>>>); //~ ERROR `extern` block uses type
fn no_result(x: Result<(), NonZero<i32>>); //~ ERROR `extern` block uses type
}

pub fn main() {}
26 changes: 13 additions & 13 deletions tests/ui/lint/lint-ctypes-enum.stderr
Original file line number Diff line number Diff line change
@@ -48,42 +48,42 @@ LL | enum T {
error: `extern` block uses type `u128`, which is not FFI-safe
--> $DIR/lint-ctypes-enum.rs:74:23
|
LL | fn nonzero_u128(x: Option<num::NonZeroU128>);
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
LL | fn nonzero_u128(x: Option<NonZero<u128>>);
| ^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= note: 128-bit integers don't currently have a known stable ABI

error: `extern` block uses type `i128`, which is not FFI-safe
--> $DIR/lint-ctypes-enum.rs:81:23
|
LL | fn nonzero_i128(x: Option<num::NonZeroI128>);
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
LL | fn nonzero_i128(x: Option<NonZero<i128>>);
| ^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= 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
|
LL | fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
LL | fn transparent_union(x: Option<TransparentUnion<NonZero<u8>>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
= 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
|
LL | fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
LL | fn repr_rust(x: Option<Rust<NonZero<u8>>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
= 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
|
LL | fn no_result(x: Result<(), num::NonZeroI32>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
LL | fn no_result(x: Result<(), NonZero<i32>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
= note: enum has no representation hint
8 changes: 5 additions & 3 deletions tests/ui/mismatched_types/non_zero_assigned_something.stderr
Original file line number Diff line number Diff line change
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
--> $DIR/non_zero_assigned_something.rs:2:35
|
LL | let _: std::num::NonZeroU64 = 1;
| -------------------- ^ expected `NonZeroU64`, found integer
| -------------------- ^ expected `NonZero<u64>`, found integer
| |
| expected due to this
|
= note: expected struct `NonZero<u64>`
found type `{integer}`
help: consider calling `NonZeroU64::new`
|
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
|
LL | let _: Option<std::num::NonZeroU64> = 1;
| ---------------------------- ^ expected `Option<NonZeroU64>`, found integer
| ---------------------------- ^ expected `Option<NonZero<u64>>`, found integer
| |
| expected due to this
|
= note: expected enum `Option<NonZeroU64>`
= note: expected enum `Option<NonZero<u64>>`
found type `{integer}`
help: consider calling `NonZeroU64::new`
|
Original file line number Diff line number Diff line change
@@ -126,7 +126,7 @@ LL | x / 100.0
<&'a u8 as Div<u8>>
<&u8 as Div<&u8>>
<u8 as Div<&u8>>
<u8 as Div<NonZeroU8>>
<u8 as Div<NonZero<u8>>>
<u8 as Div>

error[E0277]: cannot divide `f64` by `&str`
2 changes: 1 addition & 1 deletion tests/ui/or-patterns/or-patterns-syntactic-fail.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ use E::*;
fn no_top_level_or_patterns() {
// We do *not* allow or-patterns at the top level of lambdas...
let _ = |A | B: E| ();
//~^ ERROR expected identifier, found
//~^ ERROR expected identifier, found `:`
// -------- This looks like an or-pattern but is in fact `|A| (B: E | ())`.
}

22 changes: 11 additions & 11 deletions tests/ui/print_type_sizes/niche-filling.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// compile-flags: -Z print-type-sizes --crate-type=lib
// compile-flags: --crate-type=lib
// build-pass
// ignore-pass
// ^-- needed because `--pass check` does not emit the output needed.
@@ -7,17 +7,17 @@
// This file illustrates how niche-filling enums are handled,
// modelled after cases like `Option<&u32>`, `Option<bool>` and such.
//
// It uses NonZeroU32 rather than `&_` or `Unique<_>`, because
// It uses NonZero<u32> rather than `&_` or `Unique<_>`, because
// the test is not set up to deal with target-dependent pointer width.
//
// It avoids using u64/i64 because on some targets that is only 4-byte
// aligned (while on most it is 8-byte aligned) and so the resulting
// padding and overall computed sizes can be quite different.

#![feature(rustc_attrs)]
#![feature(rustc_attrs, generic_nonzero)]
#![allow(dead_code)]

use std::num::NonZeroU32;
use std::num::NonZero;

pub enum MyOption<T> { None, Some(T) }

@@ -33,7 +33,7 @@ impl<T> Default for MyOption<T> {

pub enum EmbeddedDiscr {
None,
Record { pre: u8, val: NonZeroU32, post: u16 },
Record { pre: u8, val: NonZero<u32>, post: u16 },
}

impl Default for EmbeddedDiscr {
@@ -49,13 +49,13 @@ pub struct IndirectNonZero {

pub struct NestedNonZero {
pre: u8,
val: NonZeroU32,
val: NonZero<u32>,
post: u16,
}

impl Default for NestedNonZero {
fn default() -> Self {
NestedNonZero { pre: 0, val: unsafe { NonZeroU32::new_unchecked(1) }, post: 0 }
NestedNonZero { pre: 0, val: unsafe { NonZero::new_unchecked(1) }, post: 0 }
}
}

@@ -76,7 +76,7 @@ pub union Union2<A: Copy, B: Copy> {
}

pub fn test() {
let _x: MyOption<NonZeroU32> = Default::default();
let _x: MyOption<NonZero<u32>> = Default::default();
let _y: EmbeddedDiscr = Default::default();
let _z: MyOption<IndirectNonZero> = Default::default();
let _a: MyOption<bool> = Default::default();
@@ -89,9 +89,9 @@ pub fn test() {
let _h: MyOption<MyNotNegativeOne> = Default::default();

// Unions do not currently participate in niche filling.
let _i: MyOption<Union2<NonZeroU32, u32>> = Default::default();
let _i: MyOption<Union2<NonZero<u32>, u32>> = Default::default();

// ...even when theoretically possible.
let _j: MyOption<Union1<NonZeroU32>> = Default::default();
let _k: MyOption<Union2<NonZeroU32, NonZeroU32>> = Default::default();
let _j: MyOption<Union1<NonZero<u32>>> = Default::default();
let _k: MyOption<Union2<NonZero<u32>, NonZero<u32>>> = Default::default();
}
112 changes: 0 additions & 112 deletions tests/ui/print_type_sizes/niche-filling.stdout

This file was deleted.

3 changes: 2 additions & 1 deletion tests/ui/traits/issue-77982.stderr
Original file line number Diff line number Diff line change
@@ -45,12 +45,13 @@ 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:
- impl From<Ipv4Addr> for u32;
- impl From<NonZeroU32> for u32;
- impl From<bool> for u32;
- impl From<char> for u32;
- impl From<u16> for u32;
- impl From<u8> for u32;
- impl<T> From<!> for T;
- impl<T> From<NonZero<T>> for T
where T: core::num::nonzero::ZeroablePrimitive;
- impl<T> From<T> for T;
help: try using a fully qualified path to specify the expected types
|
8 changes: 4 additions & 4 deletions tests/ui/traits/new-solver/specialization-transmute.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// compile-flags: -Ztrait-solver=next

#![feature(specialization)]
#![feature(generic_nonzero, specialization)]
//~^ WARN the feature `specialization` is incomplete

trait Default {
@@ -22,9 +22,9 @@ fn transmute<T: Default<Id = U>, U: Copy>(t: T) -> U {
*t.intu()
}

use std::num::NonZeroU8;
use std::num::NonZero;
fn main() {
let s = transmute::<u8, Option<NonZeroU8>>(0);
//~^ ERROR cannot satisfy `<u8 as Default>::Id == Option<NonZeroU8>
let s = transmute::<u8, Option<NonZero<u8>>>(0);
//~^ ERROR cannot satisfy `<u8 as Default>::Id == Option<NonZero<u8>>
assert_eq!(s, None);
}
12 changes: 6 additions & 6 deletions tests/ui/traits/new-solver/specialization-transmute.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/specialization-transmute.rs:3:12
--> $DIR/specialization-transmute.rs:3:29
|
LL | #![feature(specialization)]
| ^^^^^^^^^^^^^^
LL | #![feature(generic_nonzero, specialization)]
| ^^^^^^^^^^^^^^
|
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
= help: consider using `min_specialization` instead, which is more stable and complete
@@ -14,11 +14,11 @@ error[E0284]: type annotations needed: cannot satisfy `T <: <T as Default>::Id`
LL | self
| ^^^^ cannot satisfy `T <: <T as Default>::Id`

error[E0284]: type annotations needed: cannot satisfy `<u8 as Default>::Id == Option<NonZeroU8>`
error[E0284]: type annotations needed: cannot satisfy `<u8 as Default>::Id == Option<NonZero<u8>>`
--> $DIR/specialization-transmute.rs:27:13
|
LL | let s = transmute::<u8, Option<NonZeroU8>>(0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<u8 as Default>::Id == Option<NonZeroU8>`
LL | let s = transmute::<u8, Option<NonZero<u8>>>(0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<u8 as Default>::Id == Option<NonZero<u8>>`
|
note: required by a bound in `transmute`
--> $DIR/specialization-transmute.rs:21:25
4 changes: 1 addition & 3 deletions tests/ui/try-trait/bad-interconversion.stderr
Original file line number Diff line number Diff line change
@@ -7,9 +7,7 @@ LL | Ok(Err(123_i32)?)
| ^ the trait `From<i32>` is not implemented for `u8`
|
= 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>`:
<u8 as From<NonZeroU8>>
<u8 as From<bool>>
= help: the trait `From<bool>` is implemented for `u8`
= note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`

error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`