Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 85a0942

Browse files
committed
Use !null pattern type in libcore
Use `!null` pattern type in libcore
1 parent 33d0a2e commit 85a0942

File tree

30 files changed

+222
-186
lines changed

30 files changed

+222
-186
lines changed

‎compiler/rustc_const_eval/src/interpret/visitor.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,12 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
139139
);
140140
// ... that contains a `NonNull`... (gladly, only a single field here)
141141
assert_eq!(nonnull_ptr.layout().fields.count(), 1);
142-
let raw_ptr = self.ecx().project_field(&nonnull_ptr, FieldIdx::ZERO)?; // the actual raw ptr
142+
let pat_ty = self.ecx().project_field(&nonnull_ptr, FieldIdx::ZERO)?; // `*mut T is !null`
143+
let base = match *pat_ty.layout().ty.kind() {
144+
ty::Pat(base, _) => self.ecx().layout_of(base)?,
145+
_ => unreachable!(),
146+
};
147+
let raw_ptr = pat_ty.transmute(base, self.ecx())?; // The actual raw pointer
143148
// ... whose only field finally is a raw ptr we can dereference.
144149
self.visit_box(ty, &raw_ptr)?;
145150

‎compiler/rustc_mir_transform/src/elaborate_box_derefs.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
77
use rustc_middle::mir::visit::MutVisitor;
88
use rustc_middle::mir::*;
99
use rustc_middle::span_bug;
10-
use rustc_middle::ty::{Ty, TyCtxt};
10+
use rustc_middle::ty::{PatternKind,Ty, TyCtxt};
1111

1212
use crate::patch::MirPatch;
1313

@@ -17,13 +17,14 @@ fn build_ptr_tys<'tcx>(
1717
pointee: Ty<'tcx>,
1818
unique_did: DefId,
1919
nonnull_did: DefId,
20-
) -> (Ty<'tcx>, Ty<'tcx>, Ty<'tcx>) {
20+
) -> (Ty<'tcx>, Ty<'tcx>, Ty<'tcx>,Ty<'tcx>) {
2121
let args = tcx.mk_args(&[pointee.into()]);
2222
let unique_ty = tcx.type_of(unique_did).instantiate(tcx, args);
2323
let nonnull_ty = tcx.type_of(nonnull_did).instantiate(tcx, args);
2424
let ptr_ty = Ty::new_imm_ptr(tcx, pointee);
25+
let pat_ty = Ty::new_pat(tcx, ptr_ty, tcx.mk_pat(PatternKind::NotNull));
2526

26-
(unique_ty, nonnull_ty, ptr_ty)
27+
(unique_ty, nonnull_ty, pat_ty,ptr_ty)
2728
}
2829

2930
/// Constructs the projection needed to access a Box's pointer
@@ -63,7 +64,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'a, 'tcx> {
6364
{
6465
let source_info = self.local_decls[place.local].source_info;
6566

66-
let (unique_ty, nonnull_ty, ptr_ty) =
67+
let (unique_ty, nonnull_ty, _pat_ty,ptr_ty) =
6768
build_ptr_tys(tcx, boxed_ty, self.unique_did, self.nonnull_did);
6869

6970
let ptr_local = self.patch.new_temp(ptr_ty, source_info.span);
@@ -130,10 +131,11 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateBoxDerefs {
130131
let new_projections =
131132
new_projections.get_or_insert_with(|| base.projection.to_vec());
132133

133-
let (unique_ty, nonnull_ty, ptr_ty) =
134+
let (unique_ty, nonnull_ty, pat_ty,ptr_ty) =
134135
build_ptr_tys(tcx, boxed_ty, unique_did, nonnull_did);
135136

136137
new_projections.extend_from_slice(&build_projection(unique_ty, nonnull_ty));
138+
new_projections.push(PlaceElem::Field(FieldIdx::ZERO, pat_ty));
137139
// While we can't project into `NonNull<_>` in a basic block
138140
// due to MCP#807, this is debug info where it's fine.
139141
new_projections.push(PlaceElem::Field(FieldIdx::ZERO, ptr_ty));

‎library/core/src/ptr/non_null.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::cmp::Ordering;
22
use crate::marker::{PointeeSized, Unsize};
3-
use crate::mem::{MaybeUninit, SizedTypeProperties};
3+
use crate::mem::{MaybeUninit, SizedTypeProperties, transmute};
44
use crate::num::NonZero;
55
use crate::ops::{CoerceUnsized, DispatchFromDyn};
66
use crate::pin::PinCoerceUnsized;
@@ -69,13 +69,10 @@ use crate::{fmt, hash, intrinsics, mem, ptr};
6969
/// [null pointer optimization]: crate::option#representation
7070
#[stable(feature = "nonnull", since = "1.25.0")]
7171
#[repr(transparent)]
72-
#[rustc_layout_scalar_valid_range_start(1)]
7372
#[rustc_nonnull_optimization_guaranteed]
7473
#[rustc_diagnostic_item = "NonNull"]
7574
pub struct NonNull<T: PointeeSized> {
76-
// Remember to use `.as_ptr()` instead of `.pointer`, as field projecting to
77-
// this is banned by <https://github.com/rust-lang/compiler-team/issues/807>.
78-
pointer: *const T,
75+
pointer: crate::pattern_type!(*const T is !null),
7976
}
8077

8178
/// `NonNull` pointers are not `Send` because the data they reference may be aliased.
@@ -99,9 +96,9 @@ impl<T: Sized> NonNull<T> {
9996
#[must_use]
10097
#[inline]
10198
pub const fn without_provenance(addr: NonZero<usize>) -> Self {
102-
let pointer = crate::ptr::without_provenance(addr.get());
99+
let pointer:*constT = crate::ptr::without_provenance(addr.get());
103100
// SAFETY: we know `addr` is non-zero.
104-
unsafe { NonNull { pointer } }
101+
unsafe { NonNull { pointer:transmute(pointer) } }
105102
}
106103

107104
/// Creates a new `NonNull` that is dangling, but well-aligned.
@@ -231,7 +228,7 @@ impl<T: PointeeSized> NonNull<T> {
231228
"NonNull::new_unchecked requires that the pointer is non-null",
232229
(ptr: *mut () = ptr as *mut ()) => !ptr.is_null()
233230
);
234-
NonNull { pointer: ptras_ }
231+
NonNull { pointer: transmute(ptr) }
235232
}
236233
}
237234

@@ -274,7 +271,7 @@ impl<T: PointeeSized> NonNull<T> {
274271
#[inline]
275272
pub const fn from_ref(r: &T) -> Self {
276273
// SAFETY: A reference cannot be null.
277-
unsafe { NonNull { pointer: r as *const T } }
274+
unsafe { NonNull { pointer: transmute(r as *const T) } }
278275
}
279276

280277
/// Converts a mutable reference to a `NonNull` pointer.
@@ -283,7 +280,7 @@ impl<T: PointeeSized> NonNull<T> {
283280
#[inline]
284281
pub const fn from_mut(r: &mut T) -> Self {
285282
// SAFETY: A mutable reference cannot be null.
286-
unsafe { NonNull { pointer: r as *mut T } }
283+
unsafe { NonNull { pointer: transmute(r as *mut T) } }
287284
}
288285

289286
/// Performs the same functionality as [`std::ptr::from_raw_parts`], except that a
@@ -494,7 +491,7 @@ impl<T: PointeeSized> NonNull<T> {
494491
#[inline]
495492
pub const fn cast<U>(self) -> NonNull<U> {
496493
// SAFETY: `self` is a `NonNull` pointer which is necessarily non-null
497-
unsafe { NonNull { pointer: self.as_ptr() as *mut U } }
494+
unsafe { NonNull { pointer: transmute(self.as_ptr() as *mut U) } }
498495
}
499496

500497
/// Try to cast to a pointer of another type by checking alignment.
@@ -573,7 +570,7 @@ impl<T: PointeeSized> NonNull<T> {
573570
// Additionally safety contract of `offset` guarantees that the resulting pointer is
574571
// pointing to an allocation, there can't be an allocation at null, thus it's safe to
575572
// construct `NonNull`.
576-
unsafe { NonNull { pointer: intrinsics::offset(self.as_ptr(), count) } }
573+
unsafe { NonNull { pointer: transmute(intrinsics::offset(self.as_ptr(), count)) } }
577574
}
578575

579576
/// Calculates the offset from a pointer in bytes.
@@ -597,7 +594,7 @@ impl<T: PointeeSized> NonNull<T> {
597594
// Additionally safety contract of `offset` guarantees that the resulting pointer is
598595
// pointing to an allocation, there can't be an allocation at null, thus it's safe to
599596
// construct `NonNull`.
600-
unsafe { NonNull { pointer: self.as_ptr().byte_offset(count) } }
597+
unsafe { NonNull { pointer: transmute(self.as_ptr().byte_offset(count)) } }
601598
}
602599

603600
/// Adds an offset to a pointer (convenience for `.offset(count as isize)`).
@@ -649,7 +646,7 @@ impl<T: PointeeSized> NonNull<T> {
649646
// Additionally safety contract of `offset` guarantees that the resulting pointer is
650647
// pointing to an allocation, there can't be an allocation at null, thus it's safe to
651648
// construct `NonNull`.
652-
unsafe { NonNull { pointer: intrinsics::offset(self.as_ptr(), count) } }
649+
unsafe { NonNull { pointer: transmute(intrinsics::offset(self.as_ptr(), count)) } }
653650
}
654651

655652
/// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`).
@@ -673,7 +670,7 @@ impl<T: PointeeSized> NonNull<T> {
673670
// Additionally safety contract of `add` guarantees that the resulting pointer is pointing
674671
// to an allocation, there can't be an allocation at null, thus it's safe to construct
675672
// `NonNull`.
676-
unsafe { NonNull { pointer: self.as_ptr().byte_add(count) } }
673+
unsafe { NonNull { pointer: transmute(self.as_ptr().byte_add(count)) } }
677674
}
678675

679676
/// Subtracts an offset from a pointer (convenience for
@@ -755,7 +752,7 @@ impl<T: PointeeSized> NonNull<T> {
755752
// Additionally safety contract of `sub` guarantees that the resulting pointer is pointing
756753
// to an allocation, there can't be an allocation at null, thus it's safe to construct
757754
// `NonNull`.
758-
unsafe { NonNull { pointer: self.as_ptr().byte_sub(count) } }
755+
unsafe { NonNull { pointer: transmute(self.as_ptr().byte_sub(count)) } }
759756
}
760757

761758
/// Calculates the distance between two pointers within the same allocation. The returned value is in

‎library/std/src/os/unix/io/tests.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ use crate::os::unix::io::RawFd;
22

33
#[test]
44
fn test_raw_fd_layout() {
5-
// `OwnedFd` and `BorrowedFd` use `rustc_layout_scalar_valid_range_start`
6-
// and `rustc_layout_scalar_valid_range_end`, with values that depend on
5+
// `OwnedFd` and `BorrowedFd` use pattern types, with ranges that depend on
76
// the bit width of `RawFd`. If this ever changes, those values will need
87
// to be updated.
98
assert_eq!(size_of::<RawFd>(), 4);

‎library/std/src/os/wasi/io/tests.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ use crate::os::wasi::io::RawFd;
22

33
#[test]
44
fn test_raw_fd_layout() {
5-
// `OwnedFd` and `BorrowedFd` use `rustc_layout_scalar_valid_range_start`
6-
// and `rustc_layout_scalar_valid_range_end`, with values that depend on
5+
// `OwnedFd` and `BorrowedFd` use pattern types with ranges that depend on
76
// the bit width of `RawFd`. If this ever changes, those values will need
87
// to be updated.
98
assert_eq!(size_of::<RawFd>(), 4);

‎src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,10 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
242242
loop {
243243
ty = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty).unwrap_or(ty);
244244
return match *ty.kind() {
245+
ty::Pat(base, _) => {
246+
ty = base;
247+
continue;
248+
},
245249
ty::Array(sub_ty, _) if matches!(sub_ty.kind(), ty::Int(_) | ty::Uint(_)) => {
246250
ReducedTy::TypeErasure { raw_ptr_only: false }
247251
},

‎tests/codegen-llvm/loads.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub fn load_raw_pointer<'a>(x: &*const i32) -> *const i32 {
5858
// CHECK-LABEL: @load_box
5959
#[no_mangle]
6060
pub fn load_box<'a>(x: Box<Box<i32>>) -> Box<i32> {
61-
// CHECK: load ptr, ptr %{{.*}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !align ![[ALIGN_4_META]], !noundef !{{[0-9]+}}
61+
// CHECK: load ptr, ptr %{{.*}}, align [[PTR_ALIGNMENT]], !nonnull !{{[0-9]+}}, !noundef !{{[0-9]+}}
6262
*x
6363
}
6464

‎tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
StorageLive(_1);
1414
- _1 = const 1_usize as std::boxed::Box<Never> (Transmute);
1515
- _2 = copy ((_1.0: std::ptr::Unique<Never>).0: std::ptr::NonNull<Never>) as *const Never (Transmute);
16-
+ _1 = const Box::<Never>(Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData::<Never> }}, std::alloc::Global);
17-
+ _2 = const std::ptr::NonNull::<Never> {{ pointer: {0x1 as *const Never} }} as *const Never (Transmute);
16+
+ _1 = const Box::<Never>(Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} is !null }}, _marker: PhantomData::<Never> }}, std::alloc::Global);
17+
+ _2 = const std::ptr::NonNull::<Never> {{ pointer: {0x1 as *const Never} is !null }} as *const Never (Transmute);
1818
unreachable;
1919
}
2020
}

‎tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
StorageLive(_1);
1414
- _1 = const 1_usize as std::boxed::Box<Never> (Transmute);
1515
- _2 = copy ((_1.0: std::ptr::Unique<Never>).0: std::ptr::NonNull<Never>) as *const Never (Transmute);
16-
+ _1 = const Box::<Never>(Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData::<Never> }}, std::alloc::Global);
17-
+ _2 = const std::ptr::NonNull::<Never> {{ pointer: {0x1 as *const Never} }} as *const Never (Transmute);
16+
+ _1 = const Box::<Never>(Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} is !null }}, _marker: PhantomData::<Never> }}, std::alloc::Global);
17+
+ _2 = const std::ptr::NonNull::<Never> {{ pointer: {0x1 as *const Never} is !null }} as *const Never (Transmute);
1818
unreachable;
1919
}
2020
}

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
scope 8 (inlined std::ptr::Alignment::as_nonzero) {
2222
}
2323
scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) {
24-
let _7: *const [bool; 0];
24+
let mut _7: (*const [bool; 0]) is !null;
2525
scope 10 {
2626
}
2727
scope 11 (inlined NonZero::<usize>::get) {
@@ -47,17 +47,17 @@
4747
StorageLive(_6);
4848
_6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize is 1..));
4949
StorageLive(_7);
50-
_7 = const {0x1 as *const [bool; 0]};
51-
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
50+
_7 = const {0x1 as *const [bool; 0]} is !null;
51+
_5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} is !null }};
5252
StorageDead(_7);
5353
StorageDead(_6);
54-
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
54+
_4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} is !null }}, _marker: PhantomData::<[bool; 0]> }};
5555
StorageDead(_5);
56-
_3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
56+
_3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: (*const [bool]) is !null }}, _marker: PhantomData::<[bool]> }};
5757
StorageDead(_4);
58-
_2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
58+
_2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: (*const [bool]) is !null }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
5959
StorageDead(_3);
60-
_1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }};
60+
_1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: (*const [bool]) is !null }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }};
6161
StorageDead(_2);
6262
_0 = const ();
6363
drop(_1) -> [return: bb1, unwind unreachable];

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /