Skip to content

Commit 7f2aeea

Browse files
committed
Make TrustedStep require Copy
All the implementations of the trait already are `Copy`, and this seems to be enough to simplify the implementations enough to make the MIR inliner willing to inline basics like `Range::next`.
1 parent dbbf172 commit 7f2aeea

File tree

2 files changed

+14
-13
lines changed

2 files changed

+14
-13
lines changed

core/src/iter/range.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -619,25 +619,26 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
619619
#[inline]
620620
fn spec_next(&mut self) -> Option<T> {
621621
if self.start < self.end {
622+
let old = self.start;
622623
// SAFETY: just checked precondition
623-
let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) };
624-
Some(mem::replace(&mut self.start, n))
624+
self.start = unsafe { Step::forward_unchecked(old, 1) };
625+
Some(old)
625626
} else {
626627
None
627628
}
628629
}
629630

630631
#[inline]
631632
fn spec_nth(&mut self, n: usize) -> Option<T> {
632-
if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
633+
if let Some(plus_n) = Step::forward_checked(self.start, n) {
633634
if plus_n < self.end {
634635
// SAFETY: just checked precondition
635-
self.start = unsafe { Step::forward_unchecked(plus_n.clone(), 1) };
636+
self.start = unsafe { Step::forward_unchecked(plus_n, 1) };
636637
return Some(plus_n);
637638
}
638639
}
639640

640-
self.start = self.end.clone();
641+
self.start = self.end;
641642
None
642643
}
643644

@@ -655,7 +656,7 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
655656
// then steps_between either returns a bound to which we clamp or returns None which
656657
// together with the initial inequality implies more than usize::MAX steps.
657658
// Otherwise 0 is returned which always safe to use.
658-
self.start = unsafe { Step::forward_unchecked(self.start.clone(), taken) };
659+
self.start = unsafe { Step::forward_unchecked(self.start, taken) };
659660

660661
NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
661662
}
@@ -664,24 +665,24 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
664665
fn spec_next_back(&mut self) -> Option<T> {
665666
if self.start < self.end {
666667
// SAFETY: just checked precondition
667-
self.end = unsafe { Step::backward_unchecked(self.end.clone(), 1) };
668-
Some(self.end.clone())
668+
self.end = unsafe { Step::backward_unchecked(self.end, 1) };
669+
Some(self.end)
669670
} else {
670671
None
671672
}
672673
}
673674

674675
#[inline]
675676
fn spec_nth_back(&mut self, n: usize) -> Option<T> {
676-
if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
677+
if let Some(minus_n) = Step::backward_checked(self.end, n) {
677678
if minus_n > self.start {
678679
// SAFETY: just checked precondition
679680
self.end = unsafe { Step::backward_unchecked(minus_n, 1) };
680-
return Some(self.end.clone());
681+
return Some(self.end);
681682
}
682683
}
683684

684-
self.end = self.start.clone();
685+
self.end = self.start;
685686
None
686687
}
687688

@@ -696,7 +697,7 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
696697
let taken = available.min(n);
697698

698699
// SAFETY: same as the spec_advance_by() implementation
699-
self.end = unsafe { Step::backward_unchecked(self.end.clone(), taken) };
700+
self.end = unsafe { Step::backward_unchecked(self.end, taken) };
700701

701702
NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
702703
}

core/src/iter/traits/marker.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,4 @@ pub unsafe trait InPlaceIterable: Iterator {}
8686
/// for details. Consumers are free to rely on the invariants in unsafe code.
8787
#[unstable(feature = "trusted_step", issue = "85731")]
8888
#[rustc_specialization_trait]
89-
pub unsafe trait TrustedStep: Step {}
89+
pub unsafe trait TrustedStep: Step + Copy {}

0 commit comments

Comments
 (0)