Skip to content

Commit 65a0a8b

Browse files
committed
Stabilize ops::ControlFlow (just the type)
1 parent 3bcaeb0 commit 65a0a8b

File tree

8 files changed

+45
-13
lines changed

8 files changed

+45
-13
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ pub fn lower_crate<'a, 'hir>(
332332
lifetimes_to_define: Vec::new(),
333333
is_collecting_in_band_lifetimes: false,
334334
in_scope_lifetimes: Vec::new(),
335-
allow_try_trait: Some([sym::control_flow_enum, sym::try_trait_v2][..].into()),
335+
allow_try_trait: Some([sym::try_trait_v2][..].into()),
336336
allow_gen_future: Some([sym::gen_future][..].into()),
337337
}
338338
.lower_crate(krate)

compiler/rustc_resolve/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
1212
#![feature(box_patterns)]
1313
#![feature(bool_to_option)]
14-
#![feature(control_flow_enum)]
1514
#![feature(crate_visibility_modifier)]
1615
#![feature(format_args_capture)]
1716
#![feature(iter_zip)]

compiler/rustc_span/src/symbol.rs

-1
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,6 @@ symbols! {
414414
constructor,
415415
contents,
416416
context,
417-
control_flow_enum,
418417
convert,
419418
copy,
420419
copy_closures,

compiler/rustc_traits/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#![feature(crate_visibility_modifier)]
55
#![feature(in_band_lifetimes)]
66
#![feature(nll)]
7-
#![feature(control_flow_enum)]
87
#![recursion_limit = "256"]
98

109
#[macro_use]

library/core/src/iter/traits/iterator.rs

+41
Original file line numberDiff line numberDiff line change
@@ -1993,6 +1993,31 @@ pub trait Iterator {
19931993
/// assert_eq!(it.len(), 2);
19941994
/// assert_eq!(it.next(), Some(&40));
19951995
/// ```
1996+
///
1997+
/// While you cannot `break` from a closure, the [`crate::ops::ControlFlow`]
1998+
/// type allows a similar idea:
1999+
///
2000+
/// ```
2001+
/// use std::ops::ControlFlow;
2002+
///
2003+
/// let triangular = (1..30).try_fold(0_i8, |prev, x| {
2004+
/// if let Some(next) = prev.checked_add(x) {
2005+
/// ControlFlow::Continue(next)
2006+
/// } else {
2007+
/// ControlFlow::Break(prev)
2008+
/// }
2009+
/// });
2010+
/// assert_eq!(triangular, ControlFlow::Break(120));
2011+
///
2012+
/// let triangular = (1..30).try_fold(0_u64, |prev, x| {
2013+
/// if let Some(next) = prev.checked_add(x) {
2014+
/// ControlFlow::Continue(next)
2015+
/// } else {
2016+
/// ControlFlow::Break(prev)
2017+
/// }
2018+
/// });
2019+
/// assert_eq!(triangular, ControlFlow::Continue(435));
2020+
/// ```
19962021
#[inline]
19972022
#[stable(feature = "iterator_try_fold", since = "1.27.0")]
19982023
fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
@@ -2035,6 +2060,22 @@ pub trait Iterator {
20352060
/// // It short-circuited, so the remaining items are still in the iterator:
20362061
/// assert_eq!(it.next(), Some("stale_bread.json"));
20372062
/// ```
2063+
///
2064+
/// The [`crate::ops::ControlFlow`] type can be used with this method for the
2065+
/// situations in which you'd use `break` and `continue` in a normal loop:
2066+
///
2067+
/// ```
2068+
/// use std::ops::ControlFlow;
2069+
///
2070+
/// let r = (2..100).try_for_each(|x| {
2071+
/// if 323 % x == 0 {
2072+
/// return ControlFlow::Break(x)
2073+
/// }
2074+
///
2075+
/// ControlFlow::Continue(())
2076+
/// });
2077+
/// assert_eq!(r, ControlFlow::Break(17));
2078+
/// ```
20382079
#[inline]
20392080
#[stable(feature = "iterator_try_fold", since = "1.27.0")]
20402081
fn try_for_each<F, R>(&mut self, f: F) -> R

library/core/src/ops/control_flow.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use crate::{convert, ops};
1111
///
1212
/// Early-exiting from [`Iterator::try_for_each`]:
1313
/// ```
14-
/// #![feature(control_flow_enum)]
1514
/// use std::ops::ControlFlow;
1615
///
1716
/// let r = (2..100).try_for_each(|x| {
@@ -26,7 +25,6 @@ use crate::{convert, ops};
2625
///
2726
/// A basic tree traversal:
2827
/// ```no_run
29-
/// #![feature(control_flow_enum)]
3028
/// use std::ops::ControlFlow;
3129
///
3230
/// pub struct TreeNode<T> {
@@ -48,13 +46,15 @@ use crate::{convert, ops};
4846
/// }
4947
/// }
5048
/// ```
51-
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
49+
#[stable(feature = "control_flow_enum_type", since = "1.54.0")]
5250
#[derive(Debug, Clone, Copy, PartialEq)]
5351
pub enum ControlFlow<B, C = ()> {
5452
/// Move on to the next phase of the operation as normal.
53+
#[stable(feature = "control_flow_enum_type", since = "1.54.0")]
5554
#[cfg_attr(not(bootstrap), lang = "Continue")]
5655
Continue(C),
5756
/// Exit the operation without running subsequent phases.
57+
#[stable(feature = "control_flow_enum_type", since = "1.54.0")]
5858
#[cfg_attr(not(bootstrap), lang = "Break")]
5959
Break(B),
6060
// Yes, the order of the variants doesn't match the type parameters.

library/core/src/ops/try_trait.rs

-5
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ use crate::ops::ControlFlow;
5555
/// into the return type using [`Try::from_output`]:
5656
/// ```
5757
/// # #![feature(try_trait_v2)]
58-
/// # #![feature(control_flow_enum)]
5958
/// # use std::ops::{ControlFlow, Try};
6059
/// fn simple_try_fold_2<A, T, R: Try<Output = A>>(
6160
/// iter: impl Iterator<Item = T>,
@@ -79,7 +78,6 @@ use crate::ops::ControlFlow;
7978
/// recreated from their corresponding residual, so we'll just call it:
8079
/// ```
8180
/// # #![feature(try_trait_v2)]
82-
/// # #![feature(control_flow_enum)]
8381
/// # use std::ops::{ControlFlow, Try};
8482
/// pub fn simple_try_fold_3<A, T, R: Try<Output = A>>(
8583
/// iter: impl Iterator<Item = T>,
@@ -170,7 +168,6 @@ pub trait Try: FromResidual {
170168
///
171169
/// ```
172170
/// #![feature(try_trait_v2)]
173-
/// #![feature(control_flow_enum)]
174171
/// use std::ops::Try;
175172
///
176173
/// assert_eq!(<Result<_, String> as Try>::from_output(3), Ok(3));
@@ -202,7 +199,6 @@ pub trait Try: FromResidual {
202199
///
203200
/// ```
204201
/// #![feature(try_trait_v2)]
205-
/// #![feature(control_flow_enum)]
206202
/// use std::ops::{ControlFlow, Try};
207203
///
208204
/// assert_eq!(Ok::<_, String>(3).branch(), ControlFlow::Continue(3));
@@ -304,7 +300,6 @@ pub trait FromResidual<R = <Self as Try>::Residual> {
304300
///
305301
/// ```
306302
/// #![feature(try_trait_v2)]
307-
/// #![feature(control_flow_enum)]
308303
/// use std::ops::{ControlFlow, FromResidual};
309304
///
310305
/// assert_eq!(Result::<String, i64>::from_residual(Err(3_u8)), Err(3));

library/core/tests/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#![feature(const_ptr_read)]
1616
#![feature(const_ptr_write)]
1717
#![feature(const_ptr_offset)]
18-
#![feature(control_flow_enum)]
1918
#![feature(core_intrinsics)]
2019
#![feature(core_private_bignum)]
2120
#![feature(core_private_diy_float)]

0 commit comments

Comments
 (0)