Remove reliance on const_trait in sort implementations · model-checking/verify-rust-std@489dfce (original) (raw)

`@@ -93,10 +93,62 @@ impl UnstableSmallSortTypeImpl for T {

`

93

93

`impl<T: FreezeMarker> UnstableSmallSortTypeImpl for T {

`

94

94

`#[inline(always)]

`

95

95

`fn small_sort_threshold() -> usize {

`

96

``

`-

match const { choose_unstable_small_sort::() } {

`

97

``

`-

UnstableSmallSort::Fallback => SMALL_SORT_FALLBACK_THRESHOLD,

`

98

``

`-

UnstableSmallSort::General => SMALL_SORT_GENERAL_THRESHOLD,

`

99

``

`-

UnstableSmallSort::Network => SMALL_SORT_NETWORK_THRESHOLD,

`

``

96

`+

::small_sort_threshold()

`

``

97

`+

}

`

``

98

+

``

99

`+

#[inline(always)]

`

``

100

`+

fn small_sort(v: &mut [T], is_less: &mut F)

`

``

101

`+

where

`

``

102

`+

F: FnMut(&T, &T) -> bool,

`

``

103

`+

{

`

``

104

`+

::small_sort(v, is_less);

`

``

105

`+

}

`

``

106

`+

}

`

``

107

+

``

108

`+

/// FIXME(effects) use original ipnsort approach with choose_unstable_small_sort,

`

``

109

`+

/// as found here https://github.com/Voultapher/sort-research-rs/blob/438fad5d0495f65d4b72aa87f0b62fc96611dff3/ipnsort/src/smallsort.rs#L83C10-L83C36.

`

``

110

`+

pub(crate) trait UnstableSmallSortFreezeTypeImpl: Sized + FreezeMarker {

`

``

111

`+

fn small_sort_threshold() -> usize;

`

``

112

+

``

113

`+

fn small_sort<F: FnMut(&Self, &Self) -> bool>(v: &mut [Self], is_less: &mut F);

`

``

114

`+

}

`

``

115

+

``

116

`+

impl<T: FreezeMarker> UnstableSmallSortFreezeTypeImpl for T {

`

``

117

`+

#[inline(always)]

`

``

118

`+

default fn small_sort_threshold() -> usize {

`

``

119

`+

if (mem::size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE {

`

``

120

`+

SMALL_SORT_GENERAL_THRESHOLD

`

``

121

`+

} else {

`

``

122

`+

SMALL_SORT_FALLBACK_THRESHOLD

`

``

123

`+

}

`

``

124

`+

}

`

``

125

+

``

126

`+

#[inline(always)]

`

``

127

`+

default fn small_sort(v: &mut [T], is_less: &mut F)

`

``

128

`+

where

`

``

129

`+

F: FnMut(&T, &T) -> bool,

`

``

130

`+

{

`

``

131

`+

if (mem::size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE {

`

``

132

`+

small_sort_general(v, is_less);

`

``

133

`+

} else {

`

``

134

`+

small_sort_fallback(v, is_less);

`

``

135

`+

}

`

``

136

`+

}

`

``

137

`+

}

`

``

138

+

``

139

`+

/// SAFETY: Only used for run-time optimization heuristic.

`

``

140

`+

#[rustc_unsafe_specialization_marker]

`

``

141

`+

trait CopyMarker {}

`

``

142

+

``

143

`+

impl<T: FreezeMarker + CopyMarker> UnstableSmallSortFreezeTypeImpl for T {

`

``

144

`+

#[inline(always)]

`

``

145

`+

fn small_sort_threshold() -> usize {

`

``

146

`+

if has_efficient_in_place_swap::()

`

``

147

`+

&& (mem::size_of::() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE

`

``

148

`+

{

`

``

149

`+

SMALL_SORT_NETWORK_SCRATCH_LEN

`

``

150

`+

} else {

`

``

151

`+

SMALL_SORT_FALLBACK_THRESHOLD

`

100

152

`}

`

101

153

`}

`

102

154

``

`@@ -105,9 +157,13 @@ impl<T: FreezeMarker> UnstableSmallSortTypeImpl for T {

`

105

157

`where

`

106

158

`F: FnMut(&T, &T) -> bool,

`

107

159

`{

`

108

``

`-

// This construct is used to limit the LLVM IR generated, which saves large amounts of

`

109

``

`-

// compile-time by only instantiating the code that is needed. Idea by Frank Steffahn.

`

110

``

`-

(const { inst_unstable_small_sort::<T, F>() })(v, is_less);

`

``

160

`+

if has_efficient_in_place_swap::()

`

``

161

`+

&& (mem::size_of::() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE

`

``

162

`+

{

`

``

163

`+

small_sort_network(v, is_less);

`

``

164

`+

} else {

`

``

165

`+

small_sort_fallback(v, is_less);

`

``

166

`+

}

`

111

167

`}

`

112

168

`}

`

113

169

``

`@@ -137,37 +193,6 @@ const SMALL_SORT_NETWORK_SCRATCH_LEN: usize = SMALL_SORT_NETWORK_THRESHOLD;

`

137

193

`/// within this limit.

`

138

194

`const MAX_STACK_ARRAY_SIZE: usize = 4096;

`

139

195

``

140

``

`-

enum UnstableSmallSort {

`

141

``

`-

Fallback,

`

142

``

`-

General,

`

143

``

`-

Network,

`

144

``

`-

}

`

145

``

-

146

``

`-

const fn choose_unstable_small_sort<T: FreezeMarker>() -> UnstableSmallSort {

`

147

``

`-

if T::is_copy()

`

148

``

`-

&& has_efficient_in_place_swap::()

`

149

``

`-

&& (mem::size_of::() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE

`

150

``

`-

{

`

151

``

`-

// Heuristic for int like types.

`

152

``

`-

return UnstableSmallSort::Network;

`

153

``

`-

}

`

154

``

-

155

``

`-

if (mem::size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE {

`

156

``

`-

return UnstableSmallSort::General;

`

157

``

`-

}

`

158

``

-

159

``

`-

UnstableSmallSort::Fallback

`

160

``

`-

}

`

161

``

-

162

``

`-

const fn inst_unstable_small_sort<T: FreezeMarker, F: FnMut(&T, &T) -> bool>()

`

163

``

`-

-> fn(&mut [T], &mut F) {

`

164

``

`-

match const { choose_unstable_small_sort::() } {

`

165

``

`-

UnstableSmallSort::Fallback => small_sort_fallback::<T, F>,

`

166

``

`-

UnstableSmallSort::General => small_sort_general::<T, F>,

`

167

``

`-

UnstableSmallSort::Network => small_sort_network::<T, F>,

`

168

``

`-

}

`

169

``

`-

}

`

170

``

-

171

196

`fn small_sort_fallback<T, F: FnMut(&T, &T) -> bool>(v: &mut [T], is_less: &mut F) {

`

172

197

`if v.len() >= 2 {

`

173

198

`insertion_sort_shift_left(v, 1, is_less);

`

`@@ -822,25 +847,3 @@ pub(crate) const fn has_efficient_in_place_swap() -> bool {

`

822

847

`// Heuristic that holds true on all tested 64-bit capable architectures.

`

823

848

` mem::size_of::() <= 8 // mem::size_of::()

`

824

849

`}

`

825

``

-

826

``

`-

/// SAFETY: Only used for run-time optimization heuristic.

`

827

``

`-

#[rustc_unsafe_specialization_marker]

`

828

``

`-

trait CopyMarker {}

`

829

``

-

830

``

`-

impl<T: Copy> CopyMarker for T {}

`

831

``

-

832

``

`-

#[const_trait]

`

833

``

`-

trait IsCopy {

`

834

``

`-

fn is_copy() -> bool;

`

835

``

`-

}

`

836

``

-

837

``

`-

impl const IsCopy for T {

`

838

``

`-

default fn is_copy() -> bool {

`

839

``

`-

false

`

840

``

`-

}

`

841

``

`-

}

`

842

``

`-

impl<T: CopyMarker> const IsCopy for T {

`

843

``

`-

fn is_copy() -> bool {

`

844

``

`-

true

`

845

``

`-

}

`

846

``

`-

}

`