Skip to content

Commit 3c63072

Browse files
authored
Rollup merge of #116399 - WaffleLapkin:erase_small_things, r=cjgillot
Small changes w/ `query::Erase<_>` r? `@cjgillot` cc `@Zoxc`
2 parents b724d9c + eca9a15 commit 3c63072

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

compiler/rustc_middle/src/query/erase.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use crate::mir;
22
use crate::query::CyclePlaceholder;
33
use crate::traits;
44
use crate::ty::{self, Ty};
5-
use std::mem::{size_of, transmute_copy, MaybeUninit};
5+
use std::intrinsics::transmute_unchecked;
6+
use std::mem::{size_of, MaybeUninit};
67

78
#[derive(Copy, Clone)]
89
pub struct Erased<T: Copy> {
@@ -29,31 +30,40 @@ pub fn erase<T: EraseType>(src: T) -> Erase<T> {
2930
};
3031

3132
Erased::<<T as EraseType>::Result> {
33+
// `transmute_unchecked` is needed here because it does not have `transmute`'s size check
34+
// (and thus allows to transmute between `T` and `MaybeUninit<T::Result>`) (we do the size
35+
// check ourselves in the `const` block above).
36+
//
37+
// `transmute_copy` is also commonly used for this (and it would work here since
38+
// `EraseType: Copy`), but `transmute_unchecked` better explains the intent.
39+
//
3240
// SAFETY: It is safe to transmute to MaybeUninit for types with the same sizes.
33-
data: unsafe { transmute_copy(&src) },
41+
data: unsafe { transmute_unchecked::<T, MaybeUninit<T::Result>>(src) },
3442
}
3543
}
3644

3745
/// Restores an erased value.
3846
#[inline(always)]
3947
pub fn restore<T: EraseType>(value: Erase<T>) -> T {
4048
let value: Erased<<T as EraseType>::Result> = value;
49+
// See comment in `erase` for why we use `transmute_unchecked`.
50+
//
4151
// SAFETY: Due to the use of impl Trait in `Erase` the only way to safely create an instance
4252
// of `Erase` is to call `erase`, so we know that `value.data` is a valid instance of `T` of
4353
// the right size.
44-
unsafe { transmute_copy(&value.data) }
54+
unsafe { transmute_unchecked::<MaybeUninit<T::Result>, T>(value.data) }
4555
}
4656

4757
impl<T> EraseType for &'_ T {
48-
type Result = [u8; size_of::<*const ()>()];
58+
type Result = [u8; size_of::<&'static ()>()];
4959
}
5060

5161
impl<T> EraseType for &'_ [T] {
52-
type Result = [u8; size_of::<*const [()]>()];
62+
type Result = [u8; size_of::<&'static [()]>()];
5363
}
5464

5565
impl<T> EraseType for &'_ ty::List<T> {
56-
type Result = [u8; size_of::<*const ()>()];
66+
type Result = [u8; size_of::<&'static ty::List<()>>()];
5767
}
5868

5969
impl<I: rustc_index::Idx, T> EraseType for &'_ rustc_index::IndexSlice<I, T> {

0 commit comments

Comments
 (0)