diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index adbc0e6ba2c0..9b5d9431ae20 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -871,16 +871,33 @@ impl Iterator for Box { fn nth(&mut self, n: usize) -> Option { (**self).nth(n) } - default fn last(self) -> Option { - let mut last = None; - for x in self { last = Some(x); } - last + fn last(self) -> Option { + BoxIter::last(self) } } +trait BoxIter { + type Item; + fn last(self) -> Option; +} + +impl BoxIter for Box { + type Item = I::Item; + default fn last(self) -> Option { + #[inline] + fn some(_: Option, x: T) -> Option { + Some(x) + } + + self.fold(None, some) + } +} + +/// Specialization for sized `I`s that uses `I`s implementation of `last()` +/// instead of the default. #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Box { - fn last(self) -> Option where I: Sized { +impl BoxIter for Box { + fn last(self) -> Option { (*self).last() } }