Skip to content

Commit 871ab4c

Browse files
committed
Call NonNull::new_unchecked less
1 parent 4fca9b8 commit 871ab4c

11 files changed

+932
-301
lines changed

library/alloc/src/vec/into_iter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ impl<T, A: Allocator> IntoIter<T, A> {
136136
// struct and then overwriting &mut self.
137137
// this creates less assembly
138138
self.cap = 0;
139-
self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
139+
self.buf = RawVec::NEW.non_null();
140140
self.ptr = self.buf;
141141
self.end = self.buf.as_ptr();
142142

library/core/src/ptr/non_null.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ impl<T: ?Sized> NonNull<T> {
473473
#[inline]
474474
pub const fn cast<U>(self) -> NonNull<U> {
475475
// SAFETY: `self` is a `NonNull` pointer which is necessarily non-null
476-
unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) }
476+
unsafe { NonNull { pointer: self.as_ptr() as *mut U } }
477477
}
478478

479479
/// Calculates the offset from a pointer.
@@ -1828,8 +1828,7 @@ impl<T: ?Sized> hash::Hash for NonNull<T> {
18281828
impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
18291829
#[inline]
18301830
fn from(unique: Unique<T>) -> Self {
1831-
// SAFETY: A Unique pointer cannot be null, so the conditions for
1832-
// new_unchecked() are respected.
1831+
// SAFETY: A Unique pointer cannot be null.
18331832
unsafe { NonNull { pointer: unique.as_ptr() } }
18341833
}
18351834
}
@@ -1853,8 +1852,7 @@ impl<T: ?Sized> From<&T> for NonNull<T> {
18531852
/// This conversion is safe and infallible since references cannot be null.
18541853
#[inline]
18551854
fn from(reference: &T) -> Self {
1856-
// SAFETY: A reference cannot be null, so the conditions for
1857-
// new_unchecked() are respected.
1855+
// SAFETY: A reference cannot be null.
18581856
unsafe { NonNull { pointer: reference as *const T } }
18591857
}
18601858
}

library/core/src/ptr/unique.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ impl<T: ?Sized> Unique<T> {
138138
pub const fn cast<U>(self) -> Unique<U> {
139139
// FIXME(const-hack): replace with `From`
140140
// SAFETY: is `NonNull`
141-
unsafe { Unique::new_unchecked(self.pointer.cast().as_ptr()) }
141+
Unique { pointer: self.pointer.cast(), _marker: PhantomData }
142142
}
143143
}
144144

library/core/src/slice/iter.rs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,8 @@ unsafe impl<T: Sync> Send for Iter<'_, T> {}
8787
impl<'a, T> Iter<'a, T> {
8888
#[inline]
8989
pub(super) fn new(slice: &'a [T]) -> Self {
90-
let ptr = slice.as_ptr();
91-
// SAFETY: Similar to `IterMut::new`.
92-
unsafe {
93-
let end_or_len = if T::IS_ZST { invalid(slice.len()) } else { ptr.add(slice.len()) };
94-
95-
Self { ptr: NonNull::new_unchecked(ptr as *mut T), end_or_len, _marker: PhantomData }
96-
}
90+
let end_or_len = if T::IS_ZST { invalid(slice.len()) } else { slice.as_ptr_range().end };
91+
Self { ptr: NonNull::from(slice).cast(), end_or_len, _marker: PhantomData }
9792
}
9893

9994
/// Views the underlying data as a subslice of the original data.
@@ -208,13 +203,6 @@ unsafe impl<T: Send> Send for IterMut<'_, T> {}
208203
impl<'a, T> IterMut<'a, T> {
209204
#[inline]
210205
pub(super) fn new(slice: &'a mut [T]) -> Self {
211-
let ptr = slice.as_mut_ptr();
212-
// SAFETY: There are several things here:
213-
//
214-
// `ptr` has been obtained by `slice.as_ptr()` where `slice` is a valid
215-
// reference thus it is non-NUL and safe to use and pass to
216-
// `NonNull::new_unchecked` .
217-
//
218206
// Adding `slice.len()` to the starting pointer gives a pointer
219207
// at the end of `slice`. `end` will never be dereferenced, only checked
220208
// for direct pointer equality with `ptr` to check if the iterator is
@@ -225,12 +213,9 @@ impl<'a, T> IterMut<'a, T> {
225213
//
226214
// See the `next_unchecked!` and `is_empty!` macros as well as the
227215
// `post_inc_start` method for more information.
228-
unsafe {
229-
let end_or_len =
230-
if T::IS_ZST { invalid_mut(slice.len()) } else { ptr.add(slice.len()) };
231-
232-
Self { ptr: NonNull::new_unchecked(ptr), end_or_len, _marker: PhantomData }
233-
}
216+
let end_or_len =
217+
if T::IS_ZST { invalid_mut(slice.len()) } else { slice.as_mut_ptr_range().end };
218+
Self { ptr: NonNull::from(slice).cast(), end_or_len, _marker: PhantomData }
234219
}
235220

236221
/// Views the underlying data as a subslice of the original data.

tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir

Lines changed: 155 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,91 +4,199 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
44
debug slice => _1;
55
debug f => _2;
66
let mut _0: ();
7-
let mut _3: std::slice::Iter<'_, T>;
8-
let mut _4: std::iter::Enumerate<std::slice::Iter<'_, T>>;
9-
let mut _5: std::iter::Enumerate<std::slice::Iter<'_, T>>;
10-
let mut _6: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
11-
let mut _7: std::option::Option<(usize, &T)>;
12-
let mut _8: isize;
13-
let mut _11: &impl Fn(usize, &T);
14-
let mut _12: (usize, &T);
15-
let _13: ();
7+
let mut _17: std::slice::Iter<'_, T>;
8+
let mut _18: std::iter::Enumerate<std::slice::Iter<'_, T>>;
9+
let mut _19: std::iter::Enumerate<std::slice::Iter<'_, T>>;
10+
let mut _20: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
11+
let mut _21: std::option::Option<(usize, &T)>;
12+
let mut _22: isize;
13+
let mut _25: &impl Fn(usize, &T);
14+
let mut _26: (usize, &T);
15+
let _27: ();
1616
scope 1 {
17-
debug iter => _5;
18-
let _9: usize;
19-
let _10: &T;
17+
debug iter => _19;
18+
let _23: usize;
19+
let _24: &T;
2020
scope 2 {
21-
debug i => _9;
22-
debug x => _10;
21+
debug i => _23;
22+
debug x => _24;
2323
}
2424
}
2525
scope 3 (inlined core::slice::<impl [T]>::iter) {
2626
debug self => _1;
27+
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
28+
debug slice => _1;
29+
let mut _3: bool;
30+
let _8: *const T;
31+
let mut _9: usize;
32+
let mut _11: std::ptr::NonNull<[T]>;
33+
let mut _15: std::ptr::NonNull<T>;
34+
let mut _16: *const T;
35+
scope 5 {
36+
debug end_or_len => _8;
37+
scope 15 (inlined <NonNull<[T]> as From<&[T]>>::from) {
38+
debug reference => _1;
39+
let mut _10: *const [T];
40+
scope 16 {
41+
}
42+
}
43+
scope 17 (inlined NonNull::<[T]>::cast::<T>) {
44+
debug self => _11;
45+
let mut _12: *mut [T];
46+
let mut _13: *mut T;
47+
let mut _14: *const T;
48+
scope 18 {
49+
scope 19 (inlined NonNull::<[T]>::as_ptr) {
50+
debug self => _11;
51+
}
52+
}
53+
}
54+
}
55+
scope 6 (inlined invalid::<T>) {
56+
debug addr => _9;
57+
scope 7 {
58+
}
59+
}
60+
scope 8 (inlined core::slice::<impl [T]>::as_ptr_range) {
61+
debug self => _1;
62+
let _5: *const T;
63+
let mut _6: usize;
64+
scope 9 {
65+
debug start => _5;
66+
let _7: *const T;
67+
scope 10 {
68+
debug end => _7;
69+
}
70+
scope 11 {
71+
scope 13 (inlined std::ptr::const_ptr::<impl *const T>::add) {
72+
debug self => _5;
73+
debug count => _6;
74+
scope 14 {
75+
}
76+
}
77+
}
78+
}
79+
scope 12 (inlined core::slice::<impl [T]>::as_ptr) {
80+
debug self => _1;
81+
let mut _4: *const [T];
82+
}
83+
}
84+
}
2785
}
28-
scope 4 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
29-
debug self => _3;
30-
scope 5 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
31-
debug iter => _3;
86+
scope 20 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
87+
debug self => _17;
88+
scope 21 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
89+
debug iter => _17;
3290
}
3391
}
34-
scope 6 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
35-
debug self => _4;
92+
scope 22 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
93+
debug self => _18;
3694
}
3795

3896
bb0: {
97+
StorageLive(_17);
98+
StorageLive(_10);
99+
StorageLive(_8);
39100
StorageLive(_3);
40-
_3 = std::slice::Iter::<'_, T>::new(move _1) -> [return: bb1, unwind unreachable];
101+
_3 = const _;
102+
switchInt(move _3) -> [0: bb1, otherwise: bb2];
41103
}
42104

43105
bb1: {
44-
_4 = Enumerate::<std::slice::Iter<'_, T>> { iter: _3, count: const 0_usize };
45-
StorageDead(_3);
46106
StorageLive(_5);
47-
_5 = _4;
48-
goto -> bb2;
107+
StorageLive(_4);
108+
_4 = &raw const (*_1);
109+
_5 = move _4 as *const T (PtrToPtr);
110+
StorageDead(_4);
111+
StorageLive(_6);
112+
_6 = Len((*_1));
113+
_7 = Offset(_5, _6);
114+
StorageDead(_6);
115+
StorageDead(_5);
116+
_8 = _7;
117+
goto -> bb3;
49118
}
50119

51120
bb2: {
52-
StorageLive(_7);
53-
StorageLive(_6);
54-
_6 = &mut _5;
55-
_7 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _6) -> [return: bb3, unwind unreachable];
121+
StorageLive(_9);
122+
_9 = Len((*_1));
123+
_8 = _9 as *const T (Transmute);
124+
StorageDead(_9);
125+
goto -> bb3;
56126
}
57127

58128
bb3: {
59-
StorageDead(_6);
60-
_8 = discriminant(_7);
61-
switchInt(move _8) -> [0: bb4, 1: bb6, otherwise: bb8];
129+
StorageDead(_3);
130+
StorageLive(_15);
131+
StorageLive(_11);
132+
_10 = &raw const (*_1);
133+
_11 = NonNull::<[T]> { pointer: _10 };
134+
StorageLive(_14);
135+
StorageLive(_13);
136+
StorageLive(_12);
137+
_12 = _10 as *mut [T] (PtrToPtr);
138+
_13 = move _12 as *mut T (PtrToPtr);
139+
_14 = move _13 as *const T (PointerCoercion(MutToConstPointer));
140+
StorageDead(_12);
141+
StorageDead(_13);
142+
_15 = NonNull::<T> { pointer: move _14 };
143+
StorageDead(_14);
144+
StorageDead(_11);
145+
StorageLive(_16);
146+
_16 = _8;
147+
_17 = std::slice::Iter::<'_, T> { ptr: move _15, end_or_len: move _16, _marker: const ZeroSized: PhantomData<&T> };
148+
StorageDead(_16);
149+
StorageDead(_15);
150+
StorageDead(_8);
151+
StorageDead(_10);
152+
_18 = Enumerate::<std::slice::Iter<'_, T>> { iter: _17, count: const 0_usize };
153+
StorageDead(_17);
154+
StorageLive(_19);
155+
_19 = _18;
156+
goto -> bb4;
62157
}
63158

64159
bb4: {
65-
StorageDead(_7);
66-
StorageDead(_5);
67-
drop(_2) -> [return: bb5, unwind unreachable];
160+
StorageLive(_21);
161+
StorageLive(_20);
162+
_20 = &mut _19;
163+
_21 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _20) -> [return: bb5, unwind unreachable];
68164
}
69165

70166
bb5: {
71-
return;
167+
StorageDead(_20);
168+
_22 = discriminant(_21);
169+
switchInt(move _22) -> [0: bb6, 1: bb8, otherwise: bb10];
72170
}
73171

74172
bb6: {
75-
_9 = (((_7 as Some).0: (usize, &T)).0: usize);
76-
_10 = (((_7 as Some).0: (usize, &T)).1: &T);
77-
StorageLive(_11);
78-
_11 = &_2;
79-
StorageLive(_12);
80-
_12 = (_9, _10);
81-
_13 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _11, move _12) -> [return: bb7, unwind unreachable];
173+
StorageDead(_21);
174+
StorageDead(_19);
175+
drop(_2) -> [return: bb7, unwind unreachable];
82176
}
83177

84178
bb7: {
85-
StorageDead(_12);
86-
StorageDead(_11);
87-
StorageDead(_7);
88-
goto -> bb2;
179+
return;
89180
}
90181

91182
bb8: {
183+
_23 = (((_21 as Some).0: (usize, &T)).0: usize);
184+
_24 = (((_21 as Some).0: (usize, &T)).1: &T);
185+
StorageLive(_25);
186+
_25 = &_2;
187+
StorageLive(_26);
188+
_26 = (_23, _24);
189+
_27 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _25, move _26) -> [return: bb9, unwind unreachable];
190+
}
191+
192+
bb9: {
193+
StorageDead(_26);
194+
StorageDead(_25);
195+
StorageDead(_21);
196+
goto -> bb4;
197+
}
198+
199+
bb10: {
92200
unreachable;
93201
}
94202
}

0 commit comments

Comments
 (0)