diff options
| author | bors <bors@rust-lang.org> | 2021-12-15 09:31:59 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-12-15 09:31:59 +0000 |
| commit | 3ee016ae4d4c6ee4a34faa2eb7fdae2ffa7c9b46 (patch) | |
| tree | feda053596eb3645cbba8cb313676bdcd7024fee /library | |
| parent | df89fd2063aaa060c72c81254db0b930ff379e9a (diff) | |
| parent | 6c6cfa87c08a7bfb6b27bb01b9337aa3178716a5 (diff) | |
Auto merge of #91959 - matthiaskrgr:rollup-rhajuvw, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #90521 (Stabilize `destructuring_assignment`) - #91479 (Add `[T]::as_simd(_mut)`) - #91584 (Improve code for rustdoc-gui tester) - #91886 (core: minor `Option` doc correction) - #91888 (Handle unordered const/ty generics for object lifetime defaults) - #91905 (Fix source code page sidebar on mobile) - #91906 (Removed `in_band_lifetimes` from `library\proc_macro`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'library')
| -rw-r--r-- | library/alloc/src/lib.rs | 2 | ||||
| -rw-r--r-- | library/core/src/option.rs | 4 | ||||
| -rw-r--r-- | library/core/src/slice/mod.rs | 119 | ||||
| -rw-r--r-- | library/proc_macro/src/bridge/client.rs | 4 | ||||
| -rw-r--r-- | library/proc_macro/src/bridge/mod.rs | 8 | ||||
| -rw-r--r-- | library/proc_macro/src/bridge/rpc.rs | 8 | ||||
| -rw-r--r-- | library/proc_macro/src/lib.rs | 1 |
7 files changed, 132 insertions, 14 deletions
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index e8a932835f6..600862c4224 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -136,7 +136,7 @@ #![feature(cfg_target_has_atomic)] #![feature(const_fn_trait_bound)] #![feature(const_trait_impl)] -#![feature(destructuring_assignment)] +#![cfg_attr(bootstrap, feature(destructuring_assignment))] #![feature(dropck_eyepatch)] #![feature(exclusive_range_pattern)] #![feature(fundamental)] diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 381e2d6eed3..015366ed490 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -512,11 +512,11 @@ use crate::{ #[rustc_diagnostic_item = "Option"] #[stable(feature = "rust1", since = "1.0.0")] pub enum Option<T> { - /// No value + /// No value. #[lang = "None"] #[stable(feature = "rust1", since = "1.0.0")] None, - /// Some value `T` + /// Some value of type `T`. #[lang = "Some"] #[stable(feature = "rust1", since = "1.0.0")] Some(#[stable(feature = "rust1", since = "1.0.0")] T), diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 7d5d70f1720..49dce89a494 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -16,6 +16,8 @@ use crate::option::Option::{None, Some}; use crate::ptr; use crate::result::Result; use crate::result::Result::{Err, Ok}; +#[cfg(not(miri))] // Miri does not support all SIMD intrinsics +use crate::simd::{self, Simd}; use crate::slice; #[unstable( @@ -3512,6 +3514,123 @@ impl<T> [T] { } } + /// Split a slice into a prefix, a middle of aligned SIMD types, and a suffix. + /// + /// This is a safe wrapper around [`slice::align_to`], so has the same weak + /// postconditions as that method. You're only assured that + /// `self.len() == prefix.len() + middle.len() * LANES + suffix.len()`. + /// + /// Notably, all of the following are possible: + /// - `prefix.len() >= LANES`. + /// - `middle.is_empty()` despite `self.len() >= 3 * LANES`. + /// - `suffix.len() >= LANES`. + /// + /// That said, this is a safe method, so if you're only writing safe code, + /// then this can at most cause incorrect logic, not unsoundness. + /// + /// # Panics + /// + /// This will panic if the size of the SIMD type is different from + /// `LANES` times that of the scalar. + /// + /// At the time of writing, the trait restrictions on `Simd<T, LANES>` keeps + /// that from ever happening, as only power-of-two numbers of lanes are + /// supported. It's possible that, in the future, those restrictions might + /// be lifted in a way that would make it possible to see panics from this + /// method for something like `LANES == 3`. + /// + /// # Examples + /// + /// ``` + /// #![feature(portable_simd)] + /// + /// let short = &[1, 2, 3]; + /// let (prefix, middle, suffix) = short.as_simd::<4>(); + /// assert_eq!(middle, []); // Not enough elements for anything in the middle + /// + /// // They might be split in any possible way between prefix and suffix + /// let it = prefix.iter().chain(suffix).copied(); + /// assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]); + /// + /// fn basic_simd_sum(x: &[f32]) -> f32 { + /// use std::ops::Add; + /// use std::simd::f32x4; + /// let (prefix, middle, suffix) = x.as_simd(); + /// let sums = f32x4::from_array([ + /// prefix.iter().copied().sum(), + /// 0.0, + /// 0.0, + /// suffix.iter().copied().sum(), + /// ]); + /// let sums = middle.iter().copied().fold(sums, f32x4::add); + /// sums.horizontal_sum() + /// } + /// + /// let numbers: Vec<f32> = (1..101).map(|x| x as _).collect(); + /// assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0); + /// ``` + #[unstable(feature = "portable_simd", issue = "86656")] + #[cfg(not(miri))] // Miri does not support all SIMD intrinsics + pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T]) + where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: simd::SimdElement, + simd::LaneCount<LANES>: simd::SupportedLaneCount, + { + // These are expected to always match, as vector types are laid out like + // arrays per <https://llvm.org/docs/LangRef.html#vector-type>, but we + // might as well double-check since it'll optimize away anyhow. + assert_eq!(mem::size_of::<Simd<T, LANES>>(), mem::size_of::<[T; LANES]>()); + + // SAFETY: The simd types have the same layout as arrays, just with + // potentially-higher alignment, so the de-facto transmutes are sound. + unsafe { self.align_to() } + } + + /// Split a slice into a prefix, a middle of aligned SIMD types, and a suffix. + /// + /// This is a safe wrapper around [`slice::align_to_mut`], so has the same weak + /// postconditions as that method. You're only assured that + /// `self.len() == prefix.len() + middle.len() * LANES + suffix.len()`. + /// + /// Notably, all of the following are possible: + /// - `prefix.len() >= LANES`. + /// - `middle.is_empty()` despite `self.len() >= 3 * LANES`. + /// - `suffix.len() >= LANES`. + /// + /// That said, this is a safe method, so if you're only writing safe code, + /// then this can at most cause incorrect logic, not unsoundness. + /// + /// This is the mutable version of [`slice::as_simd`]; see that for examples. + /// + /// # Panics + /// + /// This will panic if the size of the SIMD type is different from + /// `LANES` times that of the scalar. + /// + /// At the time of writing, the trait restrictions on `Simd<T, LANES>` keeps + /// that from ever happening, as only power-of-two numbers of lanes are + /// supported. It's possible that, in the future, those restrictions might + /// be lifted in a way that would make it possible to see panics from this + /// method for something like `LANES == 3`. + #[unstable(feature = "portable_simd", issue = "86656")] + #[cfg(not(miri))] // Miri does not support all SIMD intrinsics + pub fn as_simd_mut<const LANES: usize>(&mut self) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T]) + where + Simd<T, LANES>: AsMut<[T; LANES]>, + T: simd::SimdElement, + simd::LaneCount<LANES>: simd::SupportedLaneCount, + { + // These are expected to always match, as vector types are laid out like + // arrays per <https://llvm.org/docs/LangRef.html#vector-type>, but we + // might as well double-check since it'll optimize away anyhow. + assert_eq!(mem::size_of::<Simd<T, LANES>>(), mem::size_of::<[T; LANES]>()); + + // SAFETY: The simd types have the same layout as arrays, just with + // potentially-higher alignment, so the de-facto transmutes are sound. + unsafe { self.align_to_mut() } + } + /// Checks if the elements of this slice are sorted. /// /// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index 8ae7b6de1a6..83a2ac6f0d4 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -78,7 +78,7 @@ macro_rules! define_handles { } } - impl<S: server::Types> Decode<'_, 's, HandleStore<server::MarkedTypes<S>>> + impl<'s, S: server::Types> Decode<'_, 's, HandleStore<server::MarkedTypes<S>>> for &'s Marked<S::$oty, $oty> { fn decode(r: &mut Reader<'_>, s: &'s HandleStore<server::MarkedTypes<S>>) -> Self { @@ -92,7 +92,7 @@ macro_rules! define_handles { } } - impl<S: server::Types> DecodeMut<'_, 's, HandleStore<server::MarkedTypes<S>>> + impl<'s, S: server::Types> DecodeMut<'_, 's, HandleStore<server::MarkedTypes<S>>> for &'s mut Marked<S::$oty, $oty> { fn decode( diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 2df287f7d93..fbeb585095b 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -295,13 +295,13 @@ impl<T, M> Unmark for Marked<T, M> { self.value } } -impl<T, M> Unmark for &'a Marked<T, M> { +impl<'a, T, M> Unmark for &'a Marked<T, M> { type Unmarked = &'a T; fn unmark(self) -> Self::Unmarked { &self.value } } -impl<T, M> Unmark for &'a mut Marked<T, M> { +impl<'a, T, M> Unmark for &'a mut Marked<T, M> { type Unmarked = &'a mut T; fn unmark(self) -> Self::Unmarked { &mut self.value @@ -356,8 +356,8 @@ mark_noop! { (), bool, char, - &'a [u8], - &'a str, + &'_ [u8], + &'_ str, String, usize, Delimiter, diff --git a/library/proc_macro/src/bridge/rpc.rs b/library/proc_macro/src/bridge/rpc.rs index 42432563faf..d50564d01a5 100644 --- a/library/proc_macro/src/bridge/rpc.rs +++ b/library/proc_macro/src/bridge/rpc.rs @@ -79,7 +79,7 @@ macro_rules! rpc_encode_decode { } } - impl<S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S> + impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S> for $name $(<$($T),+>)? { fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { @@ -176,7 +176,7 @@ impl<S, A: Encode<S>, B: Encode<S>> Encode<S> for (A, B) { } } -impl<S, A: for<'s> DecodeMut<'a, 's, S>, B: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S> +impl<'a, S, A: for<'s> DecodeMut<'a, 's, S>, B: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S> for (A, B) { fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { @@ -213,7 +213,7 @@ impl<S> Encode<S> for &[u8] { } } -impl<S> DecodeMut<'a, '_, S> for &'a [u8] { +impl<'a, S> DecodeMut<'a, '_, S> for &'a [u8] { fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { let len = usize::decode(r, s); let xs = &r[..len]; @@ -228,7 +228,7 @@ impl<S> Encode<S> for &str { } } -impl<S> DecodeMut<'a, '_, S> for &'a str { +impl<'a, S> DecodeMut<'a, '_, S> for &'a str { fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { str::from_utf8(<&[u8]>::decode(r, s)).unwrap() } diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index ef96d72a38b..69af598f91e 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -25,7 +25,6 @@ #![feature(allow_internal_unstable)] #![feature(decl_macro)] #![feature(extern_types)] -#![feature(in_band_lifetimes)] #![feature(negative_impls)] #![feature(auto_traits)] #![feature(restricted_std)] |
