Skip to main content

rustc_middle/query/
erase.rs

1//! To improve compile times and code size for the compiler itself, query
2//! values are "erased" in some contexts (e.g. inside in-memory cache types),
3//! to reduce the number of generic instantiations created during codegen.
4//!
5//! See <https://github.com/rust-lang/rust/pull/151715> for some bootstrap-time
6//! and performance benchmarks.
7
8use std::ffi::OsStr;
9use std::intrinsics::transmute_unchecked;
10use std::marker::PhantomData;
11use std::mem::MaybeUninit;
12
13use rustc_ast::tokenstream::TokenStream;
14use rustc_data_structures::steal::Steal;
15use rustc_data_structures::sync::{DynSend, DynSync};
16use rustc_index::{Idx, IndexSlice};
17use rustc_span::def_id::ModId;
18use rustc_span::{ErrorGuaranteed, Spanned};
19
20use crate::mono::{MonoItem, NormalizationErrorInMono};
21use crate::ty::{self, Ty, TyCtxt};
22use crate::{mir, thir, traits};
23
24unsafe extern "C" {
25    type NoAutoTraits;
26}
27
28/// Internal implementation detail of [`Erased`].
29#[derive(#[automatically_derived]
impl<Storage: ::core::marker::Copy + Copy> ::core::marker::Copy for
    ErasedData<Storage> {
}Copy, #[automatically_derived]
impl<Storage: ::core::clone::Clone + Copy> ::core::clone::Clone for
    ErasedData<Storage> {
    #[inline]
    fn clone(&self) -> ErasedData<Storage> {
        ErasedData {
            data: ::core::clone::Clone::clone(&self.data),
            no_auto_traits: ::core::clone::Clone::clone(&self.no_auto_traits),
        }
    }
}Clone)]
30pub struct ErasedData<Storage: Copy> {
31    /// We use `MaybeUninit` here to make sure it's legal to store a transmuted
32    /// value that isn't actually of type `Storage`.
33    data: MaybeUninit<Storage>,
34    /// `Storage` is an erased type, so we use an external type here to opt-out of auto traits
35    /// as those would be incorrect.
36    no_auto_traits: PhantomData<NoAutoTraits>,
37}
38
39// SAFETY: The bounds on `erase_val` ensure the types we erase are `DynSync` and `DynSend`
40unsafe impl<Storage: Copy> DynSync for ErasedData<Storage> {}
41unsafe impl<Storage: Copy> DynSend for ErasedData<Storage> {}
42
43/// Trait for types that can be erased into [`Erased<Self>`].
44///
45/// Erasing and unerasing values is performed by [`erase_val`] and [`restore_val`].
46///
47/// FIXME: This whole trait could potentially be replaced by `T: Copy` and the
48/// storage type `[u8; size_of::<T>()]` when support for that is more mature.
49pub trait Erasable: Copy {
50    /// Storage type to used for erased values of this type.
51    /// Should be `[u8; N]`, where N is equal to `size_of::<Self>`.
52    ///
53    /// [`ErasedData`] wraps this storage type in `MaybeUninit` to ensure that
54    /// transmutes to/from erased storage are well-defined.
55    type Storage: Copy;
56}
57
58/// A value of `T` that has been "erased" into some opaque storage type.
59///
60/// This is helpful for reducing the number of concrete instantiations needed
61/// during codegen when building the compiler.
62///
63/// Using an opaque type alias allows the type checker to enforce that
64/// `Erased<T>` and `Erased<U>` are still distinct types, while allowing
65/// monomorphization to see that they might actually use the same storage type.
66pub type Erased<T: Erasable> = ErasedData<impl Copy>;
67
68/// Erases a value of type `T` into `Erased<T>`.
69///
70/// `Erased<T>` and `Erased<U>` are type-checked as distinct types, but codegen
71/// can see whether they actually have the same storage type.
72#[inline(always)]
73#[define_opaque(Erased)]
74// The `DynSend` and `DynSync` bounds on `T` are used to
75// justify the safety of the implementations of these traits for `ErasedData`.
76pub fn erase_val<T: Erasable + DynSend + DynSync>(value: T) -> Erased<T> {
77    // Ensure the sizes match
78    const {
79        if size_of::<T>() != size_of::<T::Storage>() {
80            {
    ::core::panicking::panic_fmt(format_args!("size of T must match erased type <T as Erasable>::Storage"));
}panic!("size of T must match erased type <T as Erasable>::Storage")
81        }
82    };
83
84    ErasedData::<<T as Erasable>::Storage> {
85        // `transmute_unchecked` is needed here because it does not have `transmute`'s size check
86        // (and thus allows to transmute between `T` and `MaybeUninit<T::Storage>`) (we do the size
87        // check ourselves in the `const` block above).
88        //
89        // `transmute_copy` is also commonly used for this (and it would work here since
90        // `Erasable: Copy`), but `transmute_unchecked` better explains the intent.
91        //
92        // SAFETY: It is safe to transmute to MaybeUninit for types with the same sizes.
93        data: unsafe { transmute_unchecked::<T, MaybeUninit<T::Storage>>(value) },
94        no_auto_traits: PhantomData,
95    }
96}
97
98/// Restores an erased value to its real type.
99///
100/// This relies on the fact that `Erased<T>` and `Erased<U>` are type-checked
101/// as distinct types, even if they use the same storage type.
102#[inline(always)]
103#[define_opaque(Erased)]
104pub fn restore_val<T: Erasable>(erased_value: Erased<T>) -> T {
105    let ErasedData { data, .. }: ErasedData<<T as Erasable>::Storage> = erased_value;
106    // See comment in `erase_val` for why we use `transmute_unchecked`.
107    //
108    // SAFETY: Due to the use of impl Trait in `Erased` the only way to safely create an instance
109    // of `Erased` is to call `erase_val`, so we know that `erased_value.data` is a valid instance
110    // of `T` of the right size.
111    unsafe { transmute_unchecked::<MaybeUninit<T::Storage>, T>(data) }
112}
113
114impl<T> Erasable for &'_ T {
115    type Storage = [u8; size_of::<&'_ ()>()];
116}
117
118impl<T> Erasable for &'_ [T] {
119    type Storage = [u8; size_of::<&'_ [()]>()];
120}
121
122impl<I: Idx, T> Erasable for &'_ IndexSlice<I, T> {
123    type Storage = [u8; size_of::<&'_ [()]>()];
124}
125
126// Note: this impl does not overlap with the impl for `&'_ T` above because `RawList` is unsized
127// and does not satisfy the implicit `T: Sized` bound.
128//
129// Furthermore, even if that implicit bound was removed (by adding `T: ?Sized`) this impl still
130// wouldn't overlap because `?Sized` is equivalent to `MetaSized` and `RawList` does not satisfy
131// `MetaSized` because it contains an extern type.
132impl<H, T> Erasable for &'_ ty::RawList<H, T> {
133    type Storage = [u8; size_of::<&'_ ty::RawList<(), ()>>()];
134}
135
136impl<T> Erasable for Result<&'_ T, traits::query::NoSolution> {
137    type Storage = [u8; size_of::<Result<&'_ (), traits::query::NoSolution>>()];
138}
139
140impl<T> Erasable for Result<&'_ T, ErrorGuaranteed> {
141    type Storage = [u8; size_of::<Result<&'_ (), ErrorGuaranteed>>()];
142}
143
144impl<T> Erasable for Option<&'_ T> {
145    type Storage = [u8; size_of::<Option<&'_ ()>>()];
146}
147
148impl<T: Erasable> Erasable for ty::EarlyBinder<'_, T> {
149    type Storage = T::Storage;
150}
151
152impl<T0, T1> Erasable for (&'_ T0, &'_ T1) {
153    type Storage = [u8; size_of::<(&'_ (), &'_ ())>()];
154}
155
156impl<T0, T1, T2> Erasable for (&'_ T0, &'_ T1, &'_ T2) {
157    type Storage = [u8; size_of::<(&'_ (), &'_ (), &'_ ())>()];
158}
159
160impl<T0, T1> Erasable for (&'_ [T0], &'_ [T1]) {
161    type Storage = [u8; size_of::<(&'_ [()], &'_ [()])>()];
162}
163
164macro_rules! impl_erasable_for_types_with_no_type_params {
165    ($($ty:ty),+ $(,)?) => {
166        $(
167            impl Erasable for $ty {
168                type Storage = [u8; size_of::<$ty>()];
169            }
170        )*
171    }
172}
173
174// For types with no type parameters the erased storage for `Foo` is
175// `[u8; size_of::<Foo>()]`. ('_ lifetimes are allowed.)
176impl Erasable for &'_ str {
    type Storage = [u8; size_of::<&'_ str>()];
}
impl Erasable for (&'_ ty::CrateInherentImpls, Result<(), ErrorGuaranteed>) {
    type Storage =
        [u8; size_of::<(&'_ ty::CrateInherentImpls,
                Result<(), ErrorGuaranteed>)>()];
}
impl Erasable for () {
    type Storage = [u8; size_of::<()>()];
}
impl Erasable for
    (traits::solve::QueryResult<'_>,
    &'_ traits::solve::inspect::Probe<TyCtxt<'_>>, ty::RequiredDepth) {
    type Storage =
        [u8; size_of::<(traits::solve::QueryResult<'_>,
                &'_ traits::solve::inspect::Probe<TyCtxt<'_>>,
                ty::RequiredDepth)>()];
}
impl Erasable for Option<&'_ OsStr> {
    type Storage = [u8; size_of::<Option<&'_ OsStr>>()];
}
impl Erasable for
    Option<&'_ [rustc_hir::PreciseCapturingArgKind<rustc_span::Symbol,
    rustc_span::Symbol>]> {
    type Storage =
        [u8; size_of::<Option<&'_ [rustc_hir::PreciseCapturingArgKind<rustc_span::Symbol,
                rustc_span::Symbol>]>>()];
}
impl Erasable for Option<(mir::ConstValue, Ty<'_>)> {
    type Storage = [u8; size_of::<Option<(mir::ConstValue, Ty<'_>)>>()];
}
impl Erasable for
    Option<(rustc_span::def_id::DefId, rustc_session::config::EntryFnType)> {
    type Storage =
        [u8; size_of::<Option<(rustc_span::def_id::DefId,
                rustc_session::config::EntryFnType)>>()];
}
impl Erasable for Option<rustc_abi::Align> {
    type Storage = [u8; size_of::<Option<rustc_abi::Align>>()];
}
impl Erasable for Option<rustc_ast::expand::allocator::AllocatorKind> {
    type Storage =
        [u8; size_of::<Option<rustc_ast::expand::allocator::AllocatorKind>>()];
}
impl Erasable for Option<rustc_data_structures::svh::Svh> {
    type Storage = [u8; size_of::<Option<rustc_data_structures::svh::Svh>>()];
}
impl Erasable for Option<rustc_hir::ConstStability> {
    type Storage = [u8; size_of::<Option<rustc_hir::ConstStability>>()];
}
impl Erasable for Option<rustc_hir::CoroutineKind> {
    type Storage = [u8; size_of::<Option<rustc_hir::CoroutineKind>>()];
}
impl Erasable for Option<rustc_hir::DefaultBodyStability> {
    type Storage = [u8; size_of::<Option<rustc_hir::DefaultBodyStability>>()];
}
impl Erasable for Option<rustc_hir::Stability> {
    type Storage = [u8; size_of::<Option<rustc_hir::Stability>>()];
}
impl Erasable for Option<rustc_middle::middle::stability::DeprecationEntry> {
    type Storage =
        [u8; size_of::<Option<rustc_middle::middle::stability::DeprecationEntry>>()];
}
impl Erasable for Option<rustc_middle::ty::AsyncDestructor> {
    type Storage =
        [u8; size_of::<Option<rustc_middle::ty::AsyncDestructor>>()];
}
impl Erasable for Option<rustc_middle::ty::Destructor> {
    type Storage = [u8; size_of::<Option<rustc_middle::ty::Destructor>>()];
}
impl Erasable for Option<rustc_middle::ty::IntrinsicDef> {
    type Storage = [u8; size_of::<Option<rustc_middle::ty::IntrinsicDef>>()];
}
impl Erasable for Option<rustc_middle::ty::ScalarInt> {
    type Storage = [u8; size_of::<Option<rustc_middle::ty::ScalarInt>>()];
}
impl Erasable for Option<rustc_span::Span> {
    type Storage = [u8; size_of::<Option<rustc_span::Span>>()];
}
impl Erasable for Option<rustc_span::def_id::CrateNum> {
    type Storage = [u8; size_of::<Option<rustc_span::def_id::CrateNum>>()];
}
impl Erasable for Option<rustc_span::def_id::DefId> {
    type Storage = [u8; size_of::<Option<rustc_span::def_id::DefId>>()];
}
impl Erasable for Option<rustc_span::def_id::LocalDefId> {
    type Storage = [u8; size_of::<Option<rustc_span::def_id::LocalDefId>>()];
}
impl Erasable for Option<rustc_target::spec::PanicStrategy> {
    type Storage =
        [u8; size_of::<Option<rustc_target::spec::PanicStrategy>>()];
}
impl Erasable for Option<ty::EarlyBinder<'_, Ty<'_>>> {
    type Storage = [u8; size_of::<Option<ty::EarlyBinder<'_, Ty<'_>>>>()];
}
impl Erasable for Option<ty::EarlyBinder<'_, ty::Const<'_>>> {
    type Storage =
        [u8; size_of::<Option<ty::EarlyBinder<'_, ty::Const<'_>>>>()];
}
impl Erasable for Option<ty::Value<'_>> {
    type Storage = [u8; size_of::<Option<ty::Value<'_>>>()];
}
impl Erasable for Option<usize> {
    type Storage = [u8; size_of::<Option<usize>>()];
}
impl Erasable for Result<&'_ TokenStream, ()> {
    type Storage = [u8; size_of::<Result<&'_ TokenStream, ()>>()];
}
impl Erasable for
    Result<&'_ rustc_target::callconv::FnAbi<'_, Ty<'_>>,
    &'_ ty::layout::FnAbiError<'_>> {
    type Storage =
        [u8; size_of::<Result<&'_ rustc_target::callconv::FnAbi<'_, Ty<'_>>,
                &'_ ty::layout::FnAbiError<'_>>>()];
}
impl Erasable for
    Result<&'_ traits::ImplSource<'_, ()>, traits::CodegenObligationError> {
    type Storage =
        [u8; size_of::<Result<&'_ traits::ImplSource<'_, ()>,
                traits::CodegenObligationError>>()];
}
impl Erasable for Result<&'_ ty::List<Ty<'_>>, ty::util::AlwaysRequiresDrop> {
    type Storage =
        [u8; size_of::<Result<&'_ ty::List<Ty<'_>>,
                ty::util::AlwaysRequiresDrop>>()];
}
impl Erasable for
    Result<(&'_ Steal<thir::Thir<'_>>, thir::ExprId), ErrorGuaranteed> {
    type Storage =
        [u8; size_of::<Result<(&'_ Steal<thir::Thir<'_>>, thir::ExprId),
                ErrorGuaranteed>>()];
}
impl Erasable for
    Result<(&'_ [Spanned<MonoItem<'_>>], &'_ [Spanned<MonoItem<'_>>]),
    NormalizationErrorInMono> {
    type Storage =
        [u8; size_of::<Result<(&'_ [Spanned<MonoItem<'_>>],
                &'_ [Spanned<MonoItem<'_>>]), NormalizationErrorInMono>>()];
}
impl Erasable for Result<(), ErrorGuaranteed> {
    type Storage = [u8; size_of::<Result<(), ErrorGuaranteed>>()];
}
impl Erasable for
    Result<Option<ty::EarlyBinder<'_, ty::Const<'_>>>, ErrorGuaranteed> {
    type Storage =
        [u8; size_of::<Result<Option<ty::EarlyBinder<'_, ty::Const<'_>>>,
                ErrorGuaranteed>>()];
}
impl Erasable for Result<Option<ty::Instance<'_>>, ErrorGuaranteed> {
    type Storage =
        [u8; size_of::<Result<Option<ty::Instance<'_>>, ErrorGuaranteed>>()];
}
impl Erasable for Result<bool, &ty::layout::LayoutError<'_>> {
    type Storage =
        [u8; size_of::<Result<bool, &ty::layout::LayoutError<'_>>>()];
}
impl Erasable for Result<mir::ConstAlloc<'_>, mir::interpret::ErrorHandled> {
    type Storage =
        [u8; size_of::<Result<mir::ConstAlloc<'_>,
                mir::interpret::ErrorHandled>>()];
}
impl Erasable for Result<mir::ConstValue, mir::interpret::ErrorHandled> {
    type Storage =
        [u8; size_of::<Result<mir::ConstValue,
                mir::interpret::ErrorHandled>>()];
}
impl Erasable for
    Result<rustc_abi::TyAndLayout<'_, Ty<'_>>, &ty::layout::LayoutError<'_>> {
    type Storage =
        [u8; size_of::<Result<rustc_abi::TyAndLayout<'_, Ty<'_>>,
                &ty::layout::LayoutError<'_>>>()];
}
impl Erasable for
    Result<rustc_middle::traits::EvaluationResult,
    rustc_middle::traits::OverflowError> {
    type Storage =
        [u8; size_of::<Result<rustc_middle::traits::EvaluationResult,
                rustc_middle::traits::OverflowError>>()];
}
impl Erasable for
    Result<rustc_middle::ty::adjustment::CoerceUnsizedInfo, ErrorGuaranteed> {
    type Storage =
        [u8; size_of::<Result<rustc_middle::ty::adjustment::CoerceUnsizedInfo,
                ErrorGuaranteed>>()];
}
impl Erasable for Result<ty::GenericArg<'_>, traits::query::NoSolution> {
    type Storage =
        [u8; size_of::<Result<ty::GenericArg<'_>,
                traits::query::NoSolution>>()];
}
impl Erasable for Ty<'_> {
    type Storage = [u8; size_of::<Ty<'_>>()];
}
impl Erasable for bool {
    type Storage = [u8; size_of::<bool>()];
}
impl Erasable for rustc_crate_store::CrateDepKind {
    type Storage = [u8; size_of::<rustc_crate_store::CrateDepKind>()];
}
impl Erasable for rustc_data_structures::svh::Svh {
    type Storage = [u8; size_of::<rustc_data_structures::svh::Svh>()];
}
impl Erasable for rustc_hir::Constness {
    type Storage = [u8; size_of::<rustc_hir::Constness>()];
}
impl Erasable for rustc_hir::Defaultness {
    type Storage = [u8; size_of::<rustc_hir::Defaultness>()];
}
impl Erasable for rustc_hir::HirId {
    type Storage = [u8; size_of::<rustc_hir::HirId>()];
}
impl Erasable for rustc_hir::MaybeOwner<'_> {
    type Storage = [u8; size_of::<rustc_hir::MaybeOwner<'_>>()];
}
impl Erasable for rustc_hir::OpaqueTyOrigin<rustc_hir::def_id::DefId> {
    type Storage =
        [u8; size_of::<rustc_hir::OpaqueTyOrigin<rustc_hir::def_id::DefId>>()];
}
impl Erasable for rustc_hir::def::DefKind {
    type Storage = [u8; size_of::<rustc_hir::def::DefKind>()];
}
impl Erasable for rustc_hir::def_id::DefId {
    type Storage = [u8; size_of::<rustc_hir::def_id::DefId>()];
}
impl Erasable for rustc_middle::hir::ProjectedMaybeOwner<'_> {
    type Storage =
        [u8; size_of::<rustc_middle::hir::ProjectedMaybeOwner<'_>>()];
}
impl Erasable for rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs {
    type Storage =
        [u8; size_of::<rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs>()];
}
impl Erasable for
    rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault {
    type Storage =
        [u8; size_of::<rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault>()];
}
impl Erasable for rustc_middle::mir::ConstQualifs {
    type Storage = [u8; size_of::<rustc_middle::mir::ConstQualifs>()];
}
impl Erasable for rustc_middle::mir::ConstValue {
    type Storage = [u8; size_of::<rustc_middle::mir::ConstValue>()];
}
impl Erasable for rustc_middle::mir::interpret::AllocId {
    type Storage = [u8; size_of::<rustc_middle::mir::interpret::AllocId>()];
}
impl Erasable for
    rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'_> {
    type Storage =
        [u8; size_of::<rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'_>>()];
}
impl Erasable for rustc_middle::mir::interpret::EvalToValTreeResult<'_> {
    type Storage =
        [u8; size_of::<rustc_middle::mir::interpret::EvalToValTreeResult<'_>>()];
}
impl Erasable for rustc_middle::mono::MonoItemPartitions<'_> {
    type Storage =
        [u8; size_of::<rustc_middle::mono::MonoItemPartitions<'_>>()];
}
impl Erasable for rustc_middle::traits::query::MethodAutoderefStepsResult<'_>
    {
    type Storage =
        [u8; size_of::<rustc_middle::traits::query::MethodAutoderefStepsResult<'_>>()];
}
impl Erasable for rustc_middle::ty::AdtDef<'_> {
    type Storage = [u8; size_of::<rustc_middle::ty::AdtDef<'_>>()];
}
impl Erasable for rustc_middle::ty::AnonConstKind {
    type Storage = [u8; size_of::<rustc_middle::ty::AnonConstKind>()];
}
impl Erasable for rustc_middle::ty::AssocItem {
    type Storage = [u8; size_of::<rustc_middle::ty::AssocItem>()];
}
impl Erasable for rustc_middle::ty::Asyncness {
    type Storage = [u8; size_of::<rustc_middle::ty::Asyncness>()];
}
impl Erasable for
    rustc_middle::ty::Binder<'_, ty::CoroutineWitnessTypes<TyCtxt<'_>>> {
    type Storage =
        [u8; size_of::<rustc_middle::ty::Binder<'_,
                ty::CoroutineWitnessTypes<TyCtxt<'_>>>>()];
}
impl Erasable for rustc_middle::ty::Binder<'_, ty::FnSig<'_>> {
    type Storage =
        [u8; size_of::<rustc_middle::ty::Binder<'_, ty::FnSig<'_>>>()];
}
impl Erasable for rustc_middle::ty::ClosureTypeInfo<'_> {
    type Storage = [u8; size_of::<rustc_middle::ty::ClosureTypeInfo<'_>>()];
}
impl Erasable for rustc_middle::ty::Const<'_> {
    type Storage = [u8; size_of::<rustc_middle::ty::Const<'_>>()];
}
impl Erasable for rustc_middle::ty::ConstConditions<'_> {
    type Storage = [u8; size_of::<rustc_middle::ty::ConstConditions<'_>>()];
}
impl Erasable for rustc_middle::ty::GenericClauses<'_> {
    type Storage = [u8; size_of::<rustc_middle::ty::GenericClauses<'_>>()];
}
impl Erasable for rustc_middle::ty::ImplTraitHeader<'_> {
    type Storage = [u8; size_of::<rustc_middle::ty::ImplTraitHeader<'_>>()];
}
impl Erasable for rustc_middle::ty::ParamEnv<'_> {
    type Storage = [u8; size_of::<rustc_middle::ty::ParamEnv<'_>>()];
}
impl Erasable for rustc_middle::ty::SymbolName<'_> {
    type Storage = [u8; size_of::<rustc_middle::ty::SymbolName<'_>>()];
}
impl Erasable for rustc_middle::ty::TypingEnv<'_> {
    type Storage = [u8; size_of::<rustc_middle::ty::TypingEnv<'_>>()];
}
impl Erasable for rustc_middle::ty::Visibility<ModId> {
    type Storage = [u8; size_of::<rustc_middle::ty::Visibility<ModId>>()];
}
impl Erasable for rustc_middle::ty::inhabitedness::InhabitedPredicate<'_> {
    type Storage =
        [u8; size_of::<rustc_middle::ty::inhabitedness::InhabitedPredicate<'_>>()];
}
impl Erasable for rustc_session::Limits {
    type Storage = [u8; size_of::<rustc_session::Limits>()];
}
impl Erasable for rustc_session::config::OptLevel {
    type Storage = [u8; size_of::<rustc_session::config::OptLevel>()];
}
impl Erasable for rustc_session::config::SymbolManglingVersion {
    type Storage =
        [u8; size_of::<rustc_session::config::SymbolManglingVersion>()];
}
impl Erasable for rustc_span::ExpnId {
    type Storage = [u8; size_of::<rustc_span::ExpnId>()];
}
impl Erasable for rustc_span::Span {
    type Storage = [u8; size_of::<rustc_span::Span>()];
}
impl Erasable for rustc_span::Symbol {
    type Storage = [u8; size_of::<rustc_span::Symbol>()];
}
impl Erasable for rustc_target::spec::PanicStrategy {
    type Storage = [u8; size_of::<rustc_target::spec::PanicStrategy>()];
}
impl Erasable for usize {
    type Storage = [u8; size_of::<usize>()];
}impl_erasable_for_types_with_no_type_params! {
177    // tidy-alphabetical-start
178    &'_ str,
179    (&'_ ty::CrateInherentImpls, Result<(), ErrorGuaranteed>),
180    (),
181    (traits::solve::QueryResult<'_>, &'_ traits::solve::inspect::Probe<TyCtxt<'_>>, ty::RequiredDepth),
182    Option<&'_ OsStr>,
183    Option<&'_ [rustc_hir::PreciseCapturingArgKind<rustc_span::Symbol, rustc_span::Symbol>]>,
184    Option<(mir::ConstValue, Ty<'_>)>,
185    Option<(rustc_span::def_id::DefId, rustc_session::config::EntryFnType)>,
186    Option<rustc_abi::Align>,
187    Option<rustc_ast::expand::allocator::AllocatorKind>,
188    Option<rustc_data_structures::svh::Svh>,
189    Option<rustc_hir::ConstStability>,
190    Option<rustc_hir::CoroutineKind>,
191    Option<rustc_hir::DefaultBodyStability>,
192    Option<rustc_hir::Stability>,
193    Option<rustc_middle::middle::stability::DeprecationEntry>,
194    Option<rustc_middle::ty::AsyncDestructor>,
195    Option<rustc_middle::ty::Destructor>,
196    Option<rustc_middle::ty::IntrinsicDef>,
197    Option<rustc_middle::ty::ScalarInt>,
198    Option<rustc_span::Span>,
199    Option<rustc_span::def_id::CrateNum>,
200    Option<rustc_span::def_id::DefId>,
201    Option<rustc_span::def_id::LocalDefId>,
202    Option<rustc_target::spec::PanicStrategy>,
203    Option<ty::EarlyBinder<'_, Ty<'_>>>,
204    Option<ty::EarlyBinder<'_, ty::Const<'_>>>,
205    Option<ty::Value<'_>>,
206    Option<usize>,
207    Result<&'_ TokenStream, ()>,
208    Result<&'_ rustc_target::callconv::FnAbi<'_, Ty<'_>>, &'_ ty::layout::FnAbiError<'_>>,
209    Result<&'_ traits::ImplSource<'_, ()>, traits::CodegenObligationError>,
210    Result<&'_ ty::List<Ty<'_>>, ty::util::AlwaysRequiresDrop>,
211    Result<(&'_ Steal<thir::Thir<'_>>, thir::ExprId), ErrorGuaranteed>,
212    Result<(&'_ [Spanned<MonoItem<'_>>], &'_ [Spanned<MonoItem<'_>>]), NormalizationErrorInMono>,
213    Result<(), ErrorGuaranteed>,
214    Result<Option<ty::EarlyBinder<'_, ty::Const<'_>>>, ErrorGuaranteed>,
215    Result<Option<ty::Instance<'_>>, ErrorGuaranteed>,
216    Result<bool, &ty::layout::LayoutError<'_>>,
217    Result<mir::ConstAlloc<'_>, mir::interpret::ErrorHandled>,
218    Result<mir::ConstValue, mir::interpret::ErrorHandled>,
219    Result<rustc_abi::TyAndLayout<'_, Ty<'_>>, &ty::layout::LayoutError<'_>>,
220    Result<rustc_middle::traits::EvaluationResult, rustc_middle::traits::OverflowError>,
221    Result<rustc_middle::ty::adjustment::CoerceUnsizedInfo, ErrorGuaranteed>,
222    Result<ty::GenericArg<'_>, traits::query::NoSolution>,
223    Ty<'_>,
224    bool,
225    rustc_crate_store::CrateDepKind,
226    rustc_data_structures::svh::Svh,
227    rustc_hir::Constness,
228    rustc_hir::Defaultness,
229    rustc_hir::HirId,
230    rustc_hir::MaybeOwner<'_>,
231    rustc_hir::OpaqueTyOrigin<rustc_hir::def_id::DefId>,
232    rustc_hir::def::DefKind,
233    rustc_hir::def_id::DefId,
234    rustc_middle::hir::ProjectedMaybeOwner<'_>,
235    rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs,
236    rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault,
237    rustc_middle::mir::ConstQualifs,
238    rustc_middle::mir::ConstValue,
239    rustc_middle::mir::interpret::AllocId,
240    rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'_>,
241    rustc_middle::mir::interpret::EvalToValTreeResult<'_>,
242    rustc_middle::mono::MonoItemPartitions<'_>,
243    rustc_middle::traits::query::MethodAutoderefStepsResult<'_>,
244    rustc_middle::ty::AdtDef<'_>,
245    rustc_middle::ty::AnonConstKind,
246    rustc_middle::ty::AssocItem,
247    rustc_middle::ty::Asyncness,
248    rustc_middle::ty::Binder<'_, ty::CoroutineWitnessTypes<TyCtxt<'_>>>,
249    rustc_middle::ty::Binder<'_, ty::FnSig<'_>>,
250    rustc_middle::ty::ClosureTypeInfo<'_>,
251    rustc_middle::ty::Const<'_>,
252    rustc_middle::ty::ConstConditions<'_>,
253    rustc_middle::ty::GenericClauses<'_>,
254    rustc_middle::ty::ImplTraitHeader<'_>,
255    rustc_middle::ty::ParamEnv<'_>,
256    rustc_middle::ty::SymbolName<'_>,
257    rustc_middle::ty::TypingEnv<'_>,
258    rustc_middle::ty::Visibility<ModId>,
259    rustc_middle::ty::inhabitedness::InhabitedPredicate<'_>,
260    rustc_session::Limits,
261    rustc_session::config::OptLevel,
262    rustc_session::config::SymbolManglingVersion,
263    rustc_span::ExpnId,
264    rustc_span::Span,
265    rustc_span::Symbol,
266    rustc_target::spec::PanicStrategy,
267    usize,
268    // tidy-alphabetical-end
269}