diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 9748235e94a..8fb10fcca0c 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -587,20 +587,32 @@ impl ExactSize for Item {}
/// ```
#[inline]
pub fn collect>, V: FromIterator>(iter: Iter) -> Option {
- // FIXME(#11084): This should be twice as fast once this bug is closed.
- let mut iter = iter.scan(false, |state, x| {
- match x {
- Some(x) => Some(x),
- None => {
- *state = true;
- None
+ // FIXME(#11084): This could be replaced with Iterator::scan when this
+ // performance bug is closed.
+
+ struct Adapter {
+ iter: Iter,
+ found_none: bool,
+ }
+
+ impl>> Iterator for Adapter {
+ #[inline]
+ fn next(&mut self) -> Option {
+ match self.iter.next() {
+ Some(Some(value)) => Some(value),
+ Some(None) => {
+ self.found_none = true;
+ None
+ }
+ None => None,
}
}
- });
+ }
- let v: V = FromIterator::from_iter(iter.by_ref());
+ let mut adapter = Adapter { iter: iter, found_none: false };
+ let v: V = FromIterator::from_iter(adapter.by_ref());
- if iter.state {
+ if adapter.found_none {
None
} else {
Some(v)
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 6c163b79199..8cd56713ffb 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -585,20 +585,32 @@ impl Result {
/// ```
#[inline]
pub fn collect>, V: FromIterator>(iter: Iter) -> Result {
- // FIXME(#11084): This should be twice as fast once this bug is closed.
- let mut iter = iter.scan(None, |state, x| {
- match x {
- Ok(x) => Some(x),
- Err(err) => {
- *state = Some(err);
- None
+ // FIXME(#11084): This could be replaced with Iterator::scan when this
+ // performance bug is closed.
+
+ struct Adapter {
+ iter: Iter,
+ err: Option,
+ }
+
+ impl>> Iterator for Adapter {
+ #[inline]
+ fn next(&mut self) -> Option {
+ match self.iter.next() {
+ Some(Ok(value)) => Some(value),
+ Some(Err(err)) => {
+ self.err = Some(err);
+ None
+ }
+ None => None,
}
}
- });
+ }
- let v: V = FromIterator::from_iter(iter.by_ref());
+ let mut adapter = Adapter { iter: iter, err: None };
+ let v: V = FromIterator::from_iter(adapter.by_ref());
- match iter.state {
+ match adapter.err {
Some(err) => Err(err),
None => Ok(v),
}