@@ -3406,6 +3406,28 @@ impl<T> [T] {
3406
3406
/// This method has no purpose when either input element `T` or output element `U` are
3407
3407
/// zero-sized and will return the original slice without splitting anything.
3408
3408
///
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
+ ///
3409
3431
/// # Safety
3410
3432
///
3411
3433
/// This method is essentially a `transmute` with respect to the elements in the returned
@@ -3467,6 +3489,28 @@ impl<T> [T] {
3467
3489
/// This method has no purpose when either input element `T` or output element `U` are
3468
3490
/// zero-sized and will return the original slice without splitting anything.
3469
3491
///
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
+ ///
3470
3514
/// # Safety
3471
3515
///
3472
3516
/// This method is essentially a `transmute` with respect to the elements in the returned
0 commit comments