Skip to content

Commit 9774687

Browse files
committed
Start using pattern types in libcore
1 parent 6c6b492 commit 9774687

22 files changed

+110
-44
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2153,11 +2153,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21532153
}
21542154
}
21552155
CastKind::Transmute => {
2156-
span_mirbug!(
2157-
self,
2158-
rvalue,
2159-
"Unexpected CastKind::Transmute, which is not permitted in Analysis MIR",
2160-
);
2156+
let ty_from = op.ty(body, tcx);
2157+
match ty_from.kind() {
2158+
ty::Pat(base, _) if base == ty => {}
2159+
_ => span_mirbug!(
2160+
self,
2161+
rvalue,
2162+
"Unexpected CastKind::Transmute {ty_from:?} -> {ty:?}, which is not permitted in Analysis MIR",
2163+
),
2164+
}
21612165
}
21622166
}
21632167
}

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,18 @@ pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) ->
456456
AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id),
457457
},
458458
ty::Tuple(_) => build_tuple_type_di_node(cx, unique_type_id),
459-
_ => bug!("debuginfo: unexpected type in type_di_node(): {:?}", t),
459+
ty::Pat(base, _) => return type_di_node(cx, base),
460+
// FIXME(unsafe_binders): impl debug info
461+
ty::UnsafeBinder(_) => unimplemented!(),
462+
ty::Alias(..)
463+
| ty::Param(_)
464+
| ty::Bound(..)
465+
| ty::Infer(_)
466+
| ty::Placeholder(_)
467+
| ty::CoroutineWitness(..)
468+
| ty::Error(_) => {
469+
bug!("debuginfo: unexpected type in type_di_node(): {:?}", t)
470+
}
460471
};
461472

462473
{

compiler/rustc_lint/messages.ftl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -385,9 +385,6 @@ lint_improper_ctypes_only_phantomdata = composed only of `PhantomData`
385385
386386
lint_improper_ctypes_opaque = opaque types have no C equivalent
387387
388-
lint_improper_ctypes_pat_help = consider using the base type instead
389-
390-
lint_improper_ctypes_pat_reason = pattern types have no C equivalent
391388
lint_improper_ctypes_slice_help = consider using a raw pointer instead
392389
393390
lint_improper_ctypes_slice_reason = slices have no C equivalent

compiler/rustc_lint/src/foreign_modules.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,7 @@ fn structurally_same_type_impl<'tcx>(
241241
if let ty::Adt(def, args) = *ty.kind() {
242242
let is_transparent = def.repr().transparent();
243243
let is_non_null = types::nonnull_optimization_guaranteed(tcx, def);
244-
debug!(
245-
"non_transparent_ty({:?}) -- type is transparent? {}, type is non-null? {}",
246-
ty, is_transparent, is_non_null
247-
);
244+
debug!(?ty, is_transparent, is_non_null);
248245
if is_transparent && !is_non_null {
249246
debug_assert_eq!(def.variants().len(), 1);
250247
let v = &def.variant(FIRST_VARIANT);

compiler/rustc_lint/src/types.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -891,9 +891,8 @@ fn get_nullable_type<'tcx>(
891891
};
892892
return get_nullable_type(tcx, typing_env, inner_field_ty);
893893
}
894-
ty::Int(ty) => Ty::new_int(tcx, ty),
895-
ty::Uint(ty) => Ty::new_uint(tcx, ty),
896-
ty::RawPtr(ty, mutbl) => Ty::new_ptr(tcx, ty, mutbl),
894+
ty::Pat(base, ..) => return get_nullable_type(tcx, typing_env, base),
895+
ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => ty,
897896
// As these types are always non-null, the nullable equivalent of
898897
// `Option<T>` of these types are their raw pointer counterparts.
899898
ty::Ref(_region, ty, mutbl) => Ty::new_ptr(tcx, ty, mutbl),
@@ -1240,11 +1239,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
12401239
help: Some(fluent::lint_improper_ctypes_char_help),
12411240
},
12421241

1243-
ty::Pat(..) => FfiUnsafe {
1244-
ty,
1245-
reason: fluent::lint_improper_ctypes_pat_reason,
1246-
help: Some(fluent::lint_improper_ctypes_pat_help),
1247-
},
1242+
// It's just extra invariants on the type that you need to uphold,
1243+
// but only the base type is relevant for being representable in FFI.
1244+
ty::Pat(base, ..) => self.check_type_for_ffi(acc, base),
12481245

12491246
ty::Int(ty::IntTy::I128) | ty::Uint(ty::UintTy::U128) => {
12501247
FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_128bit, help: None }

compiler/rustc_mir_build/src/builder/matches/test.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
146146
let success_block = target_block(TestBranch::Success);
147147
let fail_block = target_block(TestBranch::Failure);
148148

149-
let expect_ty = value.ty();
150-
let expect = self.literal_operand(test.span, value);
149+
let mut expect_ty = value.ty();
150+
let mut expect = self.literal_operand(test.span, value);
151151

152152
let mut place = place;
153153
let mut block = block;
@@ -177,6 +177,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
177177
place = ref_str;
178178
ty = ref_str_ty;
179179
}
180+
&ty::Pat(base, _) => {
181+
assert_eq!(ty, value.ty());
182+
183+
let transmuted_place = self.temp(base, test.span);
184+
self.cfg.push_assign(
185+
block,
186+
self.source_info(scrutinee_span),
187+
transmuted_place,
188+
Rvalue::Cast(CastKind::Transmute, Operand::Copy(place), base),
189+
);
190+
191+
let transmuted_expect = self.temp(base, test.span);
192+
self.cfg.push_assign(
193+
block,
194+
self.source_info(test.span),
195+
transmuted_expect,
196+
Rvalue::Cast(CastKind::Transmute, expect, base),
197+
);
198+
199+
place = transmuted_place;
200+
expect = Operand::Copy(transmuted_expect);
201+
ty = base;
202+
expect_ty = base;
203+
}
180204
_ => {}
181205
}
182206

library/core/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@
181181
#![feature(no_core)]
182182
#![feature(no_sanitize)]
183183
#![feature(optimize_attribute)]
184+
#![feature(pattern_type_macro)]
185+
#![feature(pattern_types)]
184186
#![feature(prelude_import)]
185187
#![feature(repr_simd)]
186188
#![feature(rustc_allow_const_fn_unstable)]

library/core/src/num/niche_types.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,28 @@ use crate::cmp::Ordering;
88
use crate::fmt;
99
use crate::hash::{Hash, Hasher};
1010
use crate::marker::StructuralPartialEq;
11+
#[cfg(not(bootstrap))]
12+
use crate::pattern_type;
1113

1214
macro_rules! define_valid_range_type {
1315
($(
1416
$(#[$m:meta])*
1517
$vis:vis struct $name:ident($int:ident as $uint:ident in $low:literal..=$high:literal);
1618
)+) => {$(
17-
#[derive(Clone, Copy, Eq)]
19+
#[derive(Clone, Copy)]
1820
#[repr(transparent)]
19-
#[rustc_layout_scalar_valid_range_start($low)]
20-
#[rustc_layout_scalar_valid_range_end($high)]
21+
#[cfg_attr(bootstrap, rustc_layout_scalar_valid_range_start($low))]
22+
#[cfg_attr(bootstrap, rustc_layout_scalar_valid_range_end($high))]
2123
$(#[$m])*
24+
#[cfg(bootstrap)]
2225
$vis struct $name($int);
2326

27+
#[derive(Clone, Copy)]
28+
#[repr(transparent)]
29+
$(#[$m])*
30+
#[cfg(not(bootstrap))]
31+
$vis struct $name(pattern_type!($int is $low..=$high));
32+
2433
const _: () = {
2534
// With the `valid_range` attributes, it's always specified as unsigned
2635
assert!(<$uint>::MIN == 0);
@@ -41,7 +50,7 @@ macro_rules! define_valid_range_type {
4150
#[inline]
4251
pub const unsafe fn new_unchecked(val: $int) -> Self {
4352
// SAFETY: Caller promised that `val` is non-zero.
44-
unsafe { $name(val) }
53+
unsafe { $name(crate::mem::transmute(val)) }
4554
}
4655

4756
#[inline]
@@ -57,6 +66,8 @@ macro_rules! define_valid_range_type {
5766
// by <https://github.com/rust-lang/compiler-team/issues/807>.
5867
impl StructuralPartialEq for $name {}
5968

69+
impl Eq for $name {}
70+
6071
impl PartialEq for $name {
6172
#[inline]
6273
fn eq(&self, other: &Self) -> bool {

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({transmute(0x00000001): (usize) is 1..=usize::MAX}));
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({transmute(0x00000001): (usize) is 1..=usize::MAX}));
4949
StorageLive(_7);
5050
_7 = const {0x1 as *const [bool; 0]};
5151
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};

0 commit comments

Comments
 (0)