From 84daccc5596f6041a7593856aadd665341a3adb7 Mon Sep 17 00:00:00 2001 From: Leonora Tindall Date: Fri, 11 Sep 2020 16:36:58 -0500 Subject: [PATCH] change the order of type arguments on ControlFlow This allows ControlFlow which is much more ergonomic for common iterator combinator use cases. --- .../rustc_data_structures/src/graph/iterate/mod.rs | 3 +-- library/core/src/iter/adapters/mod.rs | 10 +++++----- library/core/src/iter/traits/double_ended.rs | 4 +--- library/core/src/iter/traits/iterator.rs | 14 +++++--------- library/core/src/ops/control_flow.rs | 12 ++++++------ 5 files changed, 18 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs index bc3d1ce53bac5..c0c3260e2e2ec 100644 --- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs @@ -87,8 +87,7 @@ where } /// Allows searches to terminate early with a value. -// FIXME (#75744): remove the alias once the generics are in a better order and `C=()`. -pub type ControlFlow = std::ops::ControlFlow<(), T>; +pub use std::ops::ControlFlow; /// The status of a node in the depth-first search. /// diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index bf30dcb7689fa..9c8e639c2d802 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -1280,7 +1280,7 @@ where #[inline] fn find( f: &mut impl FnMut(T) -> Option, - ) -> impl FnMut((), T) -> ControlFlow<(), B> + '_ { + ) -> impl FnMut((), T) -> ControlFlow + '_ { move |(), x| match f(x) { Some(x) => ControlFlow::Break(x), None => ControlFlow::CONTINUE, @@ -2059,7 +2059,7 @@ where flag: &'a mut bool, p: &'a mut impl FnMut(&T) -> bool, mut fold: impl FnMut(Acc, T) -> R + 'a, - ) -> impl FnMut(Acc, T) -> ControlFlow + 'a { + ) -> impl FnMut(Acc, T) -> ControlFlow + 'a { move |acc, x| { if p(&x) { ControlFlow::from_try(fold(acc, x)) @@ -2372,7 +2372,7 @@ where fn check>( mut n: usize, mut fold: impl FnMut(Acc, T) -> R, - ) -> impl FnMut(Acc, T) -> ControlFlow { + ) -> impl FnMut(Acc, T) -> ControlFlow { move |acc, x| { n -= 1; let r = fold(acc, x); @@ -2496,7 +2496,7 @@ where fn check<'a, T, Acc, R: Try>( n: &'a mut usize, mut fold: impl FnMut(Acc, T) -> R + 'a, - ) -> impl FnMut(Acc, T) -> ControlFlow + 'a { + ) -> impl FnMut(Acc, T) -> ControlFlow + 'a { move |acc, x| { *n -= 1; let r = fold(acc, x); @@ -2681,7 +2681,7 @@ where state: &'a mut St, f: &'a mut impl FnMut(&mut St, T) -> Option, mut fold: impl FnMut(Acc, B) -> R + 'a, - ) -> impl FnMut(Acc, T) -> ControlFlow + 'a { + ) -> impl FnMut(Acc, T) -> ControlFlow + 'a { move |acc, x| match f(state, x) { None => ControlFlow::Break(try { acc }), Some(x) => ControlFlow::from_try(fold(acc, x)), diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index 87fe3c210402e..6f8cb6b5a65b6 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -339,9 +339,7 @@ pub trait DoubleEndedIterator: Iterator { P: FnMut(&Self::Item) -> bool, { #[inline] - fn check( - mut predicate: impl FnMut(&T) -> bool, - ) -> impl FnMut((), T) -> ControlFlow<(), T> { + fn check(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow { move |(), x| { if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE } } diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 18b4adc23e8ef..7fc60caec2a73 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2109,7 +2109,7 @@ pub trait Iterator { F: FnMut(Self::Item) -> bool, { #[inline] - fn check(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> { + fn check(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> { move |(), x| { if f(x) { ControlFlow::CONTINUE } else { ControlFlow::BREAK } } @@ -2162,7 +2162,7 @@ pub trait Iterator { F: FnMut(Self::Item) -> bool, { #[inline] - fn check(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> { + fn check(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> { move |(), x| { if f(x) { ControlFlow::BREAK } else { ControlFlow::CONTINUE } } @@ -2222,9 +2222,7 @@ pub trait Iterator { P: FnMut(&Self::Item) -> bool, { #[inline] - fn check( - mut predicate: impl FnMut(&T) -> bool, - ) -> impl FnMut((), T) -> ControlFlow<(), T> { + fn check(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow { move |(), x| { if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE } } @@ -2255,9 +2253,7 @@ pub trait Iterator { F: FnMut(Self::Item) -> Option, { #[inline] - fn check( - mut f: impl FnMut(T) -> Option, - ) -> impl FnMut((), T) -> ControlFlow<(), B> { + fn check(mut f: impl FnMut(T) -> Option) -> impl FnMut((), T) -> ControlFlow { move |(), x| match f(x) { Some(x) => ControlFlow::Break(x), None => ControlFlow::CONTINUE, @@ -2296,7 +2292,7 @@ pub trait Iterator { R: Try, { #[inline] - fn check(mut f: F) -> impl FnMut((), T) -> ControlFlow<(), Result> + fn check(mut f: F) -> impl FnMut((), T) -> ControlFlow> where F: FnMut(&T) -> R, R: Try, diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index 3bca3ff97332b..5ede1ba8e2c10 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -3,7 +3,7 @@ use crate::ops::Try; /// Used to make try_fold closures more like normal loops #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] #[derive(Debug, Clone, Copy, PartialEq)] -pub enum ControlFlow { +pub enum ControlFlow { /// Continue in the loop, using the given value for the next iteration Continue(C), /// Exit the loop, yielding the given value @@ -11,7 +11,7 @@ pub enum ControlFlow { } #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] -impl Try for ControlFlow { +impl Try for ControlFlow { type Ok = C; type Error = B; #[inline] @@ -31,7 +31,7 @@ impl Try for ControlFlow { } } -impl ControlFlow { +impl ControlFlow { /// Returns `true` if this is a `Break` variant. #[inline] #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] @@ -58,7 +58,7 @@ impl ControlFlow { } } -impl ControlFlow { +impl ControlFlow { /// Create a `ControlFlow` from any type implementing `Try`. #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] #[inline] @@ -80,7 +80,7 @@ impl ControlFlow { } } -impl ControlFlow<(), B> { +impl ControlFlow { /// It's frequently the case that there's no value needed with `Continue`, /// so this provides a way to avoid typing `(())`, if you prefer it. /// @@ -102,7 +102,7 @@ impl ControlFlow<(), B> { pub const CONTINUE: Self = ControlFlow::Continue(()); } -impl ControlFlow { +impl ControlFlow<(), C> { /// APIs like `try_for_each` don't need values with `Break`, /// so this provides a way to avoid typing `(())`, if you prefer it. ///