@@ -940,6 +940,7 @@ where
940
940
F : FnMut ( & T , & T ) -> bool ,
941
941
{
942
942
if v. len ( ) >= 2 && is_less ( & v[ 1 ] , & v[ 0 ] ) {
943
+ // SAFETY: Copy tmp back even if panic, and ensure unique observation.
943
944
unsafe {
944
945
// There are three ways to implement insertion here:
945
946
//
@@ -992,6 +993,7 @@ where
992
993
993
994
impl < T > Drop for InsertionHole < T > {
994
995
fn drop ( & mut self ) {
996
+ // SAFETY: The caller must ensure that src and dest are correctly set.
995
997
unsafe {
996
998
ptr:: copy_nonoverlapping ( self . src , self . dest , 1 ) ;
997
999
}
@@ -1012,6 +1014,8 @@ where
1012
1014
{
1013
1015
let len = v. len ( ) ;
1014
1016
let v = v. as_mut_ptr ( ) ;
1017
+
1018
+ // SAFETY: mid and len must be in-bounds of v.
1015
1019
let ( v_mid, v_end) = unsafe { ( v. add ( mid) , v. add ( len) ) } ;
1016
1020
1017
1021
// The merge process first copies the shorter run into `buf`. Then it traces the newly copied
@@ -1035,6 +1039,8 @@ where
1035
1039
1036
1040
if mid <= len - mid {
1037
1041
// The left run is shorter.
1042
+
1043
+ // SAFETY: buf must have enough capacity for `v[..mid]`.
1038
1044
unsafe {
1039
1045
ptr:: copy_nonoverlapping ( v, buf, mid) ;
1040
1046
hole = MergeHole { start : buf, end : buf. add ( mid) , dest : v } ;
@@ -1048,6 +1054,8 @@ where
1048
1054
while * left < hole. end && right < v_end {
1049
1055
// Consume the lesser side.
1050
1056
// If equal, prefer the left run to maintain stability.
1057
+
1058
+ // SAFETY: left and right must be valid and part of v same for out.
1051
1059
unsafe {
1052
1060
let to_copy = if is_less ( & * right, & * * left) {
1053
1061
get_and_increment ( & mut right)
@@ -1059,6 +1067,8 @@ where
1059
1067
}
1060
1068
} else {
1061
1069
// The right run is shorter.
1070
+
1071
+ // SAFETY: buf must have enough capacity for `v[mid..]`.
1062
1072
unsafe {
1063
1073
ptr:: copy_nonoverlapping ( v_mid, buf, len - mid) ;
1064
1074
hole = MergeHole { start : buf, end : buf. add ( len - mid) , dest : v_mid } ;
@@ -1072,6 +1082,8 @@ where
1072
1082
while v < * left && buf < * right {
1073
1083
// Consume the greater side.
1074
1084
// If equal, prefer the right run to maintain stability.
1085
+
1086
+ // SAFETY: left and right must be valid and part of v same for out.
1075
1087
unsafe {
1076
1088
let to_copy = if is_less ( & * right. sub ( 1 ) , & * left. sub ( 1 ) ) {
1077
1089
decrement_and_get ( left)
@@ -1087,11 +1099,14 @@ where
1087
1099
1088
1100
unsafe fn get_and_increment < T > ( ptr : & mut * mut T ) -> * mut T {
1089
1101
let old = * ptr;
1102
+
1103
+ // SAFETY: ptr.add(1) must still be a valid pointer and part of `v`.
1090
1104
* ptr = unsafe { ptr. add ( 1 ) } ;
1091
1105
old
1092
1106
}
1093
1107
1094
1108
unsafe fn decrement_and_get < T > ( ptr : & mut * mut T ) -> * mut T {
1109
+ // SAFETY: ptr.sub(1) must still be a valid pointer and part of `v`.
1095
1110
* ptr = unsafe { ptr. sub ( 1 ) } ;
1096
1111
* ptr
1097
1112
}
@@ -1105,7 +1120,7 @@ where
1105
1120
1106
1121
impl < T > Drop for MergeHole < T > {
1107
1122
fn drop ( & mut self ) {
1108
- // `T` is not a zero-sized type, and these are pointers into a slice's elements.
1123
+ // SAFETY: `T` is not a zero-sized type, and these are pointers into a slice's elements.
1109
1124
unsafe {
1110
1125
let len = self . end . sub_ptr ( self . start ) ;
1111
1126
ptr:: copy_nonoverlapping ( self . start , self . dest , len) ;
@@ -1180,6 +1195,8 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
1180
1195
let mut start = end - 1 ;
1181
1196
if start > 0 {
1182
1197
start -= 1 ;
1198
+
1199
+ // SAFETY: The v.get_unchecked must be fed with correct inbound indicies.
1183
1200
unsafe {
1184
1201
if is_less ( v. get_unchecked ( start + 1 ) , v. get_unchecked ( start) ) {
1185
1202
while start > 0 && is_less ( v. get_unchecked ( start) , v. get_unchecked ( start - 1 ) ) {
@@ -1210,6 +1227,8 @@ pub fn merge_sort<T, CmpF, ElemAllocF, ElemDeallocF, RunAllocF, RunDeallocF>(
1210
1227
while let Some ( r) = collapse ( runs. as_slice ( ) ) {
1211
1228
let left = runs[ r + 1 ] ;
1212
1229
let right = runs[ r] ;
1230
+ // SAFETY: `buf_ptr` must hold enough capacity for the shorter of the two sides, and
1231
+ // neither side may be on length 0.
1213
1232
unsafe {
1214
1233
merge ( & mut v[ left. start ..right. start + right. len ] , left. len , buf_ptr, is_less) ;
1215
1234
}
0 commit comments