Auto merge of #148537 - oli-obk:push-yxuttqrqqyvu, r=dianqk
Start using pattern types in libcore (NonZero and friends) part of rust-lang/rust#136006 This PR only changes the internal representation of `NonZero`, `NonMax`, ... and other integral range types in libcore. This subsequently affects other types made up of it, but nothing really changes except that the field of `NonZero` is now accessible safely in contrast to the `rustc_layout_scalar_range_start` attribute, which has all kinds of obscure rules on how to properly access its field.
This commit is contained in:
commit
bb8b30a5fc
10 changed files with 65 additions and 75 deletions
|
|
@ -479,7 +479,18 @@ pub(crate) fn spanned_type_di_node<'ll, 'tcx>(
|
|||
AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id, span),
|
||||
},
|
||||
ty::Tuple(_) => build_tuple_type_di_node(cx, unique_type_id),
|
||||
_ => bug!("debuginfo: unexpected type in type_di_node(): {:?}", t),
|
||||
ty::Pat(base, _) => return type_di_node(cx, base),
|
||||
// FIXME(unsafe_binders): impl debug info
|
||||
ty::UnsafeBinder(_) => unimplemented!(),
|
||||
ty::Alias(..)
|
||||
| ty::Param(_)
|
||||
| ty::Bound(..)
|
||||
| ty::Infer(_)
|
||||
| ty::Placeholder(_)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Error(_) => {
|
||||
bug!("debuginfo: unexpected type in type_di_node(): {:?}", t)
|
||||
}
|
||||
};
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -91,6 +91,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
let (_, field) = layout.non_1zst_field(self).unwrap();
|
||||
self.unfold_transparent(field, may_unfold)
|
||||
}
|
||||
ty::Pat(base, _) => self.layout_of(*base).expect(
|
||||
"if the layout of a pattern type could be computed, so can the layout of its base",
|
||||
),
|
||||
// Not a transparent type, no further unfolding.
|
||||
_ => layout,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,45 +5,33 @@
|
|||
)]
|
||||
|
||||
use crate::cmp::Ordering;
|
||||
use crate::fmt;
|
||||
use crate::hash::{Hash, Hasher};
|
||||
use crate::marker::StructuralPartialEq;
|
||||
use crate::{fmt, pattern_type};
|
||||
|
||||
macro_rules! define_valid_range_type {
|
||||
($(
|
||||
$(#[$m:meta])*
|
||||
$vis:vis struct $name:ident($int:ident as $uint:ident in $low:literal..=$high:literal);
|
||||
$vis:vis struct $name:ident($int:ident is $pat:pat);
|
||||
)+) => {$(
|
||||
#[derive(Clone, Copy, Eq)]
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
#[rustc_layout_scalar_valid_range_start($low)]
|
||||
#[rustc_layout_scalar_valid_range_end($high)]
|
||||
$(#[$m])*
|
||||
$vis struct $name($int);
|
||||
|
||||
const _: () = {
|
||||
// With the `valid_range` attributes, it's always specified as unsigned
|
||||
assert!(<$uint>::MIN == 0);
|
||||
let ulow: $uint = $low;
|
||||
let uhigh: $uint = $high;
|
||||
assert!(ulow <= uhigh);
|
||||
|
||||
assert!(size_of::<$int>() == size_of::<$uint>());
|
||||
};
|
||||
|
||||
$vis struct $name(pattern_type!($int is $pat));
|
||||
impl $name {
|
||||
#[inline]
|
||||
pub const fn new(val: $int) -> Option<Self> {
|
||||
if (val as $uint) >= ($low as $uint) && (val as $uint) <= ($high as $uint) {
|
||||
// SAFETY: just checked the inclusive range
|
||||
Some(unsafe { $name(val) })
|
||||
#[allow(non_contiguous_range_endpoints)]
|
||||
if let $pat = val {
|
||||
// SAFETY: just checked that the value matches the pattern
|
||||
Some(unsafe { $name(crate::mem::transmute(val)) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs an instance of this type from the underlying integer
|
||||
/// primitive without checking whether its zero.
|
||||
/// primitive without checking whether its valid.
|
||||
///
|
||||
/// # Safety
|
||||
/// Immediate language UB if `val` is not within the valid range for this
|
||||
|
|
@ -51,13 +39,13 @@ macro_rules! define_valid_range_type {
|
|||
#[inline]
|
||||
pub const unsafe fn new_unchecked(val: $int) -> Self {
|
||||
// SAFETY: Caller promised that `val` is within the valid range.
|
||||
unsafe { $name(val) }
|
||||
unsafe { crate::mem::transmute(val) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn as_inner(self) -> $int {
|
||||
// SAFETY: This is a transparent wrapper, so unwrapping it is sound
|
||||
// (Not using `.0` due to MCP#807.)
|
||||
// SAFETY: pattern types are always legal values of their base type
|
||||
// (Not using `.0` because that has perf regressions.)
|
||||
unsafe { crate::mem::transmute(self) }
|
||||
}
|
||||
}
|
||||
|
|
@ -67,6 +55,8 @@ macro_rules! define_valid_range_type {
|
|||
// by <https://github.com/rust-lang/compiler-team/issues/807>.
|
||||
impl StructuralPartialEq for $name {}
|
||||
|
||||
impl Eq for $name {}
|
||||
|
||||
impl PartialEq for $name {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
|
|
@ -104,7 +94,7 @@ macro_rules! define_valid_range_type {
|
|||
}
|
||||
|
||||
define_valid_range_type! {
|
||||
pub struct Nanoseconds(u32 as u32 in 0..=999_999_999);
|
||||
pub struct Nanoseconds(u32 is 0..=999_999_999);
|
||||
}
|
||||
|
||||
impl Nanoseconds {
|
||||
|
|
@ -120,47 +110,32 @@ impl const Default for Nanoseconds {
|
|||
}
|
||||
}
|
||||
|
||||
define_valid_range_type! {
|
||||
pub struct NonZeroU8Inner(u8 as u8 in 1..=0xff);
|
||||
pub struct NonZeroU16Inner(u16 as u16 in 1..=0xff_ff);
|
||||
pub struct NonZeroU32Inner(u32 as u32 in 1..=0xffff_ffff);
|
||||
pub struct NonZeroU64Inner(u64 as u64 in 1..=0xffffffff_ffffffff);
|
||||
pub struct NonZeroU128Inner(u128 as u128 in 1..=0xffffffffffffffff_ffffffffffffffff);
|
||||
|
||||
pub struct NonZeroI8Inner(i8 as u8 in 1..=0xff);
|
||||
pub struct NonZeroI16Inner(i16 as u16 in 1..=0xff_ff);
|
||||
pub struct NonZeroI32Inner(i32 as u32 in 1..=0xffff_ffff);
|
||||
pub struct NonZeroI64Inner(i64 as u64 in 1..=0xffffffff_ffffffff);
|
||||
pub struct NonZeroI128Inner(i128 as u128 in 1..=0xffffffffffffffff_ffffffffffffffff);
|
||||
|
||||
pub struct NonZeroCharInner(char as u32 in 1..=0x10ffff);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "16")]
|
||||
define_valid_range_type! {
|
||||
pub struct UsizeNoHighBit(usize as usize in 0..=0x7fff);
|
||||
pub struct NonZeroUsizeInner(usize as usize in 1..=0xffff);
|
||||
pub struct NonZeroIsizeInner(isize as usize in 1..=0xffff);
|
||||
}
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
define_valid_range_type! {
|
||||
pub struct UsizeNoHighBit(usize as usize in 0..=0x7fff_ffff);
|
||||
pub struct NonZeroUsizeInner(usize as usize in 1..=0xffff_ffff);
|
||||
pub struct NonZeroIsizeInner(isize as usize in 1..=0xffff_ffff);
|
||||
}
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
define_valid_range_type! {
|
||||
pub struct UsizeNoHighBit(usize as usize in 0..=0x7fff_ffff_ffff_ffff);
|
||||
pub struct NonZeroUsizeInner(usize as usize in 1..=0xffff_ffff_ffff_ffff);
|
||||
pub struct NonZeroIsizeInner(isize as usize in 1..=0xffff_ffff_ffff_ffff);
|
||||
}
|
||||
const HALF_USIZE: usize = usize::MAX >> 1;
|
||||
|
||||
define_valid_range_type! {
|
||||
pub struct U32NotAllOnes(u32 as u32 in 0..=0xffff_fffe);
|
||||
pub struct I32NotAllOnes(i32 as u32 in 0..=0xffff_fffe);
|
||||
pub struct NonZeroU8Inner(u8 is 1..);
|
||||
pub struct NonZeroU16Inner(u16 is 1..);
|
||||
pub struct NonZeroU32Inner(u32 is 1..);
|
||||
pub struct NonZeroU64Inner(u64 is 1..);
|
||||
pub struct NonZeroU128Inner(u128 is 1..);
|
||||
|
||||
pub struct U64NotAllOnes(u64 as u64 in 0..=0xffff_ffff_ffff_fffe);
|
||||
pub struct I64NotAllOnes(i64 as u64 in 0..=0xffff_ffff_ffff_fffe);
|
||||
pub struct NonZeroI8Inner(i8 is ..0 | 1..);
|
||||
pub struct NonZeroI16Inner(i16 is ..0 | 1..);
|
||||
pub struct NonZeroI32Inner(i32 is ..0 | 1..);
|
||||
pub struct NonZeroI64Inner(i64 is ..0 | 1..);
|
||||
pub struct NonZeroI128Inner(i128 is ..0 | 1..);
|
||||
|
||||
pub struct UsizeNoHighBit(usize is 0..=HALF_USIZE);
|
||||
pub struct NonZeroUsizeInner(usize is 1..);
|
||||
pub struct NonZeroIsizeInner(isize is ..0 | 1..);
|
||||
|
||||
pub struct U32NotAllOnes(u32 is 0..u32::MAX);
|
||||
pub struct I32NotAllOnes(i32 is ..-1 | 0..);
|
||||
|
||||
pub struct U64NotAllOnes(u64 is 0..u64::MAX);
|
||||
pub struct I64NotAllOnes(i64 is ..-1 | 0..);
|
||||
|
||||
pub struct NonZeroCharInner(char is '\u{1}' ..= '\u{10ffff}');
|
||||
}
|
||||
|
||||
pub trait NotAllOnesHelper {
|
||||
|
|
@ -181,7 +156,7 @@ impl NotAllOnesHelper for i64 {
|
|||
}
|
||||
|
||||
define_valid_range_type! {
|
||||
pub struct CodePointInner(u32 as u32 in 0..=0x10ffff);
|
||||
pub struct CodePointInner(u32 is 0..=0x10ffff);
|
||||
}
|
||||
|
||||
impl CodePointInner {
|
||||
|
|
|
|||
|
|
@ -2184,6 +2184,9 @@ Please disable assertions with `rust.debug-assertions = false`.
|
|||
for flag in targetflags {
|
||||
cmd.arg("--target-rustcflags").arg(flag);
|
||||
}
|
||||
if target.is_synthetic() {
|
||||
cmd.arg("--target-rustcflags").arg("-Zunstable-options");
|
||||
}
|
||||
|
||||
cmd.arg("--python").arg(
|
||||
builder.config.python.as_ref().expect("python is required for running rustdoc tests"),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error: Undefined Behavior: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
|
||||
error: Undefined Behavior: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
|
||||
--> tests/fail/validity/cast_fn_ptr_invalid_callee_ret.rs:LL:CC
|
||||
|
|
||||
LL | f();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error: Undefined Behavior: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
|
||||
error: Undefined Behavior: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
|
||||
--> tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs:LL:CC
|
||||
|
|
||||
LL | Call(_res = f(*ptr), ReturnTo(retblock), UnwindContinue())
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
|
|||
00 00 00 00 │ ....
|
||||
}
|
||||
|
||||
error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
|
||||
error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
|
||||
--> $DIR/raw-bytes.rs:61:1
|
||||
|
|
||||
LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
|
||||
|
|
@ -75,7 +75,7 @@ LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
|
|||
00 │ .
|
||||
}
|
||||
|
||||
error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
|
||||
error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
|
||||
--> $DIR/raw-bytes.rs:63:1
|
||||
|
|
||||
LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
|
|||
00 00 00 00 00 00 00 00 │ ........
|
||||
}
|
||||
|
||||
error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
|
||||
error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
|
||||
--> $DIR/raw-bytes.rs:61:1
|
||||
|
|
||||
LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
|
||||
|
|
@ -75,7 +75,7 @@ LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
|
|||
00 │ .
|
||||
}
|
||||
|
||||
error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
|
||||
error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
|
||||
--> $DIR/raw-bytes.rs:63:1
|
||||
|
|
||||
LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer
|
|||
LL | let out_of_bounds_ptr = &ptr[255];
|
||||
| ^^^^^^^^^ evaluation of `OUT_OF_BOUNDS_PTR` failed here
|
||||
|
||||
error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
|
||||
error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
|
||||
--> $DIR/ub-nonnull.rs:26:1
|
||||
|
|
||||
LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
|
||||
|
|
@ -26,7 +26,7 @@ LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
|
|||
HEX_DUMP
|
||||
}
|
||||
|
||||
error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
|
||||
error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
|
||||
--> $DIR/ub-nonnull.rs:28:1
|
||||
|
|
||||
LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
|
||||
|
|
|
|||
|
|
@ -333,7 +333,6 @@ LL | let _val: (NonZero<u32>, i32) = mem::uninitialized();
|
|||
|
|
||||
= note: `std::num::NonZero<u32>` must be non-null
|
||||
= note: because `core::num::niche_types::NonZeroU32Inner` must be non-null
|
||||
= note: integers must be initialized
|
||||
|
||||
error: the type `*const dyn Send` does not permit zero-initialization
|
||||
--> $DIR/invalid_value.rs:97:37
|
||||
|
|
@ -430,7 +429,6 @@ note: because `std::num::NonZero<u32>` must be non-null (in this field of the on
|
|||
LL | Banana(NonZero<u32>),
|
||||
| ^^^^^^^^^^^^
|
||||
= note: because `core::num::niche_types::NonZeroU32Inner` must be non-null
|
||||
= note: integers must be initialized
|
||||
|
||||
error: the type `bool` does not permit being left uninitialized
|
||||
--> $DIR/invalid_value.rs:111:26
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue