summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/query/erase.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/query/erase.rs')
-rw-r--r--compiler/rustc_middle/src/query/erase.rs26
1 files changed, 18 insertions, 8 deletions
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index 8ba3764bc..cdde6a596 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> {
@@ -210,7 +220,7 @@ trivial! {
Option<rustc_attr::Stability>,
Option<rustc_data_structures::svh::Svh>,
Option<rustc_hir::def::DefKind>,
- Option<rustc_hir::GeneratorKind>,
+ Option<rustc_hir::CoroutineKind>,
Option<rustc_hir::HirId>,
Option<rustc_middle::middle::stability::DeprecationEntry>,
Option<rustc_middle::ty::Destructor>,
@@ -239,7 +249,7 @@ trivial! {
rustc_hir::def::DefKind,
rustc_hir::Defaultness,
rustc_hir::definitions::DefKey,
- rustc_hir::GeneratorKind,
+ rustc_hir::CoroutineKind,
rustc_hir::HirId,
rustc_hir::IsAsync,
rustc_hir::ItemLocalId,