Stabilize ops::ControlFlow (just the type)
This commit is contained in:
parent
3bcaeb0bf9
commit
65a0a8b386
8 changed files with 45 additions and 13 deletions
|
@ -332,7 +332,7 @@ pub fn lower_crate<'a, 'hir>(
|
||||||
lifetimes_to_define: Vec::new(),
|
lifetimes_to_define: Vec::new(),
|
||||||
is_collecting_in_band_lifetimes: false,
|
is_collecting_in_band_lifetimes: false,
|
||||||
in_scope_lifetimes: Vec::new(),
|
in_scope_lifetimes: Vec::new(),
|
||||||
allow_try_trait: Some([sym::control_flow_enum, sym::try_trait_v2][..].into()),
|
allow_try_trait: Some([sym::try_trait_v2][..].into()),
|
||||||
allow_gen_future: Some([sym::gen_future][..].into()),
|
allow_gen_future: Some([sym::gen_future][..].into()),
|
||||||
}
|
}
|
||||||
.lower_crate(krate)
|
.lower_crate(krate)
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(bool_to_option)]
|
#![feature(bool_to_option)]
|
||||||
#![feature(control_flow_enum)]
|
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(format_args_capture)]
|
#![feature(format_args_capture)]
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
|
|
|
@ -414,7 +414,6 @@ symbols! {
|
||||||
constructor,
|
constructor,
|
||||||
contents,
|
contents,
|
||||||
context,
|
context,
|
||||||
control_flow_enum,
|
|
||||||
convert,
|
convert,
|
||||||
copy,
|
copy,
|
||||||
copy_closures,
|
copy_closures,
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(control_flow_enum)]
|
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -1993,6 +1993,31 @@ pub trait Iterator {
|
||||||
/// assert_eq!(it.len(), 2);
|
/// assert_eq!(it.len(), 2);
|
||||||
/// assert_eq!(it.next(), Some(&40));
|
/// assert_eq!(it.next(), Some(&40));
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// While you cannot `break` from a closure, the [`crate::ops::ControlFlow`]
|
||||||
|
/// type allows a similar idea:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::ops::ControlFlow;
|
||||||
|
///
|
||||||
|
/// let triangular = (1..30).try_fold(0_i8, |prev, x| {
|
||||||
|
/// if let Some(next) = prev.checked_add(x) {
|
||||||
|
/// ControlFlow::Continue(next)
|
||||||
|
/// } else {
|
||||||
|
/// ControlFlow::Break(prev)
|
||||||
|
/// }
|
||||||
|
/// });
|
||||||
|
/// assert_eq!(triangular, ControlFlow::Break(120));
|
||||||
|
///
|
||||||
|
/// let triangular = (1..30).try_fold(0_u64, |prev, x| {
|
||||||
|
/// if let Some(next) = prev.checked_add(x) {
|
||||||
|
/// ControlFlow::Continue(next)
|
||||||
|
/// } else {
|
||||||
|
/// ControlFlow::Break(prev)
|
||||||
|
/// }
|
||||||
|
/// });
|
||||||
|
/// assert_eq!(triangular, ControlFlow::Continue(435));
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "iterator_try_fold", since = "1.27.0")]
|
#[stable(feature = "iterator_try_fold", since = "1.27.0")]
|
||||||
fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
|
fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
|
||||||
|
@ -2035,6 +2060,22 @@ pub trait Iterator {
|
||||||
/// // It short-circuited, so the remaining items are still in the iterator:
|
/// // It short-circuited, so the remaining items are still in the iterator:
|
||||||
/// assert_eq!(it.next(), Some("stale_bread.json"));
|
/// assert_eq!(it.next(), Some("stale_bread.json"));
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// The [`crate::ops::ControlFlow`] type can be used with this method for the
|
||||||
|
/// situations in which you'd use `break` and `continue` in a normal loop:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::ops::ControlFlow;
|
||||||
|
///
|
||||||
|
/// let r = (2..100).try_for_each(|x| {
|
||||||
|
/// if 323 % x == 0 {
|
||||||
|
/// return ControlFlow::Break(x)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// ControlFlow::Continue(())
|
||||||
|
/// });
|
||||||
|
/// assert_eq!(r, ControlFlow::Break(17));
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "iterator_try_fold", since = "1.27.0")]
|
#[stable(feature = "iterator_try_fold", since = "1.27.0")]
|
||||||
fn try_for_each<F, R>(&mut self, f: F) -> R
|
fn try_for_each<F, R>(&mut self, f: F) -> R
|
||||||
|
|
|
@ -11,7 +11,6 @@ use crate::{convert, ops};
|
||||||
///
|
///
|
||||||
/// Early-exiting from [`Iterator::try_for_each`]:
|
/// Early-exiting from [`Iterator::try_for_each`]:
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(control_flow_enum)]
|
|
||||||
/// use std::ops::ControlFlow;
|
/// use std::ops::ControlFlow;
|
||||||
///
|
///
|
||||||
/// let r = (2..100).try_for_each(|x| {
|
/// let r = (2..100).try_for_each(|x| {
|
||||||
|
@ -26,7 +25,6 @@ use crate::{convert, ops};
|
||||||
///
|
///
|
||||||
/// A basic tree traversal:
|
/// A basic tree traversal:
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// #![feature(control_flow_enum)]
|
|
||||||
/// use std::ops::ControlFlow;
|
/// use std::ops::ControlFlow;
|
||||||
///
|
///
|
||||||
/// pub struct TreeNode<T> {
|
/// pub struct TreeNode<T> {
|
||||||
|
@ -48,13 +46,15 @@ use crate::{convert, ops};
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
#[stable(feature = "control_flow_enum_type", since = "1.54.0")]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum ControlFlow<B, C = ()> {
|
pub enum ControlFlow<B, C = ()> {
|
||||||
/// Move on to the next phase of the operation as normal.
|
/// Move on to the next phase of the operation as normal.
|
||||||
|
#[stable(feature = "control_flow_enum_type", since = "1.54.0")]
|
||||||
#[cfg_attr(not(bootstrap), lang = "Continue")]
|
#[cfg_attr(not(bootstrap), lang = "Continue")]
|
||||||
Continue(C),
|
Continue(C),
|
||||||
/// Exit the operation without running subsequent phases.
|
/// Exit the operation without running subsequent phases.
|
||||||
|
#[stable(feature = "control_flow_enum_type", since = "1.54.0")]
|
||||||
#[cfg_attr(not(bootstrap), lang = "Break")]
|
#[cfg_attr(not(bootstrap), lang = "Break")]
|
||||||
Break(B),
|
Break(B),
|
||||||
// Yes, the order of the variants doesn't match the type parameters.
|
// Yes, the order of the variants doesn't match the type parameters.
|
||||||
|
|
|
@ -55,7 +55,6 @@ use crate::ops::ControlFlow;
|
||||||
/// into the return type using [`Try::from_output`]:
|
/// into the return type using [`Try::from_output`]:
|
||||||
/// ```
|
/// ```
|
||||||
/// # #![feature(try_trait_v2)]
|
/// # #![feature(try_trait_v2)]
|
||||||
/// # #![feature(control_flow_enum)]
|
|
||||||
/// # use std::ops::{ControlFlow, Try};
|
/// # use std::ops::{ControlFlow, Try};
|
||||||
/// fn simple_try_fold_2<A, T, R: Try<Output = A>>(
|
/// fn simple_try_fold_2<A, T, R: Try<Output = A>>(
|
||||||
/// iter: impl Iterator<Item = T>,
|
/// iter: impl Iterator<Item = T>,
|
||||||
|
@ -79,7 +78,6 @@ use crate::ops::ControlFlow;
|
||||||
/// recreated from their corresponding residual, so we'll just call it:
|
/// recreated from their corresponding residual, so we'll just call it:
|
||||||
/// ```
|
/// ```
|
||||||
/// # #![feature(try_trait_v2)]
|
/// # #![feature(try_trait_v2)]
|
||||||
/// # #![feature(control_flow_enum)]
|
|
||||||
/// # use std::ops::{ControlFlow, Try};
|
/// # use std::ops::{ControlFlow, Try};
|
||||||
/// pub fn simple_try_fold_3<A, T, R: Try<Output = A>>(
|
/// pub fn simple_try_fold_3<A, T, R: Try<Output = A>>(
|
||||||
/// iter: impl Iterator<Item = T>,
|
/// iter: impl Iterator<Item = T>,
|
||||||
|
@ -170,7 +168,6 @@ pub trait Try: FromResidual {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(try_trait_v2)]
|
/// #![feature(try_trait_v2)]
|
||||||
/// #![feature(control_flow_enum)]
|
|
||||||
/// use std::ops::Try;
|
/// use std::ops::Try;
|
||||||
///
|
///
|
||||||
/// assert_eq!(<Result<_, String> as Try>::from_output(3), Ok(3));
|
/// assert_eq!(<Result<_, String> as Try>::from_output(3), Ok(3));
|
||||||
|
@ -202,7 +199,6 @@ pub trait Try: FromResidual {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(try_trait_v2)]
|
/// #![feature(try_trait_v2)]
|
||||||
/// #![feature(control_flow_enum)]
|
|
||||||
/// use std::ops::{ControlFlow, Try};
|
/// use std::ops::{ControlFlow, Try};
|
||||||
///
|
///
|
||||||
/// assert_eq!(Ok::<_, String>(3).branch(), ControlFlow::Continue(3));
|
/// assert_eq!(Ok::<_, String>(3).branch(), ControlFlow::Continue(3));
|
||||||
|
@ -304,7 +300,6 @@ pub trait FromResidual<R = <Self as Try>::Residual> {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(try_trait_v2)]
|
/// #![feature(try_trait_v2)]
|
||||||
/// #![feature(control_flow_enum)]
|
|
||||||
/// use std::ops::{ControlFlow, FromResidual};
|
/// use std::ops::{ControlFlow, FromResidual};
|
||||||
///
|
///
|
||||||
/// assert_eq!(Result::<String, i64>::from_residual(Err(3_u8)), Err(3));
|
/// assert_eq!(Result::<String, i64>::from_residual(Err(3_u8)), Err(3));
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#![feature(const_ptr_read)]
|
#![feature(const_ptr_read)]
|
||||||
#![feature(const_ptr_write)]
|
#![feature(const_ptr_write)]
|
||||||
#![feature(const_ptr_offset)]
|
#![feature(const_ptr_offset)]
|
||||||
#![feature(control_flow_enum)]
|
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(core_private_bignum)]
|
#![feature(core_private_bignum)]
|
||||||
#![feature(core_private_diy_float)]
|
#![feature(core_private_diy_float)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue