Rollup merge of #116399 - WaffleLapkin:erase_small_things, r=cjgillot
Small changes w/ `query::Erase<_>` r? `@cjgillot` cc `@Zoxc`
This commit is contained in:
commit
3c6307240c
1 changed files with 16 additions and 6 deletions
|
@ -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> {
|
||||
|
|
Loading…
Add table
Reference in a new issue