Skip to content

Commit

Permalink
Add BREAK too, and improve the comments
Browse files Browse the repository at this point in the history
  • Loading branch information
scottmcm committed Sep 4, 2020
1 parent fac2726 commit 59e3733
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 8 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_data_structures/src/graph/iterate/mod.rs
Expand Up @@ -286,7 +286,7 @@ where
prior_status: Option<NodeStatus>,
) -> ControlFlow<Self::BreakVal> {
match prior_status {
Some(NodeStatus::Visited) => ControlFlow::Break(()),
Some(NodeStatus::Visited) => ControlFlow::BREAK,
_ => ControlFlow::CONTINUE,
}
}
Expand Down
14 changes: 7 additions & 7 deletions library/core/src/iter/traits/iterator.rs
Expand Up @@ -2086,10 +2086,10 @@ pub trait Iterator {
#[inline]
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> {
move |(), x| {
if f(x) { ControlFlow::Continue(()) } else { ControlFlow::Break(()) }
if f(x) { ControlFlow::CONTINUE } else { ControlFlow::BREAK }
}
}
self.try_fold((), check(f)) == ControlFlow::Continue(())
self.try_fold((), check(f)) == ControlFlow::CONTINUE
}

/// Tests if any element of the iterator matches a predicate.
Expand Down Expand Up @@ -2139,11 +2139,11 @@ pub trait Iterator {
#[inline]
fn check<T>(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> {
move |(), x| {
if f(x) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) }
if f(x) { ControlFlow::BREAK } else { ControlFlow::CONTINUE }
}
}

self.try_fold((), check(f)) == ControlFlow::Break(())
self.try_fold((), check(f)) == ControlFlow::BREAK
}

/// Searches for an element of an iterator that satisfies a predicate.
Expand Down Expand Up @@ -2201,7 +2201,7 @@ pub trait Iterator {
mut predicate: impl FnMut(&T) -> bool,
) -> impl FnMut((), T) -> ControlFlow<(), T> {
move |(), x| {
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) }
if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE }
}
}

Expand Down Expand Up @@ -2236,7 +2236,7 @@ pub trait Iterator {
) -> impl FnMut((), T) -> ControlFlow<(), B> {
move |(), x| match f(x) {
Some(x) => ControlFlow::Break(x),
None => ControlFlow::Continue(()),
None => ControlFlow::CONTINUE,
}
}

Expand Down Expand Up @@ -2278,7 +2278,7 @@ pub trait Iterator {
R: Try<Ok = bool>,
{
move |(), x| match f(&x).into_result() {
Ok(false) => ControlFlow::Continue(()),
Ok(false) => ControlFlow::CONTINUE,
Ok(true) => ControlFlow::Break(Ok(x)),
Err(x) => ControlFlow::Break(Err(x)),
}
Expand Down
36 changes: 36 additions & 0 deletions library/core/src/ops/control_flow.rs
Expand Up @@ -69,6 +69,42 @@ impl<R: Try> ControlFlow<R::Ok, R> {
impl<B> ControlFlow<(), B> {
/// 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.
///
/// # Examples
///
/// ```
/// #![feature(control_flow_enum)]
/// use std::ops::ControlFlow;
///
/// let mut partial_sum = 0;
/// let last_used = (1..10).chain(20..25).try_for_each(|x| {
/// partial_sum += x;
/// if partial_sum > 100 { ControlFlow::Break(x) }
/// else { ControlFlow::CONTINUE }
/// });
/// assert_eq!(last_used.break_value(), Some(22));
/// ```
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
pub const CONTINUE: Self = ControlFlow::Continue(());
}

impl<C> 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.
///
/// # Examples
///
/// ```
/// #![feature(control_flow_enum)]
/// use std::ops::ControlFlow;
///
/// let mut partial_sum = 0;
/// (1..10).chain(20..25).try_for_each(|x| {
/// if partial_sum > 100 { ControlFlow::BREAK }
/// else { partial_sum += x; ControlFlow::CONTINUE }
/// });
/// assert_eq!(partial_sum, 108);
/// ```
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
pub const BREAK: Self = ControlFlow::Break(());
}

0 comments on commit 59e3733

Please sign in to comment.