Skip to content

Commit e8428b9

Browse files
committed
Start using pattern types in libcore
1 parent 3b66729 commit e8428b9

18 files changed

+70
-84
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,18 @@ pub(crate) fn spanned_type_di_node<'ll, 'tcx>(
482482
AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id, span),
483483
},
484484
ty::Tuple(_) => build_tuple_type_di_node(cx, unique_type_id),
485-
_ => bug!("debuginfo: unexpected type in type_di_node(): {:?}", t),
485+
ty::Pat(base, _) => return type_di_node(cx, base),
486+
// FIXME(unsafe_binders): impl debug info
487+
ty::UnsafeBinder(_) => unimplemented!(),
488+
ty::Alias(..)
489+
| ty::Param(_)
490+
| ty::Bound(..)
491+
| ty::Infer(_)
492+
| ty::Placeholder(_)
493+
| ty::CoroutineWitness(..)
494+
| ty::Error(_) => {
495+
bug!("debuginfo: unexpected type in type_di_node(): {:?}", t)
496+
}
486497
};
487498

488499
{

compiler/rustc_const_eval/src/interpret/call.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
8989
let (_, field) = layout.non_1zst_field(self).unwrap();
9090
self.unfold_transparent(field, may_unfold)
9191
}
92+
ty::Pat(base, _) => self.layout_of(*base).expect(
93+
"if the layout of a pattern type could be computed, so can the layout of its base",
94+
),
9295
// Not a transparent type, no further unfolding.
9396
_ => layout,
9497
}

library/core/src/num/niche_types.rs

Lines changed: 38 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -5,60 +5,47 @@
55
)]
66

77
use crate::cmp::Ordering;
8-
use crate::fmt;
98
use crate::hash::{Hash, Hasher};
109
use crate::marker::StructuralPartialEq;
10+
use crate::{fmt, pattern_type};
1111

1212
macro_rules! define_valid_range_type {
1313
($(
1414
$(#[$m:meta])*
15-
$vis:vis struct $name:ident($int:ident as $uint:ident in $low:literal..=$high:literal);
15+
$vis:vis struct $name:ident($int:ident is $pat:pat);
1616
)+) => {$(
17-
#[derive(Clone, Copy, Eq)]
17+
#[derive(Clone, Copy)]
1818
#[repr(transparent)]
19-
#[rustc_layout_scalar_valid_range_start($low)]
20-
#[rustc_layout_scalar_valid_range_end($high)]
2119
$(#[$m])*
22-
$vis struct $name($int);
23-
24-
const _: () = {
25-
// With the `valid_range` attributes, it's always specified as unsigned
26-
assert!(<$uint>::MIN == 0);
27-
let ulow: $uint = $low;
28-
let uhigh: $uint = $high;
29-
assert!(ulow <= uhigh);
30-
31-
assert!(size_of::<$int>() == size_of::<$uint>());
32-
};
33-
20+
$vis struct $name(pattern_type!($int is $pat));
3421
impl $name {
3522
#[inline]
3623
pub const fn new(val: $int) -> Option<Self> {
37-
if (val as $uint) >= ($low as $uint) && (val as $uint) <= ($high as $uint) {
38-
// SAFETY: just checked the inclusive range
39-
Some(unsafe { $name(val) })
24+
#[allow(non_contiguous_range_endpoints)]
25+
if let $pat = val {
26+
// SAFETY: just checked that the value matches the pattern
27+
Some(unsafe { $name(crate::mem::transmute(val)) })
4028
} else {
4129
None
4230
}
4331
}
4432

4533
/// Constructs an instance of this type from the underlying integer
46-
/// primitive without checking whether its zero.
34+
/// primitive without checking whether its valid.
4735
///
4836
/// # Safety
4937
/// Immediate language UB if `val` is not within the valid range for this
5038
/// type, as it violates the validity invariant.
5139
#[inline]
5240
pub const unsafe fn new_unchecked(val: $int) -> Self {
5341
// SAFETY: Caller promised that `val` is within the valid range.
54-
unsafe { $name(val) }
42+
unsafe { $name(crate::mem::transmute(val)) }
5543
}
5644

5745
#[inline]
5846
pub const fn as_inner(self) -> $int {
59-
// SAFETY: This is a transparent wrapper, so unwrapping it is sound
60-
// (Not using `.0` due to MCP#807.)
61-
unsafe { crate::mem::transmute(self) }
47+
// SAFETY: pattern types are always legal values of their base type
48+
unsafe { crate::mem::transmute(self.0) }
6249
}
6350
}
6451

@@ -67,6 +54,8 @@ macro_rules! define_valid_range_type {
6754
// by <https://github.com/rust-lang/compiler-team/issues/807>.
6855
impl StructuralPartialEq for $name {}
6956

57+
impl Eq for $name {}
58+
7059
impl PartialEq for $name {
7160
#[inline]
7261
fn eq(&self, other: &Self) -> bool {
@@ -104,7 +93,7 @@ macro_rules! define_valid_range_type {
10493
}
10594

10695
define_valid_range_type! {
107-
pub struct Nanoseconds(u32 as u32 in 0..=999_999_999);
96+
pub struct Nanoseconds(u32 is 0..=999_999_999);
10897
}
10998

11099
impl Nanoseconds {
@@ -119,47 +108,32 @@ impl Default for Nanoseconds {
119108
}
120109
}
121110

122-
define_valid_range_type! {
123-
pub struct NonZeroU8Inner(u8 as u8 in 1..=0xff);
124-
pub struct NonZeroU16Inner(u16 as u16 in 1..=0xff_ff);
125-
pub struct NonZeroU32Inner(u32 as u32 in 1..=0xffff_ffff);
126-
pub struct NonZeroU64Inner(u64 as u64 in 1..=0xffffffff_ffffffff);
127-
pub struct NonZeroU128Inner(u128 as u128 in 1..=0xffffffffffffffff_ffffffffffffffff);
128-
129-
pub struct NonZeroI8Inner(i8 as u8 in 1..=0xff);
130-
pub struct NonZeroI16Inner(i16 as u16 in 1..=0xff_ff);
131-
pub struct NonZeroI32Inner(i32 as u32 in 1..=0xffff_ffff);
132-
pub struct NonZeroI64Inner(i64 as u64 in 1..=0xffffffff_ffffffff);
133-
pub struct NonZeroI128Inner(i128 as u128 in 1..=0xffffffffffffffff_ffffffffffffffff);
134-
135-
pub struct NonZeroCharInner(char as u32 in 1..=0x10ffff);
136-
}
111+
const HALF_USIZE: usize = usize::MAX >> 1;
137112

138-
#[cfg(target_pointer_width = "16")]
139-
define_valid_range_type! {
140-
pub struct UsizeNoHighBit(usize as usize in 0..=0x7fff);
141-
pub struct NonZeroUsizeInner(usize as usize in 1..=0xffff);
142-
pub struct NonZeroIsizeInner(isize as usize in 1..=0xffff);
143-
}
144-
#[cfg(target_pointer_width = "32")]
145113
define_valid_range_type! {
146-
pub struct UsizeNoHighBit(usize as usize in 0..=0x7fff_ffff);
147-
pub struct NonZeroUsizeInner(usize as usize in 1..=0xffff_ffff);
148-
pub struct NonZeroIsizeInner(isize as usize in 1..=0xffff_ffff);
149-
}
150-
#[cfg(target_pointer_width = "64")]
151-
define_valid_range_type! {
152-
pub struct UsizeNoHighBit(usize as usize in 0..=0x7fff_ffff_ffff_ffff);
153-
pub struct NonZeroUsizeInner(usize as usize in 1..=0xffff_ffff_ffff_ffff);
154-
pub struct NonZeroIsizeInner(isize as usize in 1..=0xffff_ffff_ffff_ffff);
155-
}
114+
pub struct NonZeroU8Inner(u8 is 1..);
115+
pub struct NonZeroU16Inner(u16 is 1..);
116+
pub struct NonZeroU32Inner(u32 is 1..);
117+
pub struct NonZeroU64Inner(u64 is 1..);
118+
pub struct NonZeroU128Inner(u128 is 1..);
156119

157-
define_valid_range_type! {
158-
pub struct U32NotAllOnes(u32 as u32 in 0..=0xffff_fffe);
159-
pub struct I32NotAllOnes(i32 as u32 in 0..=0xffff_fffe);
120+
pub struct NonZeroI8Inner(i8 is ..0 | 1..);
121+
pub struct NonZeroI16Inner(i16 is ..0 | 1..);
122+
pub struct NonZeroI32Inner(i32 is ..0 | 1..);
123+
pub struct NonZeroI64Inner(i64 is ..0 | 1..);
124+
pub struct NonZeroI128Inner(i128 is ..0 | 1..);
125+
126+
pub struct UsizeNoHighBit(usize is 0..=HALF_USIZE);
127+
pub struct NonZeroUsizeInner(usize is 1..);
128+
pub struct NonZeroIsizeInner(isize is ..0 | 1..);
129+
130+
pub struct U32NotAllOnes(u32 is 0..u32::MAX);
131+
pub struct I32NotAllOnes(i32 is ..-1 | 0..);
132+
133+
pub struct U64NotAllOnes(u64 is 0..u64::MAX);
134+
pub struct I64NotAllOnes(i64 is ..-1 | 0..);
160135

161-
pub struct U64NotAllOnes(u64 as u64 in 0..=0xffff_ffff_ffff_fffe);
162-
pub struct I64NotAllOnes(i64 as u64 in 0..=0xffff_ffff_ffff_fffe);
136+
pub struct NonZeroCharInner(char is '\u{1}' ..= '\u{10ffff}');
163137
}
164138

165139
pub trait NotAllOnesHelper {
@@ -180,7 +154,7 @@ impl NotAllOnesHelper for i64 {
180154
}
181155

182156
define_valid_range_type! {
183-
pub struct CodePointInner(u32 as u32 in 0..=0x10ffff);
157+
pub struct CodePointInner(u32 is 0..=0x10ffff);
184158
}
185159

186160
impl CodePointInner {

src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_callee_ret.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: Undefined Behavior: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
1+
error: Undefined Behavior: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
22
--> tests/fail/validity/cast_fn_ptr_invalid_callee_ret.rs:LL:CC
33
|
44
LL | f();

src/tools/miri/tests/fail/validity/cast_fn_ptr_invalid_caller_arg.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: Undefined Behavior: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
1+
error: Undefined Behavior: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
22
--> tests/fail/validity/cast_fn_ptr_invalid_caller_arg.rs:LL:CC
33
|
44
LL | Call(_res = f(*ptr), ReturnTo(retblock), UnwindContinue())

tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
StorageLive(_4);
4646
StorageLive(_5);
4747
StorageLive(_6);
48-
_6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize));
48+
_6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize is 1..));
4949
StorageLive(_7);
5050
_7 = const {0x1 as *const [bool; 0]};
5151
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};

tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
StorageLive(_4);
4646
StorageLive(_5);
4747
StorageLive(_6);
48-
_6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize));
48+
_6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize is 1..));
4949
StorageLive(_7);
5050
_7 = const {0x1 as *const [bool; 0]};
5151
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};

tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
StorageLive(_4);
4646
StorageLive(_5);
4747
StorageLive(_6);
48-
_6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize));
48+
_6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize is 1..));
4949
StorageLive(_7);
5050
_7 = const {0x1 as *const [bool; 0]};
5151
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};

tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
StorageLive(_4);
4646
StorageLive(_5);
4747
StorageLive(_6);
48-
_6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize));
48+
_6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize is 1..));
4949
StorageLive(_7);
5050
_7 = const {0x1 as *const [bool; 0]};
5151
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};

tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
StorageLive(_5);
4747
StorageLive(_6);
4848
- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as std::num::NonZero<usize> (Transmute);
49-
+ _6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize));
49+
+ _6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize is 1..));
5050
StorageLive(_7);
5151
- _7 = copy _6 as *const [bool; 0] (Transmute);
5252
- _5 = NonNull::<[bool; 0]> { pointer: copy _7 };

0 commit comments

Comments
 (0)