From 933b92e7f8907b72524ab6bb5a6a919289251845 Mon Sep 17 00:00:00 2001 From: Ethan Brierley Date: Fri, 4 Dec 2020 22:19:59 +0000 Subject: [PATCH 1/4] arrray::try_map --- library/core/src/array/mod.rs | 57 ++++++++++++++++++++++++++++++++++- library/stdarch | 2 +- src/doc/book | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/llvm-project | 2 +- src/tools/cargo | 2 +- src/tools/miri | 2 +- src/tools/rls | 2 +- src/tools/rustfmt | 2 +- 11 files changed, 66 insertions(+), 11 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 71548bec7aaee..b8532033f9719 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -12,7 +12,7 @@ use crate::convert::{Infallible, TryFrom}; use crate::fmt; use crate::hash::{self, Hash}; use crate::marker::Unsize; -use crate::ops::{Index, IndexMut}; +use crate::ops::{Index, IndexMut, Try}; use crate::slice::{Iter, IterMut}; mod iter; @@ -463,6 +463,61 @@ impl [T; N] { unsafe { crate::mem::transmute_copy::<_, [U; N]>(&dst) } } + /// A fallible function `f` applied to each element on array `self` in order to return an array the same size as `self` or the first error encountered. + /// + /// # Examples + /// + /// ``` + /// #![feature(array_try_map)] + /// #![feature(array_map)] + /// let a = ["1", "2", "3"]; + /// let b = a.try_map(|v| v.parse::()).unwrap().map(|v| v + 1); + /// assert_eq!(b, [2, 3, 4]); + /// + /// let a = ["1", "2a", "3"]; + /// let b = a.try_map(|v| v.parse::()); + /// assert!(b.is_err()); + /// ``` + #[unstable(feature = "array_try_map", issue = "75243")] + pub fn try_map(self, mut f: F) -> Result<[U; N], E> + where + F: FnMut(T) -> R, + R: Try, + { + use crate::mem::MaybeUninit; + struct Guard { + dst: *mut T, + initialized: usize, + } + + impl Drop for Guard { + fn drop(&mut self) { + debug_assert!(self.initialized <= N); + + let initialized_part = + crate::ptr::slice_from_raw_parts_mut(self.dst, self.initialized); + // SAFETY: this raw slice will contain only initialized objects + // that's why, it is allowed to drop it. + unsafe { + crate::ptr::drop_in_place(initialized_part); + } + } + } + let mut dst = MaybeUninit::uninit_array::(); + let mut guard: Guard = + Guard { dst: MaybeUninit::slice_as_mut_ptr(&mut dst), initialized: 0 }; + for (src, dst) in IntoIter::new(self).zip(&mut dst) { + dst.write(f(src)?); + guard.initialized += 1; + } + // FIXME: Convert to crate::mem::transmute once it works with generics. + // unsafe { crate::mem::transmute::<[MaybeUninit; N], [U; N]>(dst) } + crate::mem::forget(guard); + // SAFETY: At this point we've properly initialized the whole array + // and we just need to cast it to the correct type. + unsafe { Ok(crate::mem::transmute_copy::<_, [U; N]>(&dst)) } + } + /// 'Zips up' two arrays into a single array of pairs. /// /// `zip()` returns a new array where every element is a tuple where the diff --git a/library/stdarch b/library/stdarch index 9c732a56f67f5..777efaf564470 160000 --- a/library/stdarch +++ b/library/stdarch @@ -1 +1 @@ -Subproject commit 9c732a56f67f54d12a0b4fd99993154906c95ea6 +Subproject commit 777efaf5644706b36706a7a5c51edb63835e05ca diff --git a/src/doc/book b/src/doc/book index 5bb44f8b5b0aa..a190438d77d28 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 5bb44f8b5b0aa105c8b22602e9b18800484afa21 +Subproject commit a190438d77d28041f24da4f6592e287fab073a61 diff --git a/src/doc/nomicon b/src/doc/nomicon index a5a48441d411f..d8383b65f7948 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit a5a48441d411f61556b57d762b03d6874afe575d +Subproject commit d8383b65f7948c2ca19191b3b4bd709b403aaf45 diff --git a/src/doc/reference b/src/doc/reference index b278478b76617..a8afdca5d0715 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit b278478b766178491a8b6f67afa4bcd6b64d977a +Subproject commit a8afdca5d0715b2257b6f8b9a032fd4dd7dae855 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 1cce0737d6a7d..236c734a2cb32 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 1cce0737d6a7d3ceafb139b4a206861fb1dcb2ab +Subproject commit 236c734a2cb323541b3394f98682cb981b9ec086 diff --git a/src/llvm-project b/src/llvm-project index 8d78ad13896b9..7ade8dc4b8414 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 8d78ad13896b955f630714f386a95ed91b237e3d +Subproject commit 7ade8dc4b84142abd3e6d1fb8a0f4111b0bbd571 diff --git a/src/tools/cargo b/src/tools/cargo index 75d5d8cffe346..63d0fe43449ad 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 75d5d8cffe3464631f82dcd3c470b78dc1dda8bb +Subproject commit 63d0fe43449adcb316d34d98a982b597faca4178 diff --git a/src/tools/miri b/src/tools/miri index 2065b52dfef3c..47acece7aa25d 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 2065b52dfef3cd5a5216e65c21a056a69574bddc +Subproject commit 47acece7aa25d7b5edfae0bfd4b94e6e55a7b4b0 diff --git a/src/tools/rls b/src/tools/rls index 2cf84baa5e3c5..dab1468d6aeed 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 2cf84baa5e3c55ac02f42919e67440acb5417125 +Subproject commit dab1468d6aeed0e49f7d0569c1d2128b5a7751e0 diff --git a/src/tools/rustfmt b/src/tools/rustfmt index acd94866fd0ff..580d826e9b0f4 160000 --- a/src/tools/rustfmt +++ b/src/tools/rustfmt @@ -1 +1 @@ -Subproject commit acd94866fd0ff5eacb7e184ae21c19e5440fc5fb +Subproject commit 580d826e9b0f407a2d4b36696cda2f0fa8d7ddaa From 5941ed2584588058b0c760c82297486a8cf2b238 Mon Sep 17 00:00:00 2001 From: Ethan Brierley Date: Fri, 4 Dec 2020 22:45:57 +0000 Subject: [PATCH 2/4] Break doc comment onto two lines Co-authored-by: lcnr --- library/core/src/array/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index b8532033f9719..656f88d6665eb 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -463,7 +463,8 @@ impl [T; N] { unsafe { crate::mem::transmute_copy::<_, [U; N]>(&dst) } } - /// A fallible function `f` applied to each element on array `self` in order to return an array the same size as `self` or the first error encountered. + /// A fallible function `f` applied to each element on array `self` in order to + /// return an array the same size as `self` or the first error encountered. /// /// # Examples /// From 0ff2022476b25afdb5038e5750b5f64ced5cfd5e Mon Sep 17 00:00:00 2001 From: Ethan Brierley Date: Fri, 4 Dec 2020 22:55:53 +0000 Subject: [PATCH 3/4] Use correct link to issue --- library/core/src/array/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 656f88d6665eb..7ce77dc5c5827 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -479,7 +479,7 @@ impl [T; N] { /// let b = a.try_map(|v| v.parse::()); /// assert!(b.is_err()); /// ``` - #[unstable(feature = "array_try_map", issue = "75243")] + #[unstable(feature = "array_try_map", issue = "79711")] pub fn try_map(self, mut f: F) -> Result<[U; N], E> where F: FnMut(T) -> R, From 892963e3bb5dd6fd8fc302c4c767e0e9d519700a Mon Sep 17 00:00:00 2001 From: Ethan Brierley Date: Fri, 18 Dec 2020 16:59:21 +0000 Subject: [PATCH 4/4] Swap out `Try` for `Result` --- library/core/src/array/mod.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 7ce77dc5c5827..a6b0e3280b1d4 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -12,7 +12,7 @@ use crate::convert::{Infallible, TryFrom}; use crate::fmt; use crate::hash::{self, Hash}; use crate::marker::Unsize; -use crate::ops::{Index, IndexMut, Try}; +use crate::ops::{Index, IndexMut}; use crate::slice::{Iter, IterMut}; mod iter; @@ -480,10 +480,9 @@ impl [T; N] { /// assert!(b.is_err()); /// ``` #[unstable(feature = "array_try_map", issue = "79711")] - pub fn try_map(self, mut f: F) -> Result<[U; N], E> + pub fn try_map(self, mut f: F) -> Result<[U; N], E> where - F: FnMut(T) -> R, - R: Try, + F: FnMut(T) -> Result, { use crate::mem::MaybeUninit; struct Guard {