Skip to content

Commit 19ecce3

Browse files
committedAug 2, 2020
Auto merge of rust-lang#74948 - lzutao:stalize-result-as-deref, r=dtolnay
Stabilize `Result::as_deref` and `as_deref_mut` FCP completed in rust-lang#50264 (comment). 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 rust-lang#50264
2 parents 81e754c + 6d293ed commit 19ecce3

13 files changed

+14
-192
lines changed
 

‎library/core/src/result.rs

+2-26
Original file line numberDiff line numberDiff line change
@@ -1145,7 +1145,6 @@ impl<T, E: Into<!>> Result<T, E> {
11451145
}
11461146
}
11471147

1148-
#[unstable(feature = "inner_deref", issue = "50264")]
11491148
impl<T: Deref, E> Result<T, E> {
11501149
/// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&<T as Deref>::Target, &E>`.
11511150
///
@@ -1155,7 +1154,6 @@ impl<T: Deref, E> Result<T, E> {
11551154
/// # Examples
11561155
///
11571156
/// ```
1158-
/// #![feature(inner_deref)]
11591157
/// let x: Result<String, u32> = Ok("hello".to_string());
11601158
/// let y: Result<&str, &u32> = Ok("hello");
11611159
/// assert_eq!(x.as_deref(), y);
@@ -1164,23 +1162,12 @@ impl<T: Deref, E> Result<T, E> {
11641162
/// let y: Result<&str, &u32> = Err(&42);
11651163
/// assert_eq!(x.as_deref(), y);
11661164
/// ```
1165+
#[stable(feature = "inner_deref", since = "1.47.0")]
11671166
pub fn as_deref(&self) -> Result<&T::Target, &E> {
11681167
self.as_ref().map(|t| t.deref())
11691168
}
11701169
}
11711170

1172-
#[unstable(feature = "inner_deref", issue = "50264")]
1173-
impl<T, E: Deref> Result<T, E> {
1174-
/// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&T, &<E as Deref>::Target>`.
1175-
///
1176-
/// Coerces the [`Err`] variant of the original [`Result`] via [`Deref`](crate::ops::Deref)
1177-
/// and returns the new [`Result`].
1178-
pub fn as_deref_err(&self) -> Result<&T, &E::Target> {
1179-
self.as_ref().map_err(|e| e.deref())
1180-
}
1181-
}
1182-
1183-
#[unstable(feature = "inner_deref", issue = "50264")]
11841171
impl<T: DerefMut, E> Result<T, E> {
11851172
/// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut <T as DerefMut>::Target, &mut E>`.
11861173
///
@@ -1190,7 +1177,6 @@ impl<T: DerefMut, E> Result<T, E> {
11901177
/// # Examples
11911178
///
11921179
/// ```
1193-
/// #![feature(inner_deref)]
11941180
/// let mut s = "HELLO".to_string();
11951181
/// let mut x: Result<String, u32> = Ok("hello".to_string());
11961182
/// let y: Result<&mut str, &mut u32> = Ok(&mut s);
@@ -1201,22 +1187,12 @@ impl<T: DerefMut, E> Result<T, E> {
12011187
/// let y: Result<&mut str, &mut u32> = Err(&mut i);
12021188
/// assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y);
12031189
/// ```
1190+
#[stable(feature = "inner_deref", since = "1.47.0")]
12041191
pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E> {
12051192
self.as_mut().map(|t| t.deref_mut())
12061193
}
12071194
}
12081195

1209-
#[unstable(feature = "inner_deref", issue = "50264")]
1210-
impl<T, E: DerefMut> Result<T, E> {
1211-
/// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut T, &mut <E as DerefMut>::Target>`.
1212-
///
1213-
/// Coerces the [`Err`] variant of the original [`Result`] via [`DerefMut`](crate::ops::DerefMut)
1214-
/// and returns the new [`Result`].
1215-
pub fn as_deref_mut_err(&mut self) -> Result<&mut T, &mut E::Target> {
1216-
self.as_mut().map_err(|e| e.deref_mut())
1217-
}
1218-
}
1219-
12201196
impl<T, E> Result<Option<T>, E> {
12211197
/// Transposes a `Result` of an `Option` into an `Option` of a `Result`.
12221198
///

‎library/core/tests/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#![feature(test)]
2828
#![feature(trusted_len)]
2929
#![feature(try_trait)]
30-
#![feature(inner_deref)]
3130
#![feature(slice_internals)]
3231
#![feature(slice_partition_dedup)]
3332
#![feature(int_error_matching)]

‎library/core/tests/result.rs

+9-118
Original file line numberDiff line numberDiff line change
@@ -250,24 +250,11 @@ fn test_result_as_deref() {
250250
let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice());
251251
assert_eq!(ref_ok.as_deref(), expected_result);
252252

253-
// &Result<T, E: Deref>::Err(T).as_deref_err() ->
254-
// Result<&T, &E::Deref::Target>::Err(&*E)
255-
let ref_err = &Result::Err::<u8, &i32>(&41);
256-
let expected_result = Result::Err::<&u8, &i32>(&41);
257-
assert_eq!(ref_err.as_deref_err(), expected_result);
258-
259-
let ref_err = &Result::Err::<u32, String>(String::from("an error"));
260-
let expected_result = Result::Err::<&u32, &str>("an error");
261-
assert_eq!(ref_err.as_deref_err(), expected_result);
262-
263-
let ref_err = &Result::Err::<u32, Vec<i32>>(vec![5, 4, 3, 2, 1]);
264-
let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice());
265-
assert_eq!(ref_err.as_deref_err(), expected_result);
266-
267-
// &Result<T: Deref, E: Deref>::Err(T).as_deref_err() ->
268-
// Result<&T, &E::Deref::Target>::Err(&*E)
269-
let ref_err = &Result::Err::<&u8, &i32>(&41);
270-
let expected_result = Result::Err::<&u8, &&i32>(&&41);
253+
// &Result<T: Deref, E>::Err(T).as_deref() ->
254+
// Result<&T::Deref::Target, &E>::Err(&*E)
255+
let val = 41;
256+
let ref_err = &Result::Err::<&u8, i32>(val);
257+
let expected_result = Result::Err::<&u8, &i32>(&val);
271258
assert_eq!(ref_err.as_deref(), expected_result);
272259

273260
let s = String::from("an error");
@@ -279,46 +266,12 @@ fn test_result_as_deref() {
279266
let ref_err = &Result::Err::<&u32, Vec<i32>>(v.clone());
280267
let expected_result = Result::Err::<&u32, &Vec<i32>>(&v);
281268
assert_eq!(ref_err.as_deref(), expected_result);
282-
283-
// The following cases test calling `as_deref_*` with the wrong variant (i.e.
284-
// `as_deref()` with a `Result::Err()`, or `as_deref_err()` with a `Result::Ok()`.
285-
// While uncommon, these cases are supported to ensure that an `as_deref_*`
286-
// call can still be made even when one of the Result types does not implement
287-
// `Deref` (for example, std::io::Error).
288-
289-
// &Result<T, E: Deref>::Ok(T).as_deref_err() ->
290-
// Result<&T, &E::Deref::Target>::Ok(&T)
291-
let ref_ok = &Result::Ok::<i32, &u8>(42);
292-
let expected_result = Result::Ok::<&i32, &u8>(&42);
293-
assert_eq!(ref_ok.as_deref_err(), expected_result);
294-
295-
let ref_ok = &Result::Ok::<&str, &u32>("a result");
296-
let expected_result = Result::Ok::<&&str, &u32>(&"a result");
297-
assert_eq!(ref_ok.as_deref_err(), expected_result);
298-
299-
let ref_ok = &Result::Ok::<[i32; 5], &u32>([1, 2, 3, 4, 5]);
300-
let expected_result = Result::Ok::<&[i32; 5], &u32>(&[1, 2, 3, 4, 5]);
301-
assert_eq!(ref_ok.as_deref_err(), expected_result);
302-
303-
// &Result<T: Deref, E>::Err(E).as_deref() ->
304-
// Result<&T::Deref::Target, &E>::Err(&E)
305-
let ref_err = &Result::Err::<&u8, i32>(41);
306-
let expected_result = Result::Err::<&u8, &i32>(&41);
307-
assert_eq!(ref_err.as_deref(), expected_result);
308-
309-
let ref_err = &Result::Err::<&u32, &str>("an error");
310-
let expected_result = Result::Err::<&u32, &&str>(&"an error");
311-
assert_eq!(ref_err.as_deref(), expected_result);
312-
313-
let ref_err = &Result::Err::<&u32, [i32; 5]>([5, 4, 3, 2, 1]);
314-
let expected_result = Result::Err::<&u32, &[i32; 5]>(&[5, 4, 3, 2, 1]);
315-
assert_eq!(ref_err.as_deref(), expected_result);
316269
}
317270

318271
#[test]
319272
fn test_result_as_deref_mut() {
320-
// &mut Result<T: Deref, E>::Ok(T).as_deref_mut() ->
321-
// Result<&mut T::Deref::Target, &mut E>::Ok(&mut *T)
273+
// &mut Result<T: DerefMut, E>::Ok(T).as_deref_mut() ->
274+
// Result<&mut T::DerefMut::Target, &mut E>::Ok(&mut *T)
322275
let mut val = 42;
323276
let mut expected_val = 42;
324277
let mut_ok = &mut Result::Ok::<&mut i32, u8>(&mut val);
@@ -335,26 +288,8 @@ fn test_result_as_deref_mut() {
335288
let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice());
336289
assert_eq!(mut_ok.as_deref_mut(), expected_result);
337290

338-
// &mut Result<T, E: Deref>::Err(T).as_deref_mut_err() ->
339-
// Result<&mut T, &mut E::Deref::Target>::Err(&mut *E)
340-
let mut val = 41;
341-
let mut expected_val = 41;
342-
let mut_err = &mut Result::Err::<u8, &mut i32>(&mut val);
343-
let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
344-
assert_eq!(mut_err.as_deref_mut_err(), expected_result);
345-
346-
let mut expected_string = String::from("an error");
347-
let mut_err = &mut Result::Err::<u32, String>(expected_string.clone());
348-
let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.deref_mut());
349-
assert_eq!(mut_err.as_deref_mut_err(), expected_result);
350-
351-
let mut expected_vec = vec![5, 4, 3, 2, 1];
352-
let mut_err = &mut Result::Err::<u32, Vec<i32>>(expected_vec.clone());
353-
let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice());
354-
assert_eq!(mut_err.as_deref_mut_err(), expected_result);
355-
356-
// &mut Result<T: Deref, E: Deref>::Err(T).as_deref_mut_err() ->
357-
// Result<&mut T, &mut E::Deref::Target>::Err(&mut *E)
291+
// &mut Result<T: DerefMut, E>::Err(T).as_deref_mut() ->
292+
// Result<&mut T, &mut E>::Err(&mut *E)
358293
let mut val = 41;
359294
let mut_err = &mut Result::Err::<&mut u8, i32>(val);
360295
let expected_result = Result::Err::<&mut u8, &mut i32>(&mut val);
@@ -369,48 +304,4 @@ fn test_result_as_deref_mut() {
369304
let mut_err = &mut Result::Err::<&mut u32, Vec<i32>>(expected_vec.clone());
370305
let expected_result = Result::Err::<&mut u32, &mut Vec<i32>>(&mut expected_vec);
371306
assert_eq!(mut_err.as_deref_mut(), expected_result);
372-
373-
// The following cases test calling `as_deref_mut_*` with the wrong variant (i.e.
374-
// `as_deref_mut()` with a `Result::Err()`, or `as_deref_mut_err()` with a `Result::Ok()`.
375-
// While uncommon, these cases are supported to ensure that an `as_deref_mut_*`
376-
// call can still be made even when one of the Result types does not implement
377-
// `Deref` (for example, std::io::Error).
378-
379-
// &mut Result<T, E: Deref>::Ok(T).as_deref_mut_err() ->
380-
// Result<&mut T, &mut E::Deref::Target>::Ok(&mut T)
381-
let mut expected_val = 42;
382-
let mut_ok = &mut Result::Ok::<i32, &mut u8>(expected_val.clone());
383-
let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val);
384-
assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
385-
386-
let string = String::from("a result");
387-
let expected_string = string.clone();
388-
let mut ref_str = expected_string.as_ref();
389-
let mut_ok = &mut Result::Ok::<&str, &mut u32>(string.as_str());
390-
let expected_result = Result::Ok::<&mut &str, &mut u32>(&mut ref_str);
391-
assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
392-
393-
let mut expected_arr = [1, 2, 3, 4, 5];
394-
let mut_ok = &mut Result::Ok::<[i32; 5], &mut u32>(expected_arr.clone());
395-
let expected_result = Result::Ok::<&mut [i32; 5], &mut u32>(&mut expected_arr);
396-
assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
397-
398-
// &mut Result<T: Deref, E>::Err(E).as_deref_mut() ->
399-
// Result<&mut T::Deref::Target, &mut E>::Err(&mut E)
400-
let mut expected_val = 41;
401-
let mut_err = &mut Result::Err::<&mut u8, i32>(expected_val.clone());
402-
let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
403-
assert_eq!(mut_err.as_deref_mut(), expected_result);
404-
405-
let string = String::from("an error");
406-
let expected_string = string.clone();
407-
let mut ref_str = expected_string.as_ref();
408-
let mut_err = &mut Result::Err::<&mut u32, &str>(string.as_str());
409-
let expected_result = Result::Err::<&mut u32, &mut &str>(&mut ref_str);
410-
assert_eq!(mut_err.as_deref_mut(), expected_result);
411-
412-
let mut expected_arr = [5, 4, 3, 2, 1];
413-
let mut_err = &mut Result::Err::<&mut u32, [i32; 5]>(expected_arr.clone());
414-
let expected_result = Result::Err::<&mut u32, &mut [i32; 5]>(&mut expected_arr);
415-
assert_eq!(mut_err.as_deref_mut(), expected_result);
416307
}

‎library/proc_macro/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#![feature(decl_macro)]
2525
#![feature(extern_types)]
2626
#![feature(in_band_lifetimes)]
27-
#![feature(inner_deref)]
2827
#![feature(negative_impls)]
2928
#![feature(optin_builtin_traits)]
3029
#![feature(restricted_std)]

‎src/librustc_builtin_macros/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#![feature(bool_to_option)]
66
#![feature(crate_visibility_modifier)]
77
#![feature(decl_macro)]
8-
#![feature(inner_deref)]
98
#![feature(nll)]
109
#![feature(or_patterns)]
1110
#![feature(proc_macro_internals)]

‎src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(inner_deref)]
2-
31
fn main() {
42
let _result = &Ok(42).as_deref();
53
//~^ ERROR no method named `as_deref` found

‎src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0599]: no method named `as_deref` found for enum `std::result::Result<{integer}, _>` in the current scope
2-
--> $DIR/result-as_deref.rs:4:27
2+
--> $DIR/result-as_deref.rs:2:27
33
|
44
LL | let _result = &Ok(42).as_deref();
55
| ^^^^^^^^ help: there is an associated function with a similar name: `as_ref`

‎src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs

-6
This file was deleted.

‎src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr

-13
This file was deleted.

‎src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(inner_deref)]
2-
31
fn main() {
42
let _result = &mut Ok(42).as_deref_mut();
53
//~^ ERROR no method named `as_deref_mut` found

‎src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0599]: no method named `as_deref_mut` found for enum `std::result::Result<{integer}, _>` in the current scope
2-
--> $DIR/result-as_deref_mut.rs:4:31
2+
--> $DIR/result-as_deref_mut.rs:2:31
33
|
44
LL | let _result = &mut Ok(42).as_deref_mut();
5-
| ^^^^^^^^^^^^ help: there is an associated function with a similar name: `as_deref_err`
5+
| ^^^^^^^^^^^^ method not found in `std::result::Result<{integer}, _>`
66
|
77
= note: the method `as_deref_mut` exists but the following trait bounds were not satisfied:
88
`{integer}: std::ops::DerefMut`

‎src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs

-6
This file was deleted.

‎src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr

-13
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.