Skip to content

Commit ea5f33e

Browse files
committed
Auto merge of #152702 - oli-obk:nonnulltransmute, r=<try>
Prepare NonNull for pattern types
2 parents fef627b + b11fecb commit ea5f33e

11 files changed

Lines changed: 291 additions & 262 deletions

library/core/src/ptr/non_null.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::clone::TrivialClone;
22
use crate::cmp::Ordering;
33
use crate::marker::{Destruct, PointeeSized, Unsize};
4-
use crate::mem::{MaybeUninit, SizedTypeProperties};
4+
use crate::mem::{MaybeUninit, SizedTypeProperties, transmute};
55
use crate::num::NonZero;
66
use crate::ops::{CoerceUnsized, DispatchFromDyn};
77
use crate::pin::PinCoerceUnsized;
@@ -100,9 +100,9 @@ impl<T: Sized> NonNull<T> {
100100
#[must_use]
101101
#[inline]
102102
pub const fn without_provenance(addr: NonZero<usize>) -> Self {
103-
let pointer = crate::ptr::without_provenance(addr.get());
103+
let pointer: *const T = crate::ptr::without_provenance(addr.get());
104104
// SAFETY: we know `addr` is non-zero.
105-
unsafe { NonNull { pointer } }
105+
unsafe { NonNull { pointer: transmute(pointer) } }
106106
}
107107

108108
/// Creates a new `NonNull` that is dangling, but well-aligned.
@@ -239,7 +239,7 @@ impl<T: PointeeSized> NonNull<T> {
239239
"NonNull::new_unchecked requires that the pointer is non-null",
240240
(ptr: *mut () = ptr as *mut ()) => !ptr.is_null()
241241
);
242-
NonNull { pointer: ptr as _ }
242+
NonNull { pointer: transmute(ptr) }
243243
}
244244
}
245245

@@ -282,7 +282,7 @@ impl<T: PointeeSized> NonNull<T> {
282282
#[inline]
283283
pub const fn from_ref(r: &T) -> Self {
284284
// SAFETY: A reference cannot be null.
285-
unsafe { NonNull { pointer: r as *const T } }
285+
unsafe { NonNull { pointer: transmute(r as *const T) } }
286286
}
287287

288288
/// Converts a mutable reference to a `NonNull` pointer.
@@ -291,7 +291,7 @@ impl<T: PointeeSized> NonNull<T> {
291291
#[inline]
292292
pub const fn from_mut(r: &mut T) -> Self {
293293
// SAFETY: A mutable reference cannot be null.
294-
unsafe { NonNull { pointer: r as *mut T } }
294+
unsafe { NonNull { pointer: transmute(r as *mut T) } }
295295
}
296296

297297
/// Performs the same functionality as [`std::ptr::from_raw_parts`], except that a
@@ -502,7 +502,7 @@ impl<T: PointeeSized> NonNull<T> {
502502
#[inline]
503503
pub const fn cast<U>(self) -> NonNull<U> {
504504
// SAFETY: `self` is a `NonNull` pointer which is necessarily non-null
505-
unsafe { NonNull { pointer: self.as_ptr() as *mut U } }
505+
unsafe { NonNull { pointer: transmute(self.as_ptr() as *mut U) } }
506506
}
507507

508508
/// Try to cast to a pointer of another type by checking alignment.
@@ -581,7 +581,7 @@ impl<T: PointeeSized> NonNull<T> {
581581
// Additionally safety contract of `offset` guarantees that the resulting pointer is
582582
// pointing to an allocation, there can't be an allocation at null, thus it's safe to
583583
// construct `NonNull`.
584-
unsafe { NonNull { pointer: intrinsics::offset(self.as_ptr(), count) } }
584+
unsafe { NonNull { pointer: transmute(intrinsics::offset(self.as_ptr(), count)) } }
585585
}
586586

587587
/// Calculates the offset from a pointer in bytes.
@@ -605,7 +605,7 @@ impl<T: PointeeSized> NonNull<T> {
605605
// Additionally safety contract of `offset` guarantees that the resulting pointer is
606606
// pointing to an allocation, there can't be an allocation at null, thus it's safe to
607607
// construct `NonNull`.
608-
unsafe { NonNull { pointer: self.as_ptr().byte_offset(count) } }
608+
unsafe { NonNull { pointer: transmute(self.as_ptr().byte_offset(count)) } }
609609
}
610610

611611
/// Adds an offset to a pointer (convenience for `.offset(count as isize)`).
@@ -657,7 +657,7 @@ impl<T: PointeeSized> NonNull<T> {
657657
// Additionally safety contract of `offset` guarantees that the resulting pointer is
658658
// pointing to an allocation, there can't be an allocation at null, thus it's safe to
659659
// construct `NonNull`.
660-
unsafe { NonNull { pointer: intrinsics::offset(self.as_ptr(), count) } }
660+
unsafe { NonNull { pointer: transmute(intrinsics::offset(self.as_ptr(), count)) } }
661661
}
662662

663663
/// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`).
@@ -681,7 +681,7 @@ impl<T: PointeeSized> NonNull<T> {
681681
// Additionally safety contract of `add` guarantees that the resulting pointer is pointing
682682
// to an allocation, there can't be an allocation at null, thus it's safe to construct
683683
// `NonNull`.
684-
unsafe { NonNull { pointer: self.as_ptr().byte_add(count) } }
684+
unsafe { NonNull { pointer: transmute(self.as_ptr().byte_add(count)) } }
685685
}
686686

687687
/// Subtracts an offset from a pointer (convenience for
@@ -763,7 +763,7 @@ impl<T: PointeeSized> NonNull<T> {
763763
// Additionally safety contract of `sub` guarantees that the resulting pointer is pointing
764764
// to an allocation, there can't be an allocation at null, thus it's safe to construct
765765
// `NonNull`.
766-
unsafe { NonNull { pointer: self.as_ptr().byte_sub(count) } }
766+
unsafe { NonNull { pointer: transmute(self.as_ptr().byte_sub(count)) } }
767767
}
768768

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

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/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir

Lines changed: 72 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,36 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
55
debug f => _2;
66
let mut _0: ();
77
let mut _10: usize;
8-
let mut _28: std::option::Option<(usize, &T)>;
9-
let mut _31: &impl Fn(usize, &T);
10-
let mut _32: (usize, &T);
11-
let _33: ();
8+
let mut _31: std::option::Option<(usize, &T)>;
9+
let mut _34: &impl Fn(usize, &T);
10+
let mut _35: (usize, &T);
11+
let _36: ();
1212
scope 1 {
1313
debug (((iter: Enumerate<std::slice::Iter<'_, T>>).0: std::slice::Iter<'_, T>).0: std::ptr::NonNull<T>) => _6;
1414
debug (((iter: Enumerate<std::slice::Iter<'_, T>>).0: std::slice::Iter<'_, T>).1: *const T) => _9;
1515
debug (((iter: Enumerate<std::slice::Iter<'_, T>>).0: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>;
1616
debug ((iter: Enumerate<std::slice::Iter<'_, T>>).1: usize) => _10;
17-
let _29: usize;
18-
let _30: &T;
17+
let _32: usize;
18+
let _33: &T;
1919
scope 2 {
20-
debug i => _29;
21-
debug x => _30;
20+
debug i => _32;
21+
debug x => _33;
2222
}
2323
scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
24-
let mut _23: std::option::Option<&T>;
25-
let mut _26: (usize, bool);
26-
let mut _27: (usize, &T);
24+
let mut _21: std::option::Option<std::convert::Infallible>;
25+
let mut _26: std::option::Option<&T>;
26+
let mut _29: (usize, bool);
27+
let mut _30: (usize, &T);
2728
scope 19 {
28-
let _25: usize;
29+
let _28: usize;
2930
scope 24 {
3031
}
3132
}
3233
scope 20 {
3334
scope 21 {
3435
scope 27 (inlined <Option<(usize, &T)> as FromResidual<Option<Infallible>>>::from_residual) {
36+
let mut _20: isize;
37+
let mut _22: bool;
3538
}
3639
}
3740
}
@@ -40,7 +43,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
4043
}
4144
}
4245
scope 25 (inlined <Option<&T> as Try>::branch) {
43-
let _24: &T;
46+
let _27: &T;
4447
scope 26 {
4548
}
4649
}
@@ -49,8 +52,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
4952
let _11: std::ptr::NonNull<T>;
5053
let _13: std::ptr::NonNull<T>;
5154
let mut _16: bool;
52-
let mut _20: usize;
53-
let _22: &T;
55+
let mut _23: usize;
56+
let _25: &T;
5457
scope 29 {
5558
let _12: *const T;
5659
scope 30 {
@@ -78,13 +81,13 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
7881
}
7982
}
8083
scope 41 (inlined NonNull::<T>::add) {
81-
let mut _17: *const T;
84+
let mut _17: *mut T;
8285
let mut _18: *const T;
8386
scope 42 (inlined NonNull::<T>::as_ptr) {
8487
}
8588
}
8689
scope 43 (inlined NonNull::<T>::as_ref::<'_>) {
87-
let _21: *const T;
90+
let _24: *const T;
8891
scope 44 (inlined NonNull::<T>::as_ptr) {
8992
}
9093
scope 45 (inlined std::ptr::mut_ptr::<impl *mut T>::cast_const) {
@@ -169,16 +172,17 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
169172
}
170173

171174
bb4: {
175+
StorageLive(_31);
172176
StorageLive(_28);
173-
StorageLive(_25);
177+
StorageLive(_29);
174178
StorageLive(_26);
175-
StorageLive(_23);
176179
StorageLive(_11);
177180
StorageLive(_12);
178181
StorageLive(_19);
179-
StorageLive(_20);
182+
StorageLive(_23);
180183
StorageLive(_13);
181-
StorageLive(_22);
184+
StorageLive(_25);
185+
StorageLive(_14);
182186
_11 = copy _6;
183187
_12 = copy _9;
184188
switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb5, otherwise: bb8];
@@ -187,25 +191,23 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
187191
bb5: {
188192
StorageLive(_16);
189193
_13 = copy _12 as std::ptr::NonNull<T> (Transmute);
190-
StorageLive(_14);
191194
_14 = copy _11 as *mut T (Transmute);
192195
StorageLive(_15);
193196
_15 = copy _13 as *mut T (Transmute);
194197
_16 = Eq(copy _14, copy _15);
195198
StorageDead(_15);
196-
StorageDead(_14);
197199
switchInt(move _16) -> [0: bb6, otherwise: bb7];
198200
}
199201

200202
bb6: {
201203
StorageDead(_16);
202-
StorageLive(_18);
203204
StorageLive(_17);
204-
_17 = copy _11 as *const T (Transmute);
205-
_18 = Offset(copy _17, const 1_usize);
206-
StorageDead(_17);
205+
StorageLive(_18);
206+
_17 = Offset(copy _14, const 1_usize);
207+
_18 = copy _17 as *const T (PtrToPtr);
207208
_6 = NonNull::<T> { pointer: copy _18 };
208209
StorageDead(_18);
210+
StorageDead(_17);
209211
goto -> bb13;
210212
}
211213

@@ -224,16 +226,24 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
224226
}
225227

226228
bb10: {
227-
StorageDead(_22);
229+
StorageDead(_14);
230+
StorageDead(_25);
228231
StorageDead(_13);
229-
StorageDead(_20);
232+
StorageDead(_23);
230233
StorageDead(_19);
231234
StorageDead(_12);
232235
StorageDead(_11);
233-
StorageDead(_23);
234236
StorageDead(_26);
235-
StorageDead(_25);
237+
StorageLive(_20);
238+
StorageLive(_22);
239+
_20 = discriminant(_21);
240+
_22 = Eq(copy _20, const 0_isize);
241+
assume(move _22);
242+
StorageDead(_22);
243+
StorageDead(_20);
244+
StorageDead(_29);
236245
StorageDead(_28);
246+
StorageDead(_31);
237247
StorageDead(_10);
238248
drop(_2) -> [return: bb11, unwind unreachable];
239249
}
@@ -243,51 +253,52 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
243253
}
244254

245255
bb12: {
246-
_20 = SubUnchecked(copy _19, const 1_usize);
247-
_9 = copy _20 as *const T (Transmute);
256+
_23 = SubUnchecked(copy _19, const 1_usize);
257+
_9 = copy _23 as *const T (Transmute);
248258
goto -> bb13;
249259
}
250260

251261
bb13: {
252-
StorageLive(_21);
253-
_21 = copy _11 as *const T (Transmute);
254-
_22 = &(*_21);
255-
StorageDead(_21);
256-
_23 = Option::<&T>::Some(copy _22);
257-
StorageDead(_22);
262+
StorageLive(_24);
263+
_24 = copy _11 as *const T (Transmute);
264+
_25 = &(*_24);
265+
StorageDead(_24);
266+
_26 = Option::<&T>::Some(copy _25);
267+
StorageDead(_14);
268+
StorageDead(_25);
258269
StorageDead(_13);
259-
StorageDead(_20);
270+
StorageDead(_23);
260271
StorageDead(_19);
261272
StorageDead(_12);
262273
StorageDead(_11);
263-
_24 = copy ((_23 as Some).0: &T);
264-
StorageDead(_23);
265-
_25 = copy _10;
266-
_26 = AddWithOverflow(copy _10, const 1_usize);
267-
assert(!move (_26.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _10, const 1_usize) -> [success: bb14, unwind unreachable];
274+
_27 = copy ((_26 as Some).0: &T);
275+
StorageDead(_26);
276+
_28 = copy _10;
277+
_29 = AddWithOverflow(copy _10, const 1_usize);
278+
assert(!move (_29.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _10, const 1_usize) -> [success: bb14, unwind unreachable];
268279
}
269280

270281
bb14: {
271-
_10 = move (_26.0: usize);
272-
StorageLive(_27);
273-
_27 = (copy _25, copy _24);
274-
_28 = Option::<(usize, &T)>::Some(move _27);
275-
StorageDead(_27);
276-
StorageDead(_26);
277-
StorageDead(_25);
278-
_29 = copy (((_28 as Some).0: (usize, &T)).0: usize);
279-
_30 = copy (((_28 as Some).0: (usize, &T)).1: &T);
280-
StorageLive(_31);
281-
_31 = &_2;
282-
StorageLive(_32);
283-
_32 = (copy _29, copy _30);
284-
_33 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _31, move _32) -> [return: bb15, unwind unreachable];
282+
_10 = move (_29.0: usize);
283+
StorageLive(_30);
284+
_30 = (copy _28, copy _27);
285+
_31 = Option::<(usize, &T)>::Some(move _30);
286+
StorageDead(_30);
287+
StorageDead(_29);
288+
StorageDead(_28);
289+
_32 = copy (((_31 as Some).0: (usize, &T)).0: usize);
290+
_33 = copy (((_31 as Some).0: (usize, &T)).1: &T);
291+
StorageLive(_34);
292+
_34 = &_2;
293+
StorageLive(_35);
294+
_35 = (copy _32, copy _33);
295+
_36 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _34, move _35) -> [return: bb15, unwind unreachable];
285296
}
286297

287298
bb15: {
288-
StorageDead(_32);
299+
StorageDead(_35);
300+
StorageDead(_34);
289301
StorageDead(_31);
290-
StorageDead(_28);
291302
goto -> bb4;
292303
}
293304
}

0 commit comments

Comments
 (0)