Rollup merge of #130518 - scottmcm:stabilize-controlflow-extra, r=dtolnay
Stabilize the `map`/`value` methods on `ControlFlow` And fix the stability attribute on the `pub use` in `core::ops`. libs-api in https://github.com/rust-lang/rust/issues/75744#issuecomment-2231214910 seemed reasonably happy with naming for these, so let's try for an FCP. Summary: ```rust impl<B, C> ControlFlow<B, C> { pub fn break_value(self) -> Option<B>; pub fn map_break<T>(self, f: impl FnOnce(B) -> T) -> ControlFlow<T, C>; pub fn continue_value(self) -> Option<C>; pub fn map_continue<T>(self, f: impl FnOnce(C) -> T) -> ControlFlow<B, T>; } ``` Resolves #75744 ``@rustbot`` label +needs-fcp +t-libs-api -t-libs --- Aside, in case it keeps someone else from going down the same dead end: I looked at the `{break,continue}_value` methods and tried to make them `const` as part of this, but that's disallowed because of not having `const Drop`, so put it back to not even unstably-const.
This commit is contained in:
commit
5a8fcab713
@ -5,7 +5,6 @@
|
||||
#![doc(rust_logo)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(file_buffered)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(never_type)]
|
||||
|
@ -62,7 +62,6 @@
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![doc(rust_logo)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(let_chains)]
|
||||
|
@ -3,7 +3,6 @@
|
||||
#![allow(rustc::untranslatable_diagnostic)]
|
||||
#![feature(array_windows)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(never_type)]
|
||||
|
@ -20,7 +20,6 @@
|
||||
#![doc(rust_logo)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(extend_one)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_intersperse)]
|
||||
|
@ -32,7 +32,6 @@
|
||||
#![feature(array_windows)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(extract_if)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_order_by)]
|
||||
|
@ -2,7 +2,6 @@
|
||||
#![allow(internal_features)]
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![doc(rust_logo)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(coroutines)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(error_iter)]
|
||||
|
@ -20,7 +20,6 @@
|
||||
#![feature(associated_type_defaults)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(cfg_version)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(extract_if)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_intersperse)]
|
||||
|
@ -171,14 +171,13 @@ pub fn is_continue(&self) -> bool {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(control_flow_enum)]
|
||||
/// use std::ops::ControlFlow;
|
||||
///
|
||||
/// assert_eq!(ControlFlow::<i32, String>::Break(3).break_value(), Some(3));
|
||||
/// assert_eq!(ControlFlow::<String, i32>::Continue(3).break_value(), None);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
||||
#[stable(feature = "control_flow_enum", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub fn break_value(self) -> Option<B> {
|
||||
match self {
|
||||
ControlFlow::Continue(..) => None,
|
||||
@ -189,11 +188,8 @@ pub fn break_value(self) -> Option<B> {
|
||||
/// Maps `ControlFlow<B, C>` to `ControlFlow<T, C>` by applying a function
|
||||
/// to the break value in case it exists.
|
||||
#[inline]
|
||||
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
||||
pub fn map_break<T, F>(self, f: F) -> ControlFlow<T, C>
|
||||
where
|
||||
F: FnOnce(B) -> T,
|
||||
{
|
||||
#[stable(feature = "control_flow_enum", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub fn map_break<T>(self, f: impl FnOnce(B) -> T) -> ControlFlow<T, C> {
|
||||
match self {
|
||||
ControlFlow::Continue(x) => ControlFlow::Continue(x),
|
||||
ControlFlow::Break(x) => ControlFlow::Break(f(x)),
|
||||
@ -206,14 +202,13 @@ pub fn map_break<T, F>(self, f: F) -> ControlFlow<T, C>
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(control_flow_enum)]
|
||||
/// use std::ops::ControlFlow;
|
||||
///
|
||||
/// assert_eq!(ControlFlow::<i32, String>::Break(3).continue_value(), None);
|
||||
/// assert_eq!(ControlFlow::<String, i32>::Continue(3).continue_value(), Some(3));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
||||
#[stable(feature = "control_flow_enum", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub fn continue_value(self) -> Option<C> {
|
||||
match self {
|
||||
ControlFlow::Continue(x) => Some(x),
|
||||
@ -224,11 +219,8 @@ pub fn continue_value(self) -> Option<C> {
|
||||
/// Maps `ControlFlow<B, C>` to `ControlFlow<B, T>` by applying a function
|
||||
/// to the continue value in case it exists.
|
||||
#[inline]
|
||||
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
||||
pub fn map_continue<T, F>(self, f: F) -> ControlFlow<B, T>
|
||||
where
|
||||
F: FnOnce(C) -> T,
|
||||
{
|
||||
#[stable(feature = "control_flow_enum", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub fn map_continue<T>(self, f: impl FnOnce(C) -> T) -> ControlFlow<B, T> {
|
||||
match self {
|
||||
ControlFlow::Continue(x) => ControlFlow::Continue(f(x)),
|
||||
ControlFlow::Break(x) => ControlFlow::Break(x),
|
||||
|
@ -162,7 +162,7 @@
|
||||
pub use self::bit::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
|
||||
#[stable(feature = "op_assign_traits", since = "1.8.0")]
|
||||
pub use self::bit::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign};
|
||||
#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
|
||||
#[stable(feature = "control_flow_enum_type", since = "1.55.0")]
|
||||
pub use self::control_flow::ControlFlow;
|
||||
#[unstable(feature = "coroutine_trait", issue = "43122")]
|
||||
pub use self::coroutine::{Coroutine, CoroutineState};
|
||||
|
@ -1,7 +1,6 @@
|
||||
#![feature(array_windows)]
|
||||
#![feature(binary_heap_into_iter_sorted)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(f128)]
|
||||
#![feature(f16)]
|
||||
#![feature(if_let_guard)]
|
||||
|
@ -1,6 +1,5 @@
|
||||
#![feature(array_chunks)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(f128)]
|
||||
#![feature(f16)]
|
||||
#![feature(if_let_guard)]
|
||||
|
@ -2,7 +2,6 @@
|
||||
//@ compile-flags: -Zmir-enable-passes=+Inline
|
||||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(try_trait_v2)]
|
||||
#![feature(custom_mir, core_intrinsics, rustc_attrs)]
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
// skip-filecheck
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(try_trait_v2)]
|
||||
|
||||
//@ compile-flags: -Zunsound-mir-opts
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(ascii_char, ascii_char_variants)]
|
||||
|
||||
extern crate rustc_hir;
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(ascii_char, ascii_char_variants)]
|
||||
|
||||
extern crate rustc_hir;
|
||||
|
@ -7,7 +7,6 @@
|
||||
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
extern crate rustc_hir;
|
||||
#[macro_use]
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_smir;
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_smir;
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
extern crate rustc_middle;
|
||||
#[macro_use]
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_smir;
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_smir;
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_smir;
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(ascii_char, ascii_char_variants)]
|
||||
|
||||
extern crate rustc_hir;
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_smir;
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
extern crate rustc_hir;
|
||||
#[macro_use]
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
extern crate rustc_hir;
|
||||
#[macro_use]
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_smir;
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_smir;
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_smir;
|
||||
|
@ -1,5 +1,3 @@
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
fn result_to_result() -> Result<u64, u8> {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0277]: `?` couldn't convert the error to `u8`
|
||||
--> $DIR/bad-interconversion.rs:6:20
|
||||
--> $DIR/bad-interconversion.rs:4:20
|
||||
|
|
||||
LL | fn result_to_result() -> Result<u64, u8> {
|
||||
| --------------- expected `u8` because of this
|
||||
@ -15,7 +15,7 @@ LL | Ok(Err(123_i32)?)
|
||||
= note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`
|
||||
|
||||
error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
|
||||
--> $DIR/bad-interconversion.rs:11:12
|
||||
--> $DIR/bad-interconversion.rs:9:12
|
||||
|
|
||||
LL | fn option_to_result() -> Result<u64, String> {
|
||||
| -------------------------------------------- this function returns a `Result`
|
||||
@ -26,7 +26,7 @@ LL | Some(3)?;
|
||||
= help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>`
|
||||
|
||||
error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result`
|
||||
--> $DIR/bad-interconversion.rs:17:31
|
||||
--> $DIR/bad-interconversion.rs:15:31
|
||||
|
|
||||
LL | fn control_flow_to_result() -> Result<u64, String> {
|
||||
| -------------------------------------------------- this function returns a `Result`
|
||||
@ -37,7 +37,7 @@ LL | Ok(ControlFlow::Break(123)?)
|
||||
= help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>`
|
||||
|
||||
error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option`
|
||||
--> $DIR/bad-interconversion.rs:22:22
|
||||
--> $DIR/bad-interconversion.rs:20:22
|
||||
|
|
||||
LL | fn result_to_option() -> Option<u16> {
|
||||
| ------------------------------------ this function returns an `Option`
|
||||
@ -48,7 +48,7 @@ LL | Some(Err("hello")?)
|
||||
= help: the trait `FromResidual<Option<Infallible>>` is implemented for `Option<T>`
|
||||
|
||||
error[E0277]: the `?` operator can only be used on `Option`s in a function that returns `Option`
|
||||
--> $DIR/bad-interconversion.rs:27:33
|
||||
--> $DIR/bad-interconversion.rs:25:33
|
||||
|
|
||||
LL | fn control_flow_to_option() -> Option<u64> {
|
||||
| ------------------------------------------ this function returns an `Option`
|
||||
@ -59,7 +59,7 @@ LL | Some(ControlFlow::Break(123)?)
|
||||
= help: the trait `FromResidual<Option<Infallible>>` is implemented for `Option<T>`
|
||||
|
||||
error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
|
||||
--> $DIR/bad-interconversion.rs:32:39
|
||||
--> $DIR/bad-interconversion.rs:30:39
|
||||
|
|
||||
LL | fn result_to_control_flow() -> ControlFlow<String> {
|
||||
| -------------------------------------------------- this function returns a `ControlFlow`
|
||||
@ -71,7 +71,7 @@ LL | ControlFlow::Continue(Err("hello")?)
|
||||
= help: for that trait implementation, expected `ControlFlow<String, Infallible>`, found `Result<Infallible, &str>`
|
||||
|
||||
error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
|
||||
--> $DIR/bad-interconversion.rs:37:12
|
||||
--> $DIR/bad-interconversion.rs:35:12
|
||||
|
|
||||
LL | fn option_to_control_flow() -> ControlFlow<u64> {
|
||||
| ----------------------------------------------- this function returns a `ControlFlow`
|
||||
@ -83,7 +83,7 @@ LL | Some(3)?;
|
||||
= help: for that trait implementation, expected `ControlFlow<u64, Infallible>`, found `Option<Infallible>`
|
||||
|
||||
error[E0277]: the `?` operator in a function that returns `ControlFlow<B, _>` can only be used on other `ControlFlow<B, _>`s (with the same Break type)
|
||||
--> $DIR/bad-interconversion.rs:43:29
|
||||
--> $DIR/bad-interconversion.rs:41:29
|
||||
|
|
||||
LL | fn control_flow_to_control_flow() -> ControlFlow<i64> {
|
||||
| ----------------------------------------------------- this function returns a `ControlFlow`
|
||||
|
@ -1,6 +1,5 @@
|
||||
//@ run-pass
|
||||
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(try_trait_v2)]
|
||||
|
||||
use std::ops::{ControlFlow, FromResidual, Try};
|
||||
|
Loading…
Reference in New Issue
Block a user