change the order of type arguments on ControlFlow
This allows ControlFlow<BreakType> which is much more ergonomic for common iterator combinator use cases.
This commit is contained in:
parent
a9cd294cf2
commit
84daccc559
5 changed files with 18 additions and 25 deletions
|
@ -87,8 +87,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allows searches to terminate early with a value.
|
/// Allows searches to terminate early with a value.
|
||||||
// FIXME (#75744): remove the alias once the generics are in a better order and `C=()`.
|
pub use std::ops::ControlFlow;
|
||||||
pub type ControlFlow<T> = std::ops::ControlFlow<(), T>;
|
|
||||||
|
|
||||||
/// The status of a node in the depth-first search.
|
/// The status of a node in the depth-first search.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1280,7 +1280,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
fn find<T, B>(
|
fn find<T, B>(
|
||||||
f: &mut impl FnMut(T) -> Option<B>,
|
f: &mut impl FnMut(T) -> Option<B>,
|
||||||
) -> impl FnMut((), T) -> ControlFlow<(), B> + '_ {
|
) -> impl FnMut((), T) -> ControlFlow<B> + '_ {
|
||||||
move |(), x| match f(x) {
|
move |(), x| match f(x) {
|
||||||
Some(x) => ControlFlow::Break(x),
|
Some(x) => ControlFlow::Break(x),
|
||||||
None => ControlFlow::CONTINUE,
|
None => ControlFlow::CONTINUE,
|
||||||
|
@ -2059,7 +2059,7 @@ where
|
||||||
flag: &'a mut bool,
|
flag: &'a mut bool,
|
||||||
p: &'a mut impl FnMut(&T) -> bool,
|
p: &'a mut impl FnMut(&T) -> bool,
|
||||||
mut fold: impl FnMut(Acc, T) -> R + 'a,
|
mut fold: impl FnMut(Acc, T) -> R + 'a,
|
||||||
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
|
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
|
||||||
move |acc, x| {
|
move |acc, x| {
|
||||||
if p(&x) {
|
if p(&x) {
|
||||||
ControlFlow::from_try(fold(acc, x))
|
ControlFlow::from_try(fold(acc, x))
|
||||||
|
@ -2372,7 +2372,7 @@ where
|
||||||
fn check<T, Acc, R: Try<Ok = Acc>>(
|
fn check<T, Acc, R: Try<Ok = Acc>>(
|
||||||
mut n: usize,
|
mut n: usize,
|
||||||
mut fold: impl FnMut(Acc, T) -> R,
|
mut fold: impl FnMut(Acc, T) -> R,
|
||||||
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> {
|
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> {
|
||||||
move |acc, x| {
|
move |acc, x| {
|
||||||
n -= 1;
|
n -= 1;
|
||||||
let r = fold(acc, x);
|
let r = fold(acc, x);
|
||||||
|
@ -2496,7 +2496,7 @@ where
|
||||||
fn check<'a, T, Acc, R: Try<Ok = Acc>>(
|
fn check<'a, T, Acc, R: Try<Ok = Acc>>(
|
||||||
n: &'a mut usize,
|
n: &'a mut usize,
|
||||||
mut fold: impl FnMut(Acc, T) -> R + 'a,
|
mut fold: impl FnMut(Acc, T) -> R + 'a,
|
||||||
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
|
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
|
||||||
move |acc, x| {
|
move |acc, x| {
|
||||||
*n -= 1;
|
*n -= 1;
|
||||||
let r = fold(acc, x);
|
let r = fold(acc, x);
|
||||||
|
@ -2681,7 +2681,7 @@ where
|
||||||
state: &'a mut St,
|
state: &'a mut St,
|
||||||
f: &'a mut impl FnMut(&mut St, T) -> Option<B>,
|
f: &'a mut impl FnMut(&mut St, T) -> Option<B>,
|
||||||
mut fold: impl FnMut(Acc, B) -> R + 'a,
|
mut fold: impl FnMut(Acc, B) -> R + 'a,
|
||||||
) -> impl FnMut(Acc, T) -> ControlFlow<Acc, R> + 'a {
|
) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
|
||||||
move |acc, x| match f(state, x) {
|
move |acc, x| match f(state, x) {
|
||||||
None => ControlFlow::Break(try { acc }),
|
None => ControlFlow::Break(try { acc }),
|
||||||
Some(x) => ControlFlow::from_try(fold(acc, x)),
|
Some(x) => ControlFlow::from_try(fold(acc, x)),
|
||||||
|
|
|
@ -339,9 +339,7 @@ pub trait DoubleEndedIterator: Iterator {
|
||||||
P: FnMut(&Self::Item) -> bool,
|
P: FnMut(&Self::Item) -> bool,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check<T>(
|
fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow<T> {
|
||||||
mut predicate: impl FnMut(&T) -> bool,
|
|
||||||
) -> impl FnMut((), T) -> ControlFlow<(), T> {
|
|
||||||
move |(), x| {
|
move |(), x| {
|
||||||
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE }
|
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE }
|
||||||
}
|
}
|
||||||
|
|
|
@ -2109,7 +2109,7 @@ pub trait Iterator {
|
||||||
F: FnMut(Self::Item) -> bool,
|
F: FnMut(Self::Item) -> bool,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> {
|
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> {
|
||||||
move |(), x| {
|
move |(), x| {
|
||||||
if f(x) { ControlFlow::CONTINUE } else { ControlFlow::BREAK }
|
if f(x) { ControlFlow::CONTINUE } else { ControlFlow::BREAK }
|
||||||
}
|
}
|
||||||
|
@ -2162,7 +2162,7 @@ pub trait Iterator {
|
||||||
F: FnMut(Self::Item) -> bool,
|
F: FnMut(Self::Item) -> bool,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> {
|
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> {
|
||||||
move |(), x| {
|
move |(), x| {
|
||||||
if f(x) { ControlFlow::BREAK } else { ControlFlow::CONTINUE }
|
if f(x) { ControlFlow::BREAK } else { ControlFlow::CONTINUE }
|
||||||
}
|
}
|
||||||
|
@ -2222,9 +2222,7 @@ pub trait Iterator {
|
||||||
P: FnMut(&Self::Item) -> bool,
|
P: FnMut(&Self::Item) -> bool,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check<T>(
|
fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow<T> {
|
||||||
mut predicate: impl FnMut(&T) -> bool,
|
|
||||||
) -> impl FnMut((), T) -> ControlFlow<(), T> {
|
|
||||||
move |(), x| {
|
move |(), x| {
|
||||||
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE }
|
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE }
|
||||||
}
|
}
|
||||||
|
@ -2255,9 +2253,7 @@ pub trait Iterator {
|
||||||
F: FnMut(Self::Item) -> Option<B>,
|
F: FnMut(Self::Item) -> Option<B>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check<T, B>(
|
fn check<T, B>(mut f: impl FnMut(T) -> Option<B>) -> impl FnMut((), T) -> ControlFlow<B> {
|
||||||
mut f: impl FnMut(T) -> Option<B>,
|
|
||||||
) -> impl FnMut((), T) -> ControlFlow<(), B> {
|
|
||||||
move |(), x| match f(x) {
|
move |(), x| match f(x) {
|
||||||
Some(x) => ControlFlow::Break(x),
|
Some(x) => ControlFlow::Break(x),
|
||||||
None => ControlFlow::CONTINUE,
|
None => ControlFlow::CONTINUE,
|
||||||
|
@ -2296,7 +2292,7 @@ pub trait Iterator {
|
||||||
R: Try<Ok = bool>,
|
R: Try<Ok = bool>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> ControlFlow<(), Result<T, R::Error>>
|
fn check<F, T, R>(mut f: F) -> impl FnMut((), T) -> ControlFlow<Result<T, R::Error>>
|
||||||
where
|
where
|
||||||
F: FnMut(&T) -> R,
|
F: FnMut(&T) -> R,
|
||||||
R: Try<Ok = bool>,
|
R: Try<Ok = bool>,
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::ops::Try;
|
||||||
/// Used to make try_fold closures more like normal loops
|
/// Used to make try_fold closures more like normal loops
|
||||||
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum ControlFlow<C, B> {
|
pub enum ControlFlow<B, C = ()> {
|
||||||
/// Continue in the loop, using the given value for the next iteration
|
/// Continue in the loop, using the given value for the next iteration
|
||||||
Continue(C),
|
Continue(C),
|
||||||
/// Exit the loop, yielding the given value
|
/// Exit the loop, yielding the given value
|
||||||
|
@ -11,7 +11,7 @@ pub enum ControlFlow<C, B> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
||||||
impl<C, B> Try for ControlFlow<C, B> {
|
impl<B, C> Try for ControlFlow<B, C> {
|
||||||
type Ok = C;
|
type Ok = C;
|
||||||
type Error = B;
|
type Error = B;
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -31,7 +31,7 @@ impl<C, B> Try for ControlFlow<C, B> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, B> ControlFlow<C, B> {
|
impl<B, C> ControlFlow<B, C> {
|
||||||
/// Returns `true` if this is a `Break` variant.
|
/// Returns `true` if this is a `Break` variant.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
||||||
|
@ -58,7 +58,7 @@ impl<C, B> ControlFlow<C, B> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Try> ControlFlow<R::Ok, R> {
|
impl<R: Try> ControlFlow<R, R::Ok> {
|
||||||
/// Create a `ControlFlow` from any type implementing `Try`.
|
/// Create a `ControlFlow` from any type implementing `Try`.
|
||||||
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -80,7 +80,7 @@ impl<R: Try> ControlFlow<R::Ok, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> ControlFlow<(), B> {
|
impl<B> ControlFlow<B, ()> {
|
||||||
/// It's frequently the case that there's no value needed with `Continue`,
|
/// 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.
|
/// so this provides a way to avoid typing `(())`, if you prefer it.
|
||||||
///
|
///
|
||||||
|
@ -102,7 +102,7 @@ impl<B> ControlFlow<(), B> {
|
||||||
pub const CONTINUE: Self = ControlFlow::Continue(());
|
pub const CONTINUE: Self = ControlFlow::Continue(());
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C> ControlFlow<C, ()> {
|
impl<C> ControlFlow<(), C> {
|
||||||
/// APIs like `try_for_each` don't need values with `Break`,
|
/// APIs like `try_for_each` don't need values with `Break`,
|
||||||
/// so this provides a way to avoid typing `(())`, if you prefer it.
|
/// so this provides a way to avoid typing `(())`, if you prefer it.
|
||||||
///
|
///
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue