Add intrinsics::transmute_unchecked

This takes a whole 3 lines in `compiler/` since it lowers to `CastKind::Transmute` in MIR *exactly* the same as the existing `intrinsics::transmute` does, it just doesn't have the fancy checking in `hir_typeck`.

Added to enable experimenting with the request in <https://github.com/rust-lang/rust/pull/106281#issuecomment-1496648190> and because the portable-simd folks might be interested for dependently-sized array-vector conversions.

It also simplifies a couple places in `core`.
This commit is contained in:
Scott McMurray
2023-04-22 17:14:19 -07:00
parent 4396ceca05
commit 1de2257c3f
7 changed files with 43 additions and 54 deletions

View File

@@ -3,8 +3,9 @@
use crate::num::NonZeroUsize;
use crate::{
fmt,
intrinsics::transmute_unchecked,
iter::{self, ExactSizeIterator, FusedIterator, TrustedLen},
mem::{self, MaybeUninit},
mem::MaybeUninit,
ops::{IndexRange, Range},
ptr,
};
@@ -63,18 +64,11 @@ impl<T, const N: usize> IntoIterator for [T; N] {
// an array of `T`.
//
// With that, this initialization satisfies the invariants.
// FIXME(LukasKalbertodt): actually use `mem::transmute` here, once it
// works with const generics:
// `mem::transmute::<[T; N], [MaybeUninit<T>; N]>(array)`
//
// Until then, we can use `mem::transmute_copy` to create a bitwise copy
// as a different type, then forget `array` so that it is not dropped.
unsafe {
let iter = IntoIter { data: mem::transmute_copy(&self), alive: IndexRange::zero_to(N) };
mem::forget(self);
iter
}
// FIXME: If normal `transmute` ever gets smart enough to allow this
// directly, use it instead of `transmute_unchecked`.
let data: [MaybeUninit<T>; N] = unsafe { transmute_unchecked(self) };
IntoIter { data, alive: IndexRange::zero_to(N) }
}
}