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 8561678

Browse files
committedFeb 12, 2024
Expand precondition checks and improve get_unchecked errors
1 parent 1a648b3 commit 8561678

8 files changed

+208
-299
lines changed
 

‎library/core/src/panic.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -146,18 +146,25 @@ pub macro unreachable_2021 {
146146
/// not compromise unwind safety.
147147
#[doc(hidden)]
148148
#[unstable(feature = "panic_internals", issue = "none")]
149-
#[allow_internal_unstable(panic_internals, const_format_args)]
149+
#[allow_internal_unstable(panic_internals, const_format_args, delayed_debug_assertions)]
150150
#[rustc_macro_transparency = "semitransparent"]
151151
pub macro debug_assert_nounwind {
152152
($cond:expr $(,)?) => {
153-
if $crate::cfg!(debug_assertions) {
153+
if $crate::intrinsics::debug_assertions() {
154154
if !$cond {
155155
$crate::panicking::panic_nounwind($crate::concat!("assertion failed: ", $crate::stringify!($cond)));
156156
}
157157
}
158158
},
159+
($cond:expr, $message:expr) => {
160+
if $crate::intrinsics::debug_assertions() {
161+
if !$cond {
162+
$crate::panicking::panic_nounwind($message);
163+
}
164+
}
165+
},
159166
($cond:expr, $($arg:tt)+) => {
160-
if $crate::cfg!(debug_assertions) {
167+
if $crate::intrinsics::debug_assertions() {
161168
if !$cond {
162169
$crate::panicking::panic_nounwind_fmt($crate::const_format_args!($($arg)+), false);
163170
}

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

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ impl Alignment {
7676
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
7777
#[inline]
7878
pub const unsafe fn new_unchecked(align: usize) -> Self {
79+
#[cfg(debug_assertions)]
7980
crate::panic::debug_assert_nounwind!(
8081
align.is_power_of_two(),
8182
"Alignment::new_unchecked requires a power of two"

‎library/core/src/slice/index.rs

+56-29
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//! Indexing implementations for `[T]`.
22
3+
use crate::intrinsics::assert_unsafe_precondition;
34
use crate::intrinsics::const_eval_select;
45
use crate::intrinsics::unchecked_sub;
56
use crate::ops;
6-
use crate::panic::debug_assert_nounwind;
77
use crate::ptr;
88

99
#[stable(feature = "rust1", since = "1.0.0")]
@@ -225,28 +225,36 @@ unsafe impl<T> SliceIndex<[T]> for usize {
225225

226226
#[inline]
227227
unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
228-
debug_assert_nounwind!(
229-
self < slice.len(),
230-
"slice::get_unchecked requires that the index is within the slice",
231-
);
232228
// SAFETY: the caller guarantees that `slice` is not dangling, so it
233229
// cannot be longer than `isize::MAX`. They also guarantee that
234230
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
235231
// so the call to `add` is safe.
236232
unsafe {
237-
crate::hint::assert_unchecked(self < slice.len());
233+
assert_unsafe_precondition!(
234+
"slice::get_unchecked requires that the index is within the slice",
235+
(
236+
this: usize = self,
237+
len: usize = slice.len()
238+
) => this < len
239+
);
240+
crate::intrinsics::assume(self < slice.len());
238241
slice.as_ptr().add(self)
239242
}
240243
}
241244

242245
#[inline]
243246
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
244-
debug_assert_nounwind!(
245-
self < slice.len(),
246-
"slice::get_unchecked_mut requires that the index is within the slice",
247-
);
248247
// SAFETY: see comments for `get_unchecked` above.
249-
unsafe { slice.as_mut_ptr().add(self) }
248+
unsafe {
249+
assert_unsafe_precondition!(
250+
"slice::get_unchecked_mut requires that the index is within the slice",
251+
(
252+
this: usize = self,
253+
len: usize = slice.len()
254+
) => this < len
255+
);
256+
slice.as_mut_ptr().add(self)
257+
}
250258
}
251259

252260
#[inline]
@@ -290,25 +298,36 @@ unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
290298

291299
#[inline]
292300
unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
293-
debug_assert_nounwind!(
294-
self.end() <= slice.len(),
295-
"slice::get_unchecked requires that the index is within the slice"
296-
);
297301
// SAFETY: the caller guarantees that `slice` is not dangling, so it
298302
// cannot be longer than `isize::MAX`. They also guarantee that
299303
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
300304
// so the call to `add` is safe.
301-
unsafe { ptr::slice_from_raw_parts(slice.as_ptr().add(self.start()), self.len()) }
305+
unsafe {
306+
assert_unsafe_precondition!(
307+
"slice::get_unchecked requires that the index is within the slice",
308+
(
309+
end: usize = self.end(),
310+
len: usize = slice.len()
311+
) => end <= len
312+
);
313+
ptr::slice_from_raw_parts(slice.as_ptr().add(self.start()), self.len())
314+
}
302315
}
303316

304317
#[inline]
305318
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
306-
debug_assert_nounwind!(
307-
self.end() <= slice.len(),
308-
"slice::get_unchecked_mut requires that the index is within the slice",
309-
);
310319
// SAFETY: see comments for `get_unchecked` above.
311-
unsafe { ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start()), self.len()) }
320+
unsafe {
321+
assert_unsafe_precondition!(
322+
"slice::get_unchecked_mut requires that the index is within the slice",
323+
(
324+
end: usize = self.end(),
325+
len: usize = slice.len()
326+
) => end <= len
327+
);
328+
329+
ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start()), self.len())
330+
}
312331
}
313332

314333
#[inline]
@@ -359,28 +378,36 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
359378

360379
#[inline]
361380
unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
362-
debug_assert_nounwind!(
363-
self.end >= self.start && self.end <= slice.len(),
364-
"slice::get_unchecked requires that the range is within the slice",
365-
);
366381
// SAFETY: the caller guarantees that `slice` is not dangling, so it
367382
// cannot be longer than `isize::MAX`. They also guarantee that
368383
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
369384
// so the call to `add` is safe and the length calculation cannot overflow.
370385
unsafe {
386+
assert_unsafe_precondition!(
387+
"slice::get_unchecked requires that the range is within the slice",
388+
(
389+
end: usize = self.end,
390+
start: usize = self.start,
391+
len: usize = slice.len()
392+
) => end >= start && end <= len
393+
);
371394
let new_len = unchecked_sub(self.end, self.start);
372395
ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len)
373396
}
374397
}
375398

376399
#[inline]
377400
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
378-
debug_assert_nounwind!(
379-
self.end >= self.start && self.end <= slice.len(),
380-
"slice::get_unchecked_mut requires that the range is within the slice",
381-
);
382401
// SAFETY: see comments for `get_unchecked` above.
383402
unsafe {
403+
assert_unsafe_precondition!(
404+
"slice::get_unchecked_mut requires that the range is within the slice",
405+
(
406+
end: usize = self.end,
407+
start: usize = self.start,
408+
len: usize = slice.len()
409+
) => end >= start && end <= len
410+
);
384411
let new_len = unchecked_sub(self.end, self.start);
385412
ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len)
386413
}

‎tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir

+1-77
Original file line numberDiff line numberDiff line change
@@ -7,89 +7,13 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> {
77
scope 1 (inlined core::slice::<impl [u32]>::get_mut::<usize>) {
88
debug self => _1;
99
debug index => _2;
10-
scope 2 (inlined <usize as SliceIndex<[u32]>>::get_mut) {
11-
debug self => _2;
12-
debug slice => _1;
13-
let mut _3: usize;
14-
let mut _4: bool;
15-
let mut _5: *mut [u32];
16-
let mut _7: *mut u32;
17-
let mut _8: &mut u32;
18-
scope 3 {
19-
scope 4 (inlined <usize as SliceIndex<[u32]>>::get_unchecked_mut) {
20-
debug self => _2;
21-
debug slice => _5;
22-
let mut _6: *mut u32;
23-
let mut _9: *mut [u32];
24-
let mut _10: &[&str];
25-
scope 5 {
26-
scope 10 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) {
27-
debug self => _5;
28-
}
29-
scope 11 (inlined std::ptr::mut_ptr::<impl *mut u32>::add) {
30-
debug self => _6;
31-
debug count => _2;
32-
scope 12 {
33-
}
34-
}
35-
}
36-
scope 6 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::len) {
37-
debug self => _9;
38-
let mut _11: *const [u32];
39-
scope 7 (inlined std::ptr::metadata::<[u32]>) {
40-
debug ptr => _11;
41-
scope 8 {
42-
}
43-
}
44-
}
45-
scope 9 (inlined Arguments::<'_>::new_const) {
46-
debug pieces => _10;
47-
}
48-
}
49-
}
50-
}
5110
}
5211

5312
bb0: {
54-
StorageLive(_7);
55-
StorageLive(_4);
56-
StorageLive(_3);
57-
_3 = Len((*_1));
58-
_4 = Lt(_2, move _3);
59-
switchInt(move _4) -> [0: bb1, otherwise: bb2];
13+
_0 = <usize as SliceIndex<[u32]>>::get_mut(move _2, move _1) -> [return: bb1, unwind unreachable];
6014
}
6115

6216
bb1: {
63-
StorageDead(_3);
64-
_0 = const Option::<&mut u32>::None;
65-
goto -> bb3;
66-
}
67-
68-
bb2: {
69-
StorageDead(_3);
70-
StorageLive(_8);
71-
StorageLive(_5);
72-
_5 = &raw mut (*_1);
73-
StorageLive(_9);
74-
StorageLive(_10);
75-
StorageLive(_11);
76-
StorageLive(_6);
77-
_6 = _5 as *mut u32 (PtrToPtr);
78-
_7 = Offset(_6, _2);
79-
StorageDead(_6);
80-
StorageDead(_11);
81-
StorageDead(_10);
82-
StorageDead(_9);
83-
StorageDead(_5);
84-
_8 = &mut (*_7);
85-
_0 = Option::<&mut u32>::Some(move _8);
86-
StorageDead(_8);
87-
goto -> bb3;
88-
}
89-
90-
bb3: {
91-
StorageDead(_4);
92-
StorageDead(_7);
9317
return;
9418
}
9519
}

‎tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir

+1-77
Original file line numberDiff line numberDiff line change
@@ -7,89 +7,13 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> {
77
scope 1 (inlined core::slice::<impl [u32]>::get_mut::<usize>) {
88
debug self => _1;
99
debug index => _2;
10-
scope 2 (inlined <usize as SliceIndex<[u32]>>::get_mut) {
11-
debug self => _2;
12-
debug slice => _1;
13-
let mut _3: usize;
14-
let mut _4: bool;
15-
let mut _5: *mut [u32];
16-
let mut _7: *mut u32;
17-
let mut _8: &mut u32;
18-
scope 3 {
19-
scope 4 (inlined <usize as SliceIndex<[u32]>>::get_unchecked_mut) {
20-
debug self => _2;
21-
debug slice => _5;
22-
let mut _6: *mut u32;
23-
let mut _9: *mut [u32];
24-
let mut _10: &[&str];
25-
scope 5 {
26-
scope 10 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) {
27-
debug self => _5;
28-
}
29-
scope 11 (inlined std::ptr::mut_ptr::<impl *mut u32>::add) {
30-
debug self => _6;
31-
debug count => _2;
32-
scope 12 {
33-
}
34-
}
35-
}
36-
scope 6 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::len) {
37-
debug self => _9;
38-
let mut _11: *const [u32];
39-
scope 7 (inlined std::ptr::metadata::<[u32]>) {
40-
debug ptr => _11;
41-
scope 8 {
42-
}
43-
}
44-
}
45-
scope 9 (inlined Arguments::<'_>::new_const) {
46-
debug pieces => _10;
47-
}
48-
}
49-
}
50-
}
5110
}
5211

5312
bb0: {
54-
StorageLive(_7);
55-
StorageLive(_4);
56-
StorageLive(_3);
57-
_3 = Len((*_1));
58-
_4 = Lt(_2, move _3);
59-
switchInt(move _4) -> [0: bb1, otherwise: bb2];
13+
_0 = <usize as SliceIndex<[u32]>>::get_mut(move _2, move _1) -> [return: bb1, unwind continue];
6014
}
6115

6216
bb1: {
63-
StorageDead(_3);
64-
_0 = const Option::<&mut u32>::None;
65-
goto -> bb3;
66-
}
67-
68-
bb2: {
69-
StorageDead(_3);
70-
StorageLive(_8);
71-
StorageLive(_5);
72-
_5 = &raw mut (*_1);
73-
StorageLive(_9);
74-
StorageLive(_10);
75-
StorageLive(_11);
76-
StorageLive(_6);
77-
_6 = _5 as *mut u32 (PtrToPtr);
78-
_7 = Offset(_6, _2);
79-
StorageDead(_6);
80-
StorageDead(_11);
81-
StorageDead(_10);
82-
StorageDead(_9);
83-
StorageDead(_5);
84-
_8 = &mut (*_7);
85-
_0 = Option::<&mut u32>::Some(move _8);
86-
StorageDead(_8);
87-
goto -> bb3;
88-
}
89-
90-
bb3: {
91-
StorageDead(_4);
92-
StorageDead(_7);
9317
return;
9418
}
9519
}

‎tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir

+69-56
Original file line numberDiff line numberDiff line change
@@ -11,60 +11,59 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
1111
debug ((index: std::ops::Range<usize>).0: usize) => _3;
1212
debug ((index: std::ops::Range<usize>).1: usize) => _4;
1313
let mut _5: *mut [u32];
14-
let mut _13: *mut [u32];
14+
let mut _18: *mut [u32];
1515
scope 2 {
1616
scope 3 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked_mut) {
1717
debug ((self: std::ops::Range<usize>).0: usize) => _3;
1818
debug ((self: std::ops::Range<usize>).1: usize) => _4;
1919
debug slice => _5;
20-
let mut _7: *mut u32;
21-
let mut _8: *mut u32;
22-
let mut _14: *mut [u32];
23-
let mut _15: &[&str];
20+
let mut _6: bool;
21+
let mut _9: usize;
22+
let _10: ();
23+
let mut _12: *mut u32;
24+
let mut _13: *mut u32;
2425
scope 4 {
25-
let _6: usize;
26+
let _11: usize;
2627
scope 5 {
27-
debug new_len => _6;
28-
scope 10 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) {
28+
debug new_len => _11;
29+
scope 9 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) {
2930
debug self => _5;
3031
}
31-
scope 11 (inlined std::ptr::mut_ptr::<impl *mut u32>::add) {
32-
debug self => _7;
32+
scope 10 (inlined std::ptr::mut_ptr::<impl *mut u32>::add) {
33+
debug self => _12;
3334
debug count => _3;
34-
scope 12 {
35+
scope 11 {
3536
}
3637
}
37-
scope 13 (inlined slice_from_raw_parts_mut::<u32>) {
38-
debug data => _8;
39-
debug len => _6;
40-
let mut _9: *mut ();
41-
scope 14 (inlined std::ptr::mut_ptr::<impl *mut u32>::cast::<()>) {
42-
debug self => _8;
38+
scope 12 (inlined slice_from_raw_parts_mut::<u32>) {
39+
debug data => _13;
40+
debug len => _11;
41+
let mut _14: *mut ();
42+
scope 13 (inlined std::ptr::mut_ptr::<impl *mut u32>::cast::<()>) {
43+
debug self => _13;
4344
}
44-
scope 15 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
45-
debug data_pointer => _9;
46-
debug metadata => _6;
47-
let mut _10: *const ();
48-
let mut _11: std::ptr::metadata::PtrComponents<[u32]>;
49-
let mut _12: std::ptr::metadata::PtrRepr<[u32]>;
50-
scope 16 {
45+
scope 14 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
46+
debug data_pointer => _14;
47+
debug metadata => _11;
48+
let mut _15: *const ();
49+
let mut _16: std::ptr::metadata::PtrComponents<[u32]>;
50+
let mut _17: std::ptr::metadata::PtrRepr<[u32]>;
51+
scope 15 {
5152
}
5253
}
5354
}
5455
}
55-
}
56-
scope 6 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::len) {
57-
debug self => _14;
58-
let mut _16: *const [u32];
59-
scope 7 (inlined std::ptr::metadata::<[u32]>) {
60-
debug ptr => _16;
61-
scope 8 {
56+
scope 6 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::len) {
57+
debug self => _5;
58+
let mut _7: *const [u32];
59+
scope 7 (inlined std::ptr::metadata::<[u32]>) {
60+
debug ptr => _7;
61+
let mut _8: std::ptr::metadata::PtrRepr<[u32]>;
62+
scope 8 {
63+
}
6264
}
6365
}
6466
}
65-
scope 9 (inlined Arguments::<'_>::new_const) {
66-
debug pieces => _15;
67-
}
6867
}
6968
}
7069
}
@@ -74,36 +73,50 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
7473
_4 = move (_2.1: usize);
7574
StorageLive(_5);
7675
_5 = &raw mut (*_1);
77-
StorageLive(_14);
78-
StorageLive(_15);
76+
StorageLive(_9);
77+
StorageLive(_11);
7978
StorageLive(_6);
80-
StorageLive(_16);
81-
_6 = SubUnchecked(_4, _3);
82-
StorageLive(_8);
79+
_6 = cfg!(debug_assertions);
80+
switchInt(move _6) -> [0: bb2, otherwise: bb1];
81+
}
82+
83+
bb1: {
8384
StorageLive(_7);
84-
_7 = _5 as *mut u32 (PtrToPtr);
85-
_8 = Offset(_7, _3);
85+
_7 = _5 as *const [u32] (PointerCoercion(MutToConstPointer));
86+
StorageLive(_8);
87+
_8 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: _7 };
88+
_9 = ((_8.2: std::ptr::metadata::PtrComponents<[u32]>).1: usize);
89+
StorageDead(_8);
8690
StorageDead(_7);
87-
StorageLive(_9);
88-
_9 = _8 as *mut () (PtrToPtr);
91+
_10 = <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::precondition_check(_4, _3, move _9) -> [return: bb2, unwind unreachable];
92+
}
93+
94+
bb2: {
95+
StorageDead(_6);
96+
_11 = SubUnchecked(_4, _3);
97+
StorageLive(_13);
8998
StorageLive(_12);
90-
StorageLive(_11);
91-
StorageLive(_10);
92-
_10 = _8 as *const () (PtrToPtr);
93-
_11 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: move _10, metadata: _6 };
94-
StorageDead(_10);
95-
_12 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _11 };
96-
StorageDead(_11);
97-
_13 = (_12.1: *mut [u32]);
99+
_12 = _5 as *mut u32 (PtrToPtr);
100+
_13 = Offset(_12, _3);
98101
StorageDead(_12);
99-
StorageDead(_9);
100-
StorageDead(_8);
101-
StorageDead(_16);
102-
StorageDead(_6);
102+
StorageLive(_14);
103+
_14 = _13 as *mut () (PtrToPtr);
104+
StorageLive(_17);
105+
StorageLive(_16);
106+
StorageLive(_15);
107+
_15 = _13 as *const () (PtrToPtr);
108+
_16 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: move _15, metadata: _11 };
103109
StorageDead(_15);
110+
_17 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _16 };
111+
StorageDead(_16);
112+
_18 = (_17.1: *mut [u32]);
113+
StorageDead(_17);
104114
StorageDead(_14);
115+
StorageDead(_13);
116+
StorageDead(_11);
117+
StorageDead(_9);
105118
StorageDead(_5);
106-
_0 = &mut (*_13);
119+
_0 = &mut (*_18);
107120
return;
108121
}
109122
}

‎tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir

+69-56
Original file line numberDiff line numberDiff line change
@@ -11,60 +11,59 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
1111
debug ((index: std::ops::Range<usize>).0: usize) => _3;
1212
debug ((index: std::ops::Range<usize>).1: usize) => _4;
1313
let mut _5: *mut [u32];
14-
let mut _13: *mut [u32];
14+
let mut _18: *mut [u32];
1515
scope 2 {
1616
scope 3 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked_mut) {
1717
debug ((self: std::ops::Range<usize>).0: usize) => _3;
1818
debug ((self: std::ops::Range<usize>).1: usize) => _4;
1919
debug slice => _5;
20-
let mut _7: *mut u32;
21-
let mut _8: *mut u32;
22-
let mut _14: *mut [u32];
23-
let mut _15: &[&str];
20+
let mut _6: bool;
21+
let mut _9: usize;
22+
let _10: ();
23+
let mut _12: *mut u32;
24+
let mut _13: *mut u32;
2425
scope 4 {
25-
let _6: usize;
26+
let _11: usize;
2627
scope 5 {
27-
debug new_len => _6;
28-
scope 10 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) {
28+
debug new_len => _11;
29+
scope 9 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) {
2930
debug self => _5;
3031
}
31-
scope 11 (inlined std::ptr::mut_ptr::<impl *mut u32>::add) {
32-
debug self => _7;
32+
scope 10 (inlined std::ptr::mut_ptr::<impl *mut u32>::add) {
33+
debug self => _12;
3334
debug count => _3;
34-
scope 12 {
35+
scope 11 {
3536
}
3637
}
37-
scope 13 (inlined slice_from_raw_parts_mut::<u32>) {
38-
debug data => _8;
39-
debug len => _6;
40-
let mut _9: *mut ();
41-
scope 14 (inlined std::ptr::mut_ptr::<impl *mut u32>::cast::<()>) {
42-
debug self => _8;
38+
scope 12 (inlined slice_from_raw_parts_mut::<u32>) {
39+
debug data => _13;
40+
debug len => _11;
41+
let mut _14: *mut ();
42+
scope 13 (inlined std::ptr::mut_ptr::<impl *mut u32>::cast::<()>) {
43+
debug self => _13;
4344
}
44-
scope 15 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
45-
debug data_pointer => _9;
46-
debug metadata => _6;
47-
let mut _10: *const ();
48-
let mut _11: std::ptr::metadata::PtrComponents<[u32]>;
49-
let mut _12: std::ptr::metadata::PtrRepr<[u32]>;
50-
scope 16 {
45+
scope 14 (inlined std::ptr::from_raw_parts_mut::<[u32]>) {
46+
debug data_pointer => _14;
47+
debug metadata => _11;
48+
let mut _15: *const ();
49+
let mut _16: std::ptr::metadata::PtrComponents<[u32]>;
50+
let mut _17: std::ptr::metadata::PtrRepr<[u32]>;
51+
scope 15 {
5152
}
5253
}
5354
}
5455
}
55-
}
56-
scope 6 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::len) {
57-
debug self => _14;
58-
let mut _16: *const [u32];
59-
scope 7 (inlined std::ptr::metadata::<[u32]>) {
60-
debug ptr => _16;
61-
scope 8 {
56+
scope 6 (inlined std::ptr::mut_ptr::<impl *mut [u32]>::len) {
57+
debug self => _5;
58+
let mut _7: *const [u32];
59+
scope 7 (inlined std::ptr::metadata::<[u32]>) {
60+
debug ptr => _7;
61+
let mut _8: std::ptr::metadata::PtrRepr<[u32]>;
62+
scope 8 {
63+
}
6264
}
6365
}
6466
}
65-
scope 9 (inlined Arguments::<'_>::new_const) {
66-
debug pieces => _15;
67-
}
6867
}
6968
}
7069
}
@@ -74,36 +73,50 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
7473
_4 = move (_2.1: usize);
7574
StorageLive(_5);
7675
_5 = &raw mut (*_1);
77-
StorageLive(_14);
78-
StorageLive(_15);
76+
StorageLive(_9);
77+
StorageLive(_11);
7978
StorageLive(_6);
80-
StorageLive(_16);
81-
_6 = SubUnchecked(_4, _3);
82-
StorageLive(_8);
79+
_6 = cfg!(debug_assertions);
80+
switchInt(move _6) -> [0: bb2, otherwise: bb1];
81+
}
82+
83+
bb1: {
8384
StorageLive(_7);
84-
_7 = _5 as *mut u32 (PtrToPtr);
85-
_8 = Offset(_7, _3);
85+
_7 = _5 as *const [u32] (PointerCoercion(MutToConstPointer));
86+
StorageLive(_8);
87+
_8 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: _7 };
88+
_9 = ((_8.2: std::ptr::metadata::PtrComponents<[u32]>).1: usize);
89+
StorageDead(_8);
8690
StorageDead(_7);
87-
StorageLive(_9);
88-
_9 = _8 as *mut () (PtrToPtr);
91+
_10 = <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::precondition_check(_4, _3, move _9) -> [return: bb2, unwind unreachable];
92+
}
93+
94+
bb2: {
95+
StorageDead(_6);
96+
_11 = SubUnchecked(_4, _3);
97+
StorageLive(_13);
8998
StorageLive(_12);
90-
StorageLive(_11);
91-
StorageLive(_10);
92-
_10 = _8 as *const () (PtrToPtr);
93-
_11 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: move _10, metadata: _6 };
94-
StorageDead(_10);
95-
_12 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _11 };
96-
StorageDead(_11);
97-
_13 = (_12.1: *mut [u32]);
99+
_12 = _5 as *mut u32 (PtrToPtr);
100+
_13 = Offset(_12, _3);
98101
StorageDead(_12);
99-
StorageDead(_9);
100-
StorageDead(_8);
101-
StorageDead(_16);
102-
StorageDead(_6);
102+
StorageLive(_14);
103+
_14 = _13 as *mut () (PtrToPtr);
104+
StorageLive(_17);
105+
StorageLive(_16);
106+
StorageLive(_15);
107+
_15 = _13 as *const () (PtrToPtr);
108+
_16 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: move _15, metadata: _11 };
103109
StorageDead(_15);
110+
_17 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _16 };
111+
StorageDead(_16);
112+
_18 = (_17.1: *mut [u32]);
113+
StorageDead(_17);
104114
StorageDead(_14);
115+
StorageDead(_13);
116+
StorageDead(_11);
117+
StorageDead(_9);
105118
StorageDead(_5);
106-
_0 = &mut (*_13);
119+
_0 = &mut (*_18);
107120
return;
108121
}
109122
}

‎tests/ui/precondition-checks/out-of-bounds-get-unchecked.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// run-fail
22
// compile-flags: -Copt-level=3 -Cdebug-assertions=yes
3-
// error-pattern: unsafe precondition(s) violated: hint::assert_unchecked
3+
// error-pattern: unsafe precondition(s) violated: slice::get_unchecked requires
44
// ignore-debug
55
// ignore-wasm32-bare no panic messages
66

0 commit comments

Comments
 (0)
Please sign in to comment.