about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-08-02 23:55:12 +0000
committerbors <bors@rust-lang.org>2020-08-02 23:55:12 +0000
commit19ecce332e56941ea0dd2a805270faa102acdb14 (patch)
tree8b73f9e433d646360167a81d4fbfb12c166e97fa
parent81e754c359c471f91263813c46c67955071716a7 (diff)
parent6d293ede9f0790e1a450113bfbda0998fec9e48c (diff)
downloadrust-19ecce332e56941ea0dd2a805270faa102acdb14.tar.gz
rust-19ecce332e56941ea0dd2a805270faa102acdb14.zip
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
-rw-r--r--library/core/src/result.rs28
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/result.rs127
-rw-r--r--library/proc_macro/src/lib.rs1
-rw-r--r--src/librustc_builtin_macros/lib.rs1
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs2
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr2
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr13
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs2
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr4
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr13
13 files changed, 14 insertions, 192 deletions
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 0c0e6d291bb..e68dbf5215f 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -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`.
     ///
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 6b28a815f03..b4c299d3905 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -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)]
diff --git a/library/core/tests/result.rs b/library/core/tests/result.rs
index c835313aae7..caa2d916cd7 100644
--- a/library/core/tests/result.rs
+++ b/library/core/tests/result.rs
@@ -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);
 }
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index c050a3c591c..42ba7f5c025 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -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)]
diff --git a/src/librustc_builtin_macros/lib.rs b/src/librustc_builtin_macros/lib.rs
index 173a823dc7d..87be6d1743a 100644
--- a/src/librustc_builtin_macros/lib.rs
+++ b/src/librustc_builtin_macros/lib.rs
@@ -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)]
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs
index 1d5eabd6170..f713dee507f 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs
@@ -1,5 +1,3 @@
-#![feature(inner_deref)]
-
 fn main() {
     let _result = &Ok(42).as_deref();
 //~^ ERROR no method named `as_deref` found
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr
index f33e9c7823e..96524c30959 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr
@@ -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`
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs
deleted file mode 100644
index 104aa3bcadf..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(inner_deref)]
-
-fn main() {
-    let _result = &Err(41).as_deref_err();
-//~^ ERROR no method named `as_deref_err` found
-}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr
deleted file mode 100644
index 68ebfab95c4..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr
+++ /dev/null
@@ -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`.
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs
index c897ab3531f..3af7033dd5d 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs
@@ -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
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
index d2ba1049b76..73266bc7f68 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
@@ -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`
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs
deleted file mode 100644
index b7849ecb6d2..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs
+++ /dev/null
@@ -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
-}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr
deleted file mode 100644
index d724ae5c74b..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr
+++ /dev/null
@@ -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`.