Skip to content

Commit 14f829a

Browse files
committed
Use marker/specialization traits instead of associated consts to signal the need for pre/post loop calls
The loop setup and cleanup functions are only required for some specific iterators. To avoid emitting IR when they're not needed even in debug mode we need to use the type system instead of const-DCE because the constants would only be known after monomorphization.
1 parent 9686822 commit 14f829a

File tree

17 files changed

+258
-79
lines changed

17 files changed

+258
-79
lines changed

library/alloc/src/collections/vec_deque/iter.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,6 @@ unsafe impl<T> TrustedLen for Iter<'_, T> {}
206206
#[doc(hidden)]
207207
#[unstable(feature = "trusted_random_access", issue = "none")]
208208
unsafe impl<T> TrustedRandomAccess for Iter<'_, T> {
209-
const NEEDS_CLEANUP: bool = false;
210-
211209
fn cleanup(&mut self, num: usize, forward: bool) {
212210
if forward {
213211
let _ = self.advance_by(num);

library/alloc/src/collections/vec_deque/iter_mut.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,6 @@ unsafe impl<T> TrustedLen for IterMut<'_, T> {}
155155
#[doc(hidden)]
156156
#[unstable(feature = "trusted_random_access", issue = "none")]
157157
unsafe impl<T> TrustedRandomAccess for IterMut<'_, T> {
158-
const NEEDS_CLEANUP: bool = false;
159-
160158
fn cleanup(&mut self, num: usize, forward: bool) {
161159
if forward {
162160
let _ = self.advance_by(num);

library/alloc/src/vec/into_iter.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ use crate::alloc::{Allocator, Global};
44
use crate::raw_vec::RawVec;
55
use core::fmt;
66
use core::intrinsics::arith_offset;
7-
use core::iter::{FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccess};
7+
use core::iter::{
8+
FusedIterator, InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccess,
9+
TrustedRandomAccessNeedsCleanup,
10+
};
811
use core::marker::PhantomData;
912
use core::mem::{self, ManuallyDrop};
1013
use core::ops::Deref;
@@ -286,8 +289,6 @@ unsafe impl<T, A: Allocator> TrustedRandomAccess for IntoIter<T, A>
286289
where
287290
T: NonDrop,
288291
{
289-
const NEEDS_CLEANUP: bool = true;
290-
291292
fn cleanup(&mut self, num: usize, forward: bool) {
292293
if forward {
293294
if mem::size_of::<T>() == 0 {
@@ -313,6 +314,10 @@ where
313314
}
314315
}
315316

317+
#[doc(hidden)]
318+
#[unstable(issue = "none", feature = "std_internals")]
319+
unsafe impl<T, A: Allocator> TrustedRandomAccessNeedsCleanup for IntoIter<T, A> where T: NonDrop {}
320+
316321
#[cfg(not(no_global_oom_handling))]
317322
#[stable(feature = "vec_into_iter_clone", since = "1.8.0")]
318323
impl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> {

library/core/src/iter/adapters/cloned.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use crate::iter::traits::trusted_random_access::try_get_unchecked;
2-
use crate::iter::traits::TrustedRandomAccess;
2+
use crate::iter::traits::{
3+
TrustedRandomAccess, TrustedRandomAccessNeedsCleanup, TrustedRandomAccessNeedsForwardSetup,
4+
TrustedRandomAccessNeedsReverseSetup,
5+
};
36
use crate::iter::{FusedIterator, TrustedLen};
47
use crate::ops::Try;
58

@@ -126,14 +129,31 @@ unsafe impl<I> TrustedRandomAccess for Cloned<I>
126129
where
127130
I: TrustedRandomAccess,
128131
{
129-
const NEEDS_CLEANUP: bool = I::NEEDS_CLEANUP;
130-
131132
#[inline]
132133
fn cleanup(&mut self, num: usize, forward: bool) {
133134
self.it.cleanup(num, forward);
134135
}
135136
}
136137

138+
#[doc(hidden)]
139+
#[unstable(feature = "trusted_random_access", issue = "none")]
140+
unsafe impl<I> TrustedRandomAccessNeedsCleanup for Cloned<I> where I: TrustedRandomAccessNeedsCleanup
141+
{}
142+
143+
#[doc(hidden)]
144+
#[unstable(feature = "trusted_random_access", issue = "none")]
145+
unsafe impl<I> TrustedRandomAccessNeedsForwardSetup for Cloned<I> where
146+
I: TrustedRandomAccessNeedsForwardSetup
147+
{
148+
}
149+
150+
#[doc(hidden)]
151+
#[unstable(feature = "trusted_random_access", issue = "none")]
152+
unsafe impl<I> TrustedRandomAccessNeedsReverseSetup for Cloned<I> where
153+
I: TrustedRandomAccessNeedsReverseSetup
154+
{
155+
}
156+
137157
#[unstable(feature = "trusted_len", issue = "37572")]
138158
unsafe impl<'a, I, T: 'a> TrustedLen for Cloned<I>
139159
where

library/core/src/iter/adapters/copied.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use crate::iter::traits::trusted_random_access::try_get_unchecked;
2-
use crate::iter::traits::TrustedRandomAccess;
2+
use crate::iter::traits::{
3+
TrustedRandomAccess, TrustedRandomAccessNeedsCleanup, TrustedRandomAccessNeedsForwardSetup,
4+
TrustedRandomAccessNeedsReverseSetup,
5+
};
36
use crate::iter::{FusedIterator, TrustedLen};
47
use crate::ops::Try;
58

@@ -152,14 +155,31 @@ unsafe impl<I> TrustedRandomAccess for Copied<I>
152155
where
153156
I: TrustedRandomAccess,
154157
{
155-
const NEEDS_CLEANUP: bool = I::NEEDS_CLEANUP;
156-
157158
#[inline]
158159
fn cleanup(&mut self, num: usize, forward: bool) {
159160
self.it.cleanup(num, forward);
160161
}
161162
}
162163

164+
#[doc(hidden)]
165+
#[unstable(feature = "trusted_random_access", issue = "none")]
166+
unsafe impl<I> TrustedRandomAccessNeedsCleanup for Copied<I> where I: TrustedRandomAccessNeedsCleanup
167+
{}
168+
169+
#[doc(hidden)]
170+
#[unstable(feature = "trusted_random_access", issue = "none")]
171+
unsafe impl<I> TrustedRandomAccessNeedsForwardSetup for Copied<I> where
172+
I: TrustedRandomAccessNeedsForwardSetup
173+
{
174+
}
175+
176+
#[doc(hidden)]
177+
#[unstable(feature = "trusted_random_access", issue = "none")]
178+
unsafe impl<I> TrustedRandomAccessNeedsReverseSetup for Copied<I> where
179+
I: TrustedRandomAccessNeedsReverseSetup
180+
{
181+
}
182+
163183
#[stable(feature = "iter_copied", since = "1.36.0")]
164184
unsafe impl<'a, I, T: 'a> TrustedLen for Copied<I>
165185
where

library/core/src/iter/adapters/enumerate.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use crate::iter::adapters::SourceIter;
22
use crate::iter::traits::trusted_random_access::try_get_unchecked;
3-
use crate::iter::traits::TrustedRandomAccess;
3+
use crate::iter::traits::{
4+
TrustedRandomAccess, TrustedRandomAccessNeedsCleanup, TrustedRandomAccessNeedsForwardSetup,
5+
TrustedRandomAccessNeedsReverseSetup,
6+
};
47
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
58
use crate::ops::Try;
69

@@ -236,14 +239,33 @@ unsafe impl<I> TrustedRandomAccess for Enumerate<I>
236239
where
237240
I: TrustedRandomAccess,
238241
{
239-
const NEEDS_CLEANUP: bool = I::NEEDS_CLEANUP;
240-
241242
#[inline]
242243
fn cleanup(&mut self, num: usize, forward: bool) {
243244
self.iter.cleanup(num, forward);
244245
}
245246
}
246247

248+
#[doc(hidden)]
249+
#[unstable(feature = "trusted_random_access", issue = "none")]
250+
unsafe impl<I> TrustedRandomAccessNeedsCleanup for Enumerate<I> where
251+
I: TrustedRandomAccessNeedsCleanup
252+
{
253+
}
254+
255+
#[doc(hidden)]
256+
#[unstable(feature = "trusted_random_access", issue = "none")]
257+
unsafe impl<I> TrustedRandomAccessNeedsForwardSetup for Enumerate<I> where
258+
I: TrustedRandomAccessNeedsForwardSetup
259+
{
260+
}
261+
262+
#[doc(hidden)]
263+
#[unstable(feature = "trusted_random_access", issue = "none")]
264+
unsafe impl<I> TrustedRandomAccessNeedsReverseSetup for Enumerate<I> where
265+
I: TrustedRandomAccessNeedsReverseSetup
266+
{
267+
}
268+
247269
#[stable(feature = "fused", since = "1.26.0")]
248270
impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {}
249271

library/core/src/iter/adapters/fuse.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use crate::intrinsics;
22
use crate::iter::traits::trusted_random_access::try_get_unchecked;
33
use crate::iter::{
44
DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess,
5+
TrustedRandomAccessNeedsCleanup, TrustedRandomAccessNeedsForwardSetup,
6+
TrustedRandomAccessNeedsReverseSetup,
57
};
68
use crate::ops::Try;
79

@@ -225,8 +227,6 @@ unsafe impl<I> TrustedRandomAccess for Fuse<I>
225227
where
226228
I: TrustedRandomAccess,
227229
{
228-
const NEEDS_CLEANUP: bool = I::NEEDS_CLEANUP;
229-
230230
#[inline]
231231
fn cleanup(&mut self, num: usize, forward: bool) {
232232
if let Some(iter) = self.iter.as_mut() {
@@ -235,6 +235,24 @@ where
235235
}
236236
}
237237

238+
#[doc(hidden)]
239+
#[unstable(feature = "trusted_random_access", issue = "none")]
240+
unsafe impl<I> TrustedRandomAccessNeedsCleanup for Fuse<I> where I: TrustedRandomAccessNeedsCleanup {}
241+
242+
#[doc(hidden)]
243+
#[unstable(feature = "trusted_random_access", issue = "none")]
244+
unsafe impl<I> TrustedRandomAccessNeedsForwardSetup for Fuse<I> where
245+
I: TrustedRandomAccessNeedsForwardSetup
246+
{
247+
}
248+
249+
#[doc(hidden)]
250+
#[unstable(feature = "trusted_random_access", issue = "none")]
251+
unsafe impl<I> TrustedRandomAccessNeedsReverseSetup for Fuse<I> where
252+
I: TrustedRandomAccessNeedsReverseSetup
253+
{
254+
}
255+
238256
/// Fuse specialization trait
239257
///
240258
/// We only need to worry about `&mut self` methods, which

library/core/src/iter/adapters/map.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use crate::fmt;
22
use crate::iter::adapters::SourceIter;
33
use crate::iter::traits::trusted_random_access::try_get_unchecked;
4-
use crate::iter::traits::TrustedRandomAccess;
4+
use crate::iter::traits::{
5+
TrustedRandomAccess, TrustedRandomAccessNeedsCleanup, TrustedRandomAccessNeedsForwardSetup,
6+
TrustedRandomAccessNeedsReverseSetup,
7+
};
58
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
69
use crate::ops::Try;
710

@@ -194,14 +197,33 @@ unsafe impl<I, F> TrustedRandomAccess for Map<I, F>
194197
where
195198
I: TrustedRandomAccess,
196199
{
197-
const NEEDS_CLEANUP: bool = I::NEEDS_CLEANUP;
198-
199200
#[inline]
200201
fn cleanup(&mut self, num: usize, forward: bool) {
201202
self.iter.cleanup(num, forward);
202203
}
203204
}
204205

206+
#[doc(hidden)]
207+
#[unstable(feature = "trusted_random_access", issue = "none")]
208+
unsafe impl<I, F> TrustedRandomAccessNeedsCleanup for Map<I, F> where
209+
I: TrustedRandomAccessNeedsCleanup
210+
{
211+
}
212+
213+
#[doc(hidden)]
214+
#[unstable(feature = "trusted_random_access", issue = "none")]
215+
unsafe impl<I, F> TrustedRandomAccessNeedsForwardSetup for Map<I, F> where
216+
I: TrustedRandomAccessNeedsForwardSetup
217+
{
218+
}
219+
220+
#[doc(hidden)]
221+
#[unstable(feature = "trusted_random_access", issue = "none")]
222+
unsafe impl<I, F> TrustedRandomAccessNeedsReverseSetup for Map<I, F> where
223+
I: TrustedRandomAccessNeedsReverseSetup
224+
{
225+
}
226+
205227
#[unstable(issue = "none", feature = "inplace_iteration")]
206228
unsafe impl<I, F> SourceIter for Map<I, F>
207229
where

library/core/src/iter/adapters/zip.rs

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ use crate::cmp;
22
use crate::fmt::{self, Debug};
33
use crate::iter::traits::trusted_random_access::try_get_unchecked;
44
use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
5-
use crate::iter::{InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccess};
5+
use crate::iter::{
6+
InPlaceIterable, SourceIter, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNeedsCleanup,
7+
TrustedRandomAccessNeedsForwardSetup, TrustedRandomAccessNeedsReverseSetup,
8+
};
69
use crate::ops::Try;
710

811
/// An iterator that iterates two other iterators simultaneously.
@@ -259,14 +262,63 @@ where
259262
A: TrustedRandomAccess,
260263
B: TrustedRandomAccess,
261264
{
262-
const NEEDS_CLEANUP: bool = A::NEEDS_CLEANUP || B::NEEDS_CLEANUP;
263-
264265
fn cleanup(&mut self, num: usize, forward: bool) {
265266
self.a.cleanup(num, forward);
266267
self.b.cleanup(num, forward);
267268
}
268269
}
269270

271+
#[doc(hidden)]
272+
#[unstable(feature = "trusted_random_access", issue = "none")]
273+
unsafe impl<A, B> TrustedRandomAccessNeedsCleanup for Zip<A, B> where
274+
A: TrustedRandomAccessNeedsCleanup
275+
{
276+
}
277+
278+
#[doc(hidden)]
279+
#[unstable(feature = "trusted_random_access", issue = "none")]
280+
unsafe impl<A, B> TrustedRandomAccessNeedsCleanup for Zip<A, B> where
281+
B: TrustedRandomAccessNeedsCleanup
282+
{
283+
}
284+
285+
#[doc(hidden)]
286+
#[unstable(feature = "trusted_random_access", issue = "none")]
287+
unsafe impl<A, B> TrustedRandomAccessNeedsCleanup for Zip<A, B>
288+
where
289+
A: TrustedRandomAccessNeedsCleanup,
290+
B: TrustedRandomAccessNeedsCleanup,
291+
{
292+
}
293+
294+
#[doc(hidden)]
295+
#[unstable(feature = "trusted_random_access", issue = "none")]
296+
unsafe impl<A, B> TrustedRandomAccessNeedsForwardSetup for Zip<A, B> where
297+
A: TrustedRandomAccessNeedsForwardSetup
298+
{
299+
}
300+
301+
#[doc(hidden)]
302+
#[unstable(feature = "trusted_random_access", issue = "none")]
303+
unsafe impl<A, B> TrustedRandomAccessNeedsForwardSetup for Zip<A, B> where
304+
B: TrustedRandomAccessNeedsForwardSetup
305+
{
306+
}
307+
308+
#[doc(hidden)]
309+
#[unstable(feature = "trusted_random_access", issue = "none")]
310+
unsafe impl<A, B> TrustedRandomAccessNeedsForwardSetup for Zip<A, B>
311+
where
312+
A: TrustedRandomAccessNeedsForwardSetup,
313+
B: TrustedRandomAccessNeedsForwardSetup,
314+
{
315+
}
316+
317+
318+
#[doc(hidden)]
319+
#[unstable(feature = "trusted_random_access", issue = "none")]
320+
unsafe impl<A, B> TrustedRandomAccessNeedsReverseSetup for Zip<A, B> where Self: TrustedRandomAccess {}
321+
270322
#[stable(feature = "fused", since = "1.26.0")]
271323
impl<A, B> FusedIterator for Zip<A, B>
272324
where

0 commit comments

Comments
 (0)