Auto merge of #74948 - lzutao:stalize-result-as-deref, r=dtolnay
Stabilize `Result::as_deref` and `as_deref_mut` FCP completed in https://github.com/rust-lang/rust/issues/50264#issuecomment-645681400. This PR stabilizes two new APIs for `std::result::Result`: ```rust fn as_deref(&self) -> Result<&T::Target, &E> where T: Deref; fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E> where T: DerefMut; ``` This PR also removes two rarely used unstable APIs from `Result`: ```rust fn as_deref_err(&self) -> Result<&T, &E::Target> where E: Deref; fn as_deref_mut_err(&mut self) -> Result<&mut T, &mut E::Target> where E: DerefMut; ``` Closes #50264
This commit is contained in:
commit
19ecce332e
@ -1145,7 +1145,6 @@ impl<T, E: Into<!>> Result<T, E> {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "inner_deref", issue = "50264")]
|
||||
impl<T: Deref, E> Result<T, E> {
|
||||
/// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&<T as Deref>::Target, &E>`.
|
||||
///
|
||||
@ -1155,7 +1154,6 @@ impl<T: Deref, E> Result<T, E> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inner_deref)]
|
||||
/// let x: Result<String, u32> = Ok("hello".to_string());
|
||||
/// let y: Result<&str, &u32> = Ok("hello");
|
||||
/// assert_eq!(x.as_deref(), y);
|
||||
@ -1164,23 +1162,12 @@ impl<T: Deref, E> Result<T, E> {
|
||||
/// let y: Result<&str, &u32> = Err(&42);
|
||||
/// assert_eq!(x.as_deref(), y);
|
||||
/// ```
|
||||
#[stable(feature = "inner_deref", since = "1.47.0")]
|
||||
pub fn as_deref(&self) -> Result<&T::Target, &E> {
|
||||
self.as_ref().map(|t| t.deref())
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "inner_deref", issue = "50264")]
|
||||
impl<T, E: Deref> Result<T, E> {
|
||||
/// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&T, &<E as Deref>::Target>`.
|
||||
///
|
||||
/// Coerces the [`Err`] variant of the original [`Result`] via [`Deref`](crate::ops::Deref)
|
||||
/// and returns the new [`Result`].
|
||||
pub fn as_deref_err(&self) -> Result<&T, &E::Target> {
|
||||
self.as_ref().map_err(|e| e.deref())
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "inner_deref", issue = "50264")]
|
||||
impl<T: DerefMut, E> Result<T, E> {
|
||||
/// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut <T as DerefMut>::Target, &mut E>`.
|
||||
///
|
||||
@ -1190,7 +1177,6 @@ impl<T: DerefMut, E> Result<T, E> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inner_deref)]
|
||||
/// let mut s = "HELLO".to_string();
|
||||
/// let mut x: Result<String, u32> = Ok("hello".to_string());
|
||||
/// let y: Result<&mut str, &mut u32> = Ok(&mut s);
|
||||
@ -1201,22 +1187,12 @@ impl<T: DerefMut, E> Result<T, E> {
|
||||
/// let y: Result<&mut str, &mut u32> = Err(&mut i);
|
||||
/// assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y);
|
||||
/// ```
|
||||
#[stable(feature = "inner_deref", since = "1.47.0")]
|
||||
pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E> {
|
||||
self.as_mut().map(|t| t.deref_mut())
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "inner_deref", issue = "50264")]
|
||||
impl<T, E: DerefMut> Result<T, E> {
|
||||
/// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut T, &mut <E as DerefMut>::Target>`.
|
||||
///
|
||||
/// Coerces the [`Err`] variant of the original [`Result`] via [`DerefMut`](crate::ops::DerefMut)
|
||||
/// and returns the new [`Result`].
|
||||
pub fn as_deref_mut_err(&mut self) -> Result<&mut T, &mut E::Target> {
|
||||
self.as_mut().map_err(|e| e.deref_mut())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> Result<Option<T>, E> {
|
||||
/// Transposes a `Result` of an `Option` into an `Option` of a `Result`.
|
||||
///
|
||||
|
@ -27,7 +27,6 @@
|
||||
#![feature(test)]
|
||||
#![feature(trusted_len)]
|
||||
#![feature(try_trait)]
|
||||
#![feature(inner_deref)]
|
||||
#![feature(slice_internals)]
|
||||
#![feature(slice_partition_dedup)]
|
||||
#![feature(int_error_matching)]
|
||||
|
@ -250,24 +250,11 @@ fn test_result_as_deref() {
|
||||
let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice());
|
||||
assert_eq!(ref_ok.as_deref(), expected_result);
|
||||
|
||||
// &Result<T, E: Deref>::Err(T).as_deref_err() ->
|
||||
// Result<&T, &E::Deref::Target>::Err(&*E)
|
||||
let ref_err = &Result::Err::<u8, &i32>(&41);
|
||||
let expected_result = Result::Err::<&u8, &i32>(&41);
|
||||
assert_eq!(ref_err.as_deref_err(), expected_result);
|
||||
|
||||
let ref_err = &Result::Err::<u32, String>(String::from("an error"));
|
||||
let expected_result = Result::Err::<&u32, &str>("an error");
|
||||
assert_eq!(ref_err.as_deref_err(), expected_result);
|
||||
|
||||
let ref_err = &Result::Err::<u32, Vec<i32>>(vec![5, 4, 3, 2, 1]);
|
||||
let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice());
|
||||
assert_eq!(ref_err.as_deref_err(), expected_result);
|
||||
|
||||
// &Result<T: Deref, E: Deref>::Err(T).as_deref_err() ->
|
||||
// Result<&T, &E::Deref::Target>::Err(&*E)
|
||||
let ref_err = &Result::Err::<&u8, &i32>(&41);
|
||||
let expected_result = Result::Err::<&u8, &&i32>(&&41);
|
||||
// &Result<T: Deref, E>::Err(T).as_deref() ->
|
||||
// Result<&T::Deref::Target, &E>::Err(&*E)
|
||||
let val = 41;
|
||||
let ref_err = &Result::Err::<&u8, i32>(val);
|
||||
let expected_result = Result::Err::<&u8, &i32>(&val);
|
||||
assert_eq!(ref_err.as_deref(), expected_result);
|
||||
|
||||
let s = String::from("an error");
|
||||
@ -279,46 +266,12 @@ fn test_result_as_deref() {
|
||||
let ref_err = &Result::Err::<&u32, Vec<i32>>(v.clone());
|
||||
let expected_result = Result::Err::<&u32, &Vec<i32>>(&v);
|
||||
assert_eq!(ref_err.as_deref(), expected_result);
|
||||
|
||||
// The following cases test calling `as_deref_*` with the wrong variant (i.e.
|
||||
// `as_deref()` with a `Result::Err()`, or `as_deref_err()` with a `Result::Ok()`.
|
||||
// While uncommon, these cases are supported to ensure that an `as_deref_*`
|
||||
// call can still be made even when one of the Result types does not implement
|
||||
// `Deref` (for example, std::io::Error).
|
||||
|
||||
// &Result<T, E: Deref>::Ok(T).as_deref_err() ->
|
||||
// Result<&T, &E::Deref::Target>::Ok(&T)
|
||||
let ref_ok = &Result::Ok::<i32, &u8>(42);
|
||||
let expected_result = Result::Ok::<&i32, &u8>(&42);
|
||||
assert_eq!(ref_ok.as_deref_err(), expected_result);
|
||||
|
||||
let ref_ok = &Result::Ok::<&str, &u32>("a result");
|
||||
let expected_result = Result::Ok::<&&str, &u32>(&"a result");
|
||||
assert_eq!(ref_ok.as_deref_err(), expected_result);
|
||||
|
||||
let ref_ok = &Result::Ok::<[i32; 5], &u32>([1, 2, 3, 4, 5]);
|
||||
let expected_result = Result::Ok::<&[i32; 5], &u32>(&[1, 2, 3, 4, 5]);
|
||||
assert_eq!(ref_ok.as_deref_err(), expected_result);
|
||||
|
||||
// &Result<T: Deref, E>::Err(E).as_deref() ->
|
||||
// Result<&T::Deref::Target, &E>::Err(&E)
|
||||
let ref_err = &Result::Err::<&u8, i32>(41);
|
||||
let expected_result = Result::Err::<&u8, &i32>(&41);
|
||||
assert_eq!(ref_err.as_deref(), expected_result);
|
||||
|
||||
let ref_err = &Result::Err::<&u32, &str>("an error");
|
||||
let expected_result = Result::Err::<&u32, &&str>(&"an error");
|
||||
assert_eq!(ref_err.as_deref(), expected_result);
|
||||
|
||||
let ref_err = &Result::Err::<&u32, [i32; 5]>([5, 4, 3, 2, 1]);
|
||||
let expected_result = Result::Err::<&u32, &[i32; 5]>(&[5, 4, 3, 2, 1]);
|
||||
assert_eq!(ref_err.as_deref(), expected_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_result_as_deref_mut() {
|
||||
// &mut Result<T: Deref, E>::Ok(T).as_deref_mut() ->
|
||||
// Result<&mut T::Deref::Target, &mut E>::Ok(&mut *T)
|
||||
// &mut Result<T: DerefMut, E>::Ok(T).as_deref_mut() ->
|
||||
// Result<&mut T::DerefMut::Target, &mut E>::Ok(&mut *T)
|
||||
let mut val = 42;
|
||||
let mut expected_val = 42;
|
||||
let mut_ok = &mut Result::Ok::<&mut i32, u8>(&mut val);
|
||||
@ -335,26 +288,8 @@ fn test_result_as_deref_mut() {
|
||||
let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice());
|
||||
assert_eq!(mut_ok.as_deref_mut(), expected_result);
|
||||
|
||||
// &mut Result<T, E: Deref>::Err(T).as_deref_mut_err() ->
|
||||
// Result<&mut T, &mut E::Deref::Target>::Err(&mut *E)
|
||||
let mut val = 41;
|
||||
let mut expected_val = 41;
|
||||
let mut_err = &mut Result::Err::<u8, &mut i32>(&mut val);
|
||||
let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
|
||||
assert_eq!(mut_err.as_deref_mut_err(), expected_result);
|
||||
|
||||
let mut expected_string = String::from("an error");
|
||||
let mut_err = &mut Result::Err::<u32, String>(expected_string.clone());
|
||||
let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.deref_mut());
|
||||
assert_eq!(mut_err.as_deref_mut_err(), expected_result);
|
||||
|
||||
let mut expected_vec = vec![5, 4, 3, 2, 1];
|
||||
let mut_err = &mut Result::Err::<u32, Vec<i32>>(expected_vec.clone());
|
||||
let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice());
|
||||
assert_eq!(mut_err.as_deref_mut_err(), expected_result);
|
||||
|
||||
// &mut Result<T: Deref, E: Deref>::Err(T).as_deref_mut_err() ->
|
||||
// Result<&mut T, &mut E::Deref::Target>::Err(&mut *E)
|
||||
// &mut Result<T: DerefMut, E>::Err(T).as_deref_mut() ->
|
||||
// Result<&mut T, &mut E>::Err(&mut *E)
|
||||
let mut val = 41;
|
||||
let mut_err = &mut Result::Err::<&mut u8, i32>(val);
|
||||
let expected_result = Result::Err::<&mut u8, &mut i32>(&mut val);
|
||||
@ -369,48 +304,4 @@ fn test_result_as_deref_mut() {
|
||||
let mut_err = &mut Result::Err::<&mut u32, Vec<i32>>(expected_vec.clone());
|
||||
let expected_result = Result::Err::<&mut u32, &mut Vec<i32>>(&mut expected_vec);
|
||||
assert_eq!(mut_err.as_deref_mut(), expected_result);
|
||||
|
||||
// The following cases test calling `as_deref_mut_*` with the wrong variant (i.e.
|
||||
// `as_deref_mut()` with a `Result::Err()`, or `as_deref_mut_err()` with a `Result::Ok()`.
|
||||
// While uncommon, these cases are supported to ensure that an `as_deref_mut_*`
|
||||
// call can still be made even when one of the Result types does not implement
|
||||
// `Deref` (for example, std::io::Error).
|
||||
|
||||
// &mut Result<T, E: Deref>::Ok(T).as_deref_mut_err() ->
|
||||
// Result<&mut T, &mut E::Deref::Target>::Ok(&mut T)
|
||||
let mut expected_val = 42;
|
||||
let mut_ok = &mut Result::Ok::<i32, &mut u8>(expected_val.clone());
|
||||
let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val);
|
||||
assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
|
||||
|
||||
let string = String::from("a result");
|
||||
let expected_string = string.clone();
|
||||
let mut ref_str = expected_string.as_ref();
|
||||
let mut_ok = &mut Result::Ok::<&str, &mut u32>(string.as_str());
|
||||
let expected_result = Result::Ok::<&mut &str, &mut u32>(&mut ref_str);
|
||||
assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
|
||||
|
||||
let mut expected_arr = [1, 2, 3, 4, 5];
|
||||
let mut_ok = &mut Result::Ok::<[i32; 5], &mut u32>(expected_arr.clone());
|
||||
let expected_result = Result::Ok::<&mut [i32; 5], &mut u32>(&mut expected_arr);
|
||||
assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
|
||||
|
||||
// &mut Result<T: Deref, E>::Err(E).as_deref_mut() ->
|
||||
// Result<&mut T::Deref::Target, &mut E>::Err(&mut E)
|
||||
let mut expected_val = 41;
|
||||
let mut_err = &mut Result::Err::<&mut u8, i32>(expected_val.clone());
|
||||
let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
|
||||
assert_eq!(mut_err.as_deref_mut(), expected_result);
|
||||
|
||||
let string = String::from("an error");
|
||||
let expected_string = string.clone();
|
||||
let mut ref_str = expected_string.as_ref();
|
||||
let mut_err = &mut Result::Err::<&mut u32, &str>(string.as_str());
|
||||
let expected_result = Result::Err::<&mut u32, &mut &str>(&mut ref_str);
|
||||
assert_eq!(mut_err.as_deref_mut(), expected_result);
|
||||
|
||||
let mut expected_arr = [5, 4, 3, 2, 1];
|
||||
let mut_err = &mut Result::Err::<&mut u32, [i32; 5]>(expected_arr.clone());
|
||||
let expected_result = Result::Err::<&mut u32, &mut [i32; 5]>(&mut expected_arr);
|
||||
assert_eq!(mut_err.as_deref_mut(), expected_result);
|
||||
}
|
||||
|
@ -24,7 +24,6 @@
|
||||
#![feature(decl_macro)]
|
||||
#![feature(extern_types)]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(inner_deref)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(restricted_std)]
|
||||
|
@ -5,7 +5,6 @@
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(inner_deref)]
|
||||
#![feature(nll)]
|
||||
#![feature(or_patterns)]
|
||||
#![feature(proc_macro_internals)]
|
||||
|
@ -1,5 +1,3 @@
|
||||
#![feature(inner_deref)]
|
||||
|
||||
fn main() {
|
||||
let _result = &Ok(42).as_deref();
|
||||
//~^ ERROR no method named `as_deref` found
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0599]: no method named `as_deref` found for enum `std::result::Result<{integer}, _>` in the current scope
|
||||
--> $DIR/result-as_deref.rs:4:27
|
||||
--> $DIR/result-as_deref.rs:2:27
|
||||
|
|
||||
LL | let _result = &Ok(42).as_deref();
|
||||
| ^^^^^^^^ help: there is an associated function with a similar name: `as_ref`
|
||||
|
@ -1,6 +0,0 @@
|
||||
#![feature(inner_deref)]
|
||||
|
||||
fn main() {
|
||||
let _result = &Err(41).as_deref_err();
|
||||
//~^ ERROR no method named `as_deref_err` found
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
error[E0599]: no method named `as_deref_err` found for enum `std::result::Result<_, {integer}>` in the current scope
|
||||
--> $DIR/result-as_deref_err.rs:4:28
|
||||
|
|
||||
LL | let _result = &Err(41).as_deref_err();
|
||||
| ^^^^^^^^^^^^ help: there is an associated function with a similar name: `as_deref_mut`
|
||||
|
|
||||
= note: the method `as_deref_err` exists but the following trait bounds were not satisfied:
|
||||
`{integer}: std::ops::Deref`
|
||||
`<{integer} as std::ops::Deref>::Target = _`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
@ -1,5 +1,3 @@
|
||||
#![feature(inner_deref)]
|
||||
|
||||
fn main() {
|
||||
let _result = &mut Ok(42).as_deref_mut();
|
||||
//~^ ERROR no method named `as_deref_mut` found
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0599]: no method named `as_deref_mut` found for enum `std::result::Result<{integer}, _>` in the current scope
|
||||
--> $DIR/result-as_deref_mut.rs:4:31
|
||||
--> $DIR/result-as_deref_mut.rs:2:31
|
||||
|
|
||||
LL | let _result = &mut Ok(42).as_deref_mut();
|
||||
| ^^^^^^^^^^^^ help: there is an associated function with a similar name: `as_deref_err`
|
||||
| ^^^^^^^^^^^^ method not found in `std::result::Result<{integer}, _>`
|
||||
|
|
||||
= note: the method `as_deref_mut` exists but the following trait bounds were not satisfied:
|
||||
`{integer}: std::ops::DerefMut`
|
||||
|
@ -1,6 +0,0 @@
|
||||
#![feature(inner_deref)]
|
||||
|
||||
fn main() {
|
||||
let _result = &mut Err(41).as_deref_mut_err();
|
||||
//~^ ERROR no method named `as_deref_mut_err` found
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
error[E0599]: no method named `as_deref_mut_err` found for enum `std::result::Result<_, {integer}>` in the current scope
|
||||
--> $DIR/result-as_deref_mut_err.rs:4:32
|
||||
|
|
||||
LL | let _result = &mut Err(41).as_deref_mut_err();
|
||||
| ^^^^^^^^^^^^^^^^ help: there is an associated function with a similar name: `as_deref_mut`
|
||||
|
|
||||
= note: the method `as_deref_mut_err` exists but the following trait bounds were not satisfied:
|
||||
`{integer}: std::ops::DerefMut`
|
||||
`<{integer} as std::ops::Deref>::Target = _`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
Loading…
Reference in New Issue
Block a user