diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-11-08 00:47:51 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-08 00:47:51 +0100 |
| commit | 3c6307240cc1c41ec18ac3b5f86add84aa286f77 (patch) | |
| tree | 97d38fc4be748ce09b9e00a8de16c9c77f46c705 /compiler/rustc_middle/src/query | |
| parent | b724d9c90ef0ba055ca06b3ce3531c11d94a24bb (diff) | |
| parent | eca9a1533f4bf2848a34723410d9ae2f1e76975d (diff) | |
| download | rust-3c6307240cc1c41ec18ac3b5f86add84aa286f77.tar.gz rust-3c6307240cc1c41ec18ac3b5f86add84aa286f77.zip | |
Rollup merge of #116399 - WaffleLapkin:erase_small_things, r=cjgillot
Small changes w/ `query::Erase<_>` r? `@cjgillot` cc `@Zoxc`
Diffstat (limited to 'compiler/rustc_middle/src/query')
| -rw-r--r-- | compiler/rustc_middle/src/query/erase.rs | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index e20e9d9312c..cdde6a596a8 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -2,7 +2,8 @@ use crate::mir; use crate::query::CyclePlaceholder; use crate::traits; use crate::ty::{self, Ty}; -use std::mem::{size_of, transmute_copy, MaybeUninit}; +use std::intrinsics::transmute_unchecked; +use std::mem::{size_of, MaybeUninit}; #[derive(Copy, Clone)] pub struct Erased<T: Copy> { @@ -29,8 +30,15 @@ pub fn erase<T: EraseType>(src: T) -> Erase<T> { }; Erased::<<T as EraseType>::Result> { + // `transmute_unchecked` is needed here because it does not have `transmute`'s size check + // (and thus allows to transmute between `T` and `MaybeUninit<T::Result>`) (we do the size + // check ourselves in the `const` block above). + // + // `transmute_copy` is also commonly used for this (and it would work here since + // `EraseType: Copy`), but `transmute_unchecked` better explains the intent. + // // SAFETY: It is safe to transmute to MaybeUninit for types with the same sizes. - data: unsafe { transmute_copy(&src) }, + data: unsafe { transmute_unchecked::<T, MaybeUninit<T::Result>>(src) }, } } @@ -38,22 +46,24 @@ pub fn erase<T: EraseType>(src: T) -> Erase<T> { #[inline(always)] pub fn restore<T: EraseType>(value: Erase<T>) -> T { let value: Erased<<T as EraseType>::Result> = value; + // See comment in `erase` for why we use `transmute_unchecked`. + // // SAFETY: Due to the use of impl Trait in `Erase` the only way to safely create an instance // of `Erase` is to call `erase`, so we know that `value.data` is a valid instance of `T` of // the right size. - unsafe { transmute_copy(&value.data) } + unsafe { transmute_unchecked::<MaybeUninit<T::Result>, T>(value.data) } } impl<T> EraseType for &'_ T { - type Result = [u8; size_of::<*const ()>()]; + type Result = [u8; size_of::<&'static ()>()]; } impl<T> EraseType for &'_ [T] { - type Result = [u8; size_of::<*const [()]>()]; + type Result = [u8; size_of::<&'static [()]>()]; } impl<T> EraseType for &'_ ty::List<T> { - type Result = [u8; size_of::<*const ()>()]; + type Result = [u8; size_of::<&'static ty::List<()>>()]; } impl<I: rustc_index::Idx, T> EraseType for &'_ rustc_index::IndexSlice<I, T> { |
