@@ -3406,6 +3406,28 @@ impl<T> [T] {
34063406 /// This method has no purpose when either input element `T` or output element `U` are
34073407 /// zero-sized and will return the original slice without splitting anything.
34083408 ///
3409+ /// The reason this operation is slightly vague on its guarantees is because:
3410+ ///
3411+ /// * It's for SIMD, specifically [`slice::as_simd`]
3412+ /// * It wants code that uses SIMD operations to work in a `const fn`
3413+ ///
3414+ /// In particular, this operation is intended for breaking up a loop into its component
3415+ /// unaligned and aligned parts, so that the aligned parts can be processed using SIMD.
3416+ /// For that kind of pattern it's always ok to "fail" to align the slice, because the
3417+ /// unaligned path can always handle all the data.
3418+ ///
3419+ /// Lots of really basic operations want to use SIMD under the hood, so it would be very
3420+ /// frustrating if using this pattern made it impossible for an operation to work in
3421+ /// const contexts. Unfortunately, observing any properties of a pointer's address
3422+ /// is a very dangerous and problematic operation in const contexts, because it's a huge
3423+ /// reproducibility issue (which has actual soundness implications with compilation units).
3424+ ///
3425+ /// Thankfully, because the precise SIMD pattern we're interested in *already* has a fallback
3426+ /// mode where the alignment completely fails, the compiler can just make this operation always
3427+ /// fail to align the slice when doing const evaluation, and then everything is
3428+ /// always deterministic and reproducible (and the const evaluator is an interpreter anyway,
3429+ /// so you weren't actually going to get amazing SIMD speedups).
3430+ ///
34093431 /// # Safety
34103432 ///
34113433 /// This method is essentially a `transmute` with respect to the elements in the returned
@@ -3467,6 +3489,28 @@ impl<T> [T] {
34673489 /// This method has no purpose when either input element `T` or output element `U` are
34683490 /// zero-sized and will return the original slice without splitting anything.
34693491 ///
3492+ /// The reason this operation is slightly vague on its guarantees is because:
3493+ ///
3494+ /// * It's for SIMD, specifically [`slice::as_simd_mut`]
3495+ /// * It wants code that uses SIMD operations to work in a `const fn`
3496+ ///
3497+ /// In particular, this operation is intended for breaking up a loop into its component
3498+ /// unaligned and aligned parts, so that the aligned parts can be processed using SIMD.
3499+ /// For that kind of pattern it's always ok to "fail" to align the slice, because the
3500+ /// unaligned path can always handle all the data.
3501+ ///
3502+ /// Lots of really basic operations want to use SIMD under the hood, so it would be very
3503+ /// frustrating if using this pattern made it impossible for an operation to work in
3504+ /// const contexts. Unfortunately, observing any properties of a pointer's address
3505+ /// is a very dangerous and problematic operation in const contexts, because it's a huge
3506+ /// reproducibility issue (which has actual soundness implications with compilation units).
3507+ ///
3508+ /// Thankfully, because the precise SIMD pattern we're interested in *already* has a fallback
3509+ /// mode where the alignment completely fails, the compiler can just make this operation always
3510+ /// fail to align the slice when doing const evaluation, and then everything is
3511+ /// always deterministic and reproducible (and the const evaluator is an interpreter anyway,
3512+ /// so you weren't actually going to get amazing SIMD speedups).
3513+ ///
34703514 /// # Safety
34713515 ///
34723516 /// This method is essentially a `transmute` with respect to the elements in the returned
0 commit comments