diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 325efe721e30c..8eb1ed641cfae 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -1626,6 +1626,25 @@ impl> FromIterator> for Result { } } +//FIXME: Figure out how to mark this as unstable without x.py refusing to run any tests +#[stable(feature = "tuple_from_result_iter", since = "1.53.0")] +impl FromIterator> for (U, V) +where + U: Default + Extend, + V: Default + Extend, +{ + fn from_iter>>(iter: I) -> (U, V) { + let (mut oks, mut errs) = (U::default(), V::default()); + for result in iter { + match result { + Ok(ok) => oks.extend_one(ok), + Err(err) => errs.extend_one(err), + } + } + (oks, errs) + } +} + #[unstable(feature = "try_trait_v2", issue = "84277")] impl ops::TryV2 for Result { type Output = T; diff --git a/library/core/tests/result.rs b/library/core/tests/result.rs index 612f083a5c178..415e2e43cdd82 100644 --- a/library/core/tests/result.rs +++ b/library/core/tests/result.rs @@ -402,3 +402,21 @@ fn result_try_trait_v2_branch() { assert_eq!(Ok::(one).branch(), Continue(one)); assert_eq!(Err::(()).branch(), Break(Err(()))); } + +#[test] +fn tuple_from_result_iter() { + let results = [Ok(1), Err(false), Ok(3), Ok(4), Err(true)]; + let (oks, errs) = IntoIterator::into_iter(results).collect::<(Vec<_>, Vec)>(); + assert_eq!(oks, [1, 3, 4]); + assert_eq!(errs, [false, true]); + // All `Ok`s + let results = [Ok(5), Ok(6), Ok(7)]; + let (oks, errs) = IntoIterator::into_iter(results).collect::<(Vec<_>, Vec)>(); + assert_eq!(oks, [5, 6, 7]); + assert_eq!(errs, [] as [String; 0]); + // All `Errs`s + let results: [Result; 2] = [Err("hello"), Err("world")]; + let (oks, errs) = IntoIterator::into_iter(results).collect::<(Vec, Vec<_>)>(); + assert_eq!(oks, [] as [i32; 0]); + assert_eq!(errs, ["hello", "world"]); +}