Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 9514a86

Browse files
committedJan 27, 2025
Start using pattern types in libcore
1 parent 6c6b492 commit 9514a86

File tree

12 files changed

+99
-33
lines changed

12 files changed

+99
-33
lines changed
 

‎compiler/rustc_borrowck/src/type_check/mod.rs

+9-5
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

+12-1
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

-3
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

+1-4
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

+5-8
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

+26-2
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

+2
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

+15-4
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/ui/consts/const-eval/raw-bytes.64bit.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ error[E0080]: it is undefined behavior to use this value
6868
--> $DIR/raw-bytes.rs:59:1
6969
|
7070
LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
71-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
71+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
7272
|
7373
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
7474
= note: the raw bytes of the constant (size: 1, align: 1) {
@@ -79,7 +79,7 @@ error[E0080]: it is undefined behavior to use this value
7979
--> $DIR/raw-bytes.rs:61:1
8080
|
8181
LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
82-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
82+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
8383
|
8484
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
8585
= note: the raw bytes of the constant (size: 8, align: 8) {

‎tests/ui/consts/const-eval/ub-nonnull.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ error[E0080]: it is undefined behavior to use this value
1919
--> $DIR/ub-nonnull.rs:24:1
2020
|
2121
LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
22-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
2323
|
2424
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
2525
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
@@ -30,7 +30,7 @@ error[E0080]: it is undefined behavior to use this value
3030
--> $DIR/ub-nonnull.rs:26:1
3131
|
3232
LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
33-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
33+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
3434
|
3535
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
3636
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {

‎tests/ui/lint/invalid_value.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,6 @@ LL | let _val: (NonZero<u32>, i32) = mem::uninitialized();
333333
|
334334
= note: `std::num::NonZero<u32>` must be non-null
335335
= note: because `core::num::niche_types::NonZeroU32Inner` must be non-null
336-
= note: integers must be initialized
337336

338337
error: the type `*const dyn Send` does not permit zero-initialization
339338
--> $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
430429
LL | Banana(NonZero<u32>),
431430
| ^^^^^^^^^^^^
432431
= note: because `core::num::niche_types::NonZeroU32Inner` must be non-null
433-
= note: integers must be initialized
434432

435433
error: the type `bool` does not permit being left uninitialized
436434
--> $DIR/invalid_value.rs:111:26
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#![feature(pattern_types, pattern_type_macro, structural_match)]
2+
3+
//@ check-pass
4+
5+
use std::marker::StructuralPartialEq;
6+
use std::pat::pattern_type;
7+
8+
struct Thing(pattern_type!(u32 is 1..));
9+
10+
impl StructuralPartialEq for Thing {}
11+
impl Eq for Thing {}
12+
impl PartialEq for Thing {
13+
fn eq(&self, other: &Thing) -> bool {
14+
todo!()
15+
}
16+
}
17+
18+
const TWO: Thing = Thing(unsafe { std::mem::transmute(2_u32) });
19+
20+
const _: () = match TWO {
21+
TWO => {}
22+
_ => unreachable!(),
23+
};
24+
25+
fn main() {}

0 commit comments

Comments
 (0)
Failed to load comments.