Apply review comments · model-checking/verify-rust-std@83c530f (original) (raw)

`@@ -61,91 +61,91 @@ pub fn merge<T, F: FnMut(&T, &T) -> bool>(

`

61

61

`` // Finally, merge_state gets dropped. If the shorter run was not fully

``

62

62

`` // consumed, whatever remains of it will now be copied into the hole in v.

``

63

63

`}

`

``

64

`+

}

`

64

65

``

65

``

`` -

// When dropped, copies the range start..end into dst...

``

66

``

`-

struct MergeState {

`

67

``

`-

start: *mut T,

`

68

``

`-

end: *mut T,

`

69

``

`-

dst: *mut T,

`

70

``

`-

}

`

``

66

`` +

// When dropped, copies the range start..end into dst...

``

``

67

`+

struct MergeState {

`

``

68

`+

start: *mut T,

`

``

69

`+

end: *mut T,

`

``

70

`+

dst: *mut T,

`

``

71

`+

}

`

71

72

``

72

``

`-

impl MergeState {

`

73

``

`-

/// # Safety

`

74

``

`` -

/// The caller MUST guarantee that self is initialized in a way where start -> end is

``

75

``

`` -

/// the longer sub-slice and so that dst can be written to at least the shorter sub-slice

``

76

``

`` -

/// length times. In addition start -> end and right -> right_end MUST be valid to be

``

77

``

`-

/// read. This function MUST only be called once.

`

78

``

`-

unsafe fn merge_up<F: FnMut(&T, &T) -> bool>(

`

79

``

`-

&mut self,

`

80

``

`-

mut right: *const T,

`

81

``

`-

right_end: *const T,

`

82

``

`-

is_less: &mut F,

`

83

``

`-

) {

`

84

``

`-

// SAFETY: See function safety comment.

`

85

``

`-

unsafe {

`

86

``

`-

let left = &mut self.start;

`

87

``

`-

let out = &mut self.dst;

`

88

``

-

89

``

`-

while *left != self.end && right as *const T != right_end {

`

90

``

`-

let consume_left = !is_less(&*right, &**left);

`

91

``

-

92

``

`-

let src = if consume_left { *left } else { right };

`

93

``

`-

ptr::copy_nonoverlapping(src, *out, 1);

`

94

``

-

95

``

`-

*left = left.add(consume_left as usize);

`

96

``

`-

right = right.add(!consume_left as usize);

`

97

``

-

98

``

`-

*out = out.add(1);

`

99

``

`-

}

`

``

73

`+

impl MergeState {

`

``

74

`+

/// # Safety

`

``

75

`` +

/// The caller MUST guarantee that self is initialized in a way where start -> end is

``

``

76

`` +

/// the longer sub-slice and so that dst can be written to at least the shorter sub-slice

``

``

77

`` +

/// length times. In addition start -> end and right -> right_end MUST be valid to be

``

``

78

`+

/// read. This function MUST only be called once.

`

``

79

`+

unsafe fn merge_up<F: FnMut(&T, &T) -> bool>(

`

``

80

`+

&mut self,

`

``

81

`+

mut right: *const T,

`

``

82

`+

right_end: *const T,

`

``

83

`+

is_less: &mut F,

`

``

84

`+

) {

`

``

85

`+

// SAFETY: See function safety comment.

`

``

86

`+

unsafe {

`

``

87

`+

let left = &mut self.start;

`

``

88

`+

let out = &mut self.dst;

`

``

89

+

``

90

`+

while *left != self.end && right as *const T != right_end {

`

``

91

`+

let consume_left = !is_less(&*right, &**left);

`

``

92

+

``

93

`+

let src = if consume_left { *left } else { right };

`

``

94

`+

ptr::copy_nonoverlapping(src, *out, 1);

`

``

95

+

``

96

`+

*left = left.add(consume_left as usize);

`

``

97

`+

right = right.add(!consume_left as usize);

`

``

98

+

``

99

`+

*out = out.add(1);

`

100

100

`}

`

101

101

`}

`

``

102

`+

}

`

102

103

``

103

``

`-

/// # Safety

`

104

``

`` -

/// The caller MUST guarantee that self is initialized in a way where left_end <- dst is

``

105

``

`` -

/// the shorter sub-slice and so that out can be written to at least the shorter sub-slice

``

106

``

`` -

/// length times. In addition left_end <- dst and right_end <- end MUST be valid to be

``

107

``

`-

/// read. This function MUST only be called once.

`

108

``

`-

unsafe fn merge_down<F: FnMut(&T, &T) -> bool>(

`

109

``

`-

&mut self,

`

110

``

`-

left_end: *const T,

`

111

``

`-

right_end: *const T,

`

112

``

`-

mut out: *mut T,

`

113

``

`-

is_less: &mut F,

`

114

``

`-

) {

`

115

``

`-

// SAFETY: See function safety comment.

`

116

``

`-

unsafe {

`

117

``

`-

loop {

`

118

``

`-

let left = self.dst.sub(1);

`

119

``

`-

let right = self.end.sub(1);

`

120

``

`-

out = out.sub(1);

`

121

``

-

122

``

`-

let consume_left = is_less(&*right, &*left);

`

123

``

-

124

``

`-

let src = if consume_left { left } else { right };

`

125

``

`-

ptr::copy_nonoverlapping(src, out, 1);

`

126

``

-

127

``

`-

self.dst = left.add(!consume_left as usize);

`

128

``

`-

self.end = right.add(consume_left as usize);

`

129

``

-

130

``

`-

if self.dst as *const T == left_end || self.end as *const T == right_end {

`

131

``

`-

break;

`

132

``

`-

}

`

``

104

`+

/// # Safety

`

``

105

`` +

/// The caller MUST guarantee that self is initialized in a way where left_end <- dst is

``

``

106

`` +

/// the shorter sub-slice and so that out can be written to at least the shorter sub-slice

``

``

107

`` +

/// length times. In addition left_end <- dst and right_end <- end MUST be valid to be

``

``

108

`+

/// read. This function MUST only be called once.

`

``

109

`+

unsafe fn merge_down<F: FnMut(&T, &T) -> bool>(

`

``

110

`+

&mut self,

`

``

111

`+

left_end: *const T,

`

``

112

`+

right_end: *const T,

`

``

113

`+

mut out: *mut T,

`

``

114

`+

is_less: &mut F,

`

``

115

`+

) {

`

``

116

`+

// SAFETY: See function safety comment.

`

``

117

`+

unsafe {

`

``

118

`+

loop {

`

``

119

`+

let left = self.dst.sub(1);

`

``

120

`+

let right = self.end.sub(1);

`

``

121

`+

out = out.sub(1);

`

``

122

+

``

123

`+

let consume_left = is_less(&*right, &*left);

`

``

124

+

``

125

`+

let src = if consume_left { left } else { right };

`

``

126

`+

ptr::copy_nonoverlapping(src, out, 1);

`

``

127

+

``

128

`+

self.dst = left.add(!consume_left as usize);

`

``

129

`+

self.end = right.add(consume_left as usize);

`

``

130

+

``

131

`+

if self.dst as *const T == left_end || self.end as *const T == right_end {

`

``

132

`+

break;

`

133

133

`}

`

134

134

`}

`

135

135

`}

`

136

136

`}

`

``

137

`+

}

`

137

138

``

138

``

`-

impl Drop for MergeState {

`

139

``

`-

fn drop(&mut self) {

`

140

``

`-

// SAFETY: The user of MergeState MUST ensure, that at any point this drop

`

141

``

`` -

// impl MAY run, for example when the user provided is_less panics, that

``

142

``

`` -

// copying the contiguous region between start and end to dst will

``

143

``

`` -

// leave the input slice v with each original element and all possible

``

144

``

`-

// modifications observed.

`

145

``

`-

unsafe {

`

146

``

`-

let len = self.end.sub_ptr(self.start);

`

147

``

`-

ptr::copy_nonoverlapping(self.start, self.dst, len);

`

148

``

`-

}

`

``

139

`+

impl Drop for MergeState {

`

``

140

`+

fn drop(&mut self) {

`

``

141

`+

// SAFETY: The user of MergeState MUST ensure, that at any point this drop

`

``

142

`` +

// impl MAY run, for example when the user provided is_less panics, that

``

``

143

`` +

// copying the contiguous region between start and end to dst will

``

``

144

`` +

// leave the input slice v with each original element and all possible

``

``

145

`+

// modifications observed.

`

``

146

`+

unsafe {

`

``

147

`+

let len = self.end.sub_ptr(self.start);

`

``

148

`+

ptr::copy_nonoverlapping(self.start, self.dst, len);

`

149

149

`}

`

150

150

`}

`

151

151

`}

`