diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 71548bec7aaee..a6b0e3280b1d4 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -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 = "79711")] + pub fn try_map(self, mut f: F) -> Result<[U; N], E> + where + F: FnMut(T) -> Result, + { + 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