use alloc::borrow::ToOwned;
use alloc::boxed::Box;
use alloc::format;
use alloc::string::{String, ToString};
use alloc::vec;
use alloc::vec::Vec;
use core::marker::PhantomData;
use core::mem::transmute_copy;
use core::mem::MaybeUninit;
use crate::rustc_ast::tokenstream::TokenStream;
use crate::rustc_data_structures::steal::Steal;
use crate::rustc_data_structures::sync::{DynSend, DynSync};
use crate::rustc_span::def_id::ModId;
use crate::rustc_span::{ErrorGuaranteed, Spanned};
use crate::rustc_middle::mono::{MonoItem, NormalizationErrorInMono};
use crate::rustc_middle::ty::{self, Ty, TyCtxt};
use crate::rustc_middle::{mir, thir, traits};
type NoAutoTraits = *const ();
#[derive(Copy, Clone)]
pub struct ErasedData<Storage: Copy> {
data: MaybeUninit<Storage>,
no_auto_traits: PhantomData<NoAutoTraits>,
}
pub trait Erasable: Copy {
type Storage: Copy;
}
pub struct Erased<T: Erasable> {
data: ErasedData<<T as Erasable>::Storage>,
_type: PhantomData<fn() -> T>,
}
impl<T: Erasable> Copy for Erased<T> {}
impl<T: Erasable> Clone for Erased<T> {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}
#[inline(always)]
pub fn erase_val<T: Erasable + DynSend + DynSync>(value: T) -> Erased<T> {
const {
if size_of::<T>() != size_of::<T::Storage>() {
panic!("size of T must match erased type <T as Erasable>::Storage")
}
};
Erased {
data: ErasedData::<<T as Erasable>::Storage> {
data: unsafe { transmute_copy::<T, MaybeUninit<T::Storage>>(&value) },
no_auto_traits: PhantomData,
},
_type: PhantomData,
}
}
#[inline(always)]
pub fn restore_val<T: Erasable>(erased_value: Erased<T>) -> T {
let Erased { data: ErasedData { data, .. }, .. } = erased_value;
unsafe { transmute_copy::<MaybeUninit<T::Storage>, T>(&data) }
}
impl<T> Erasable for &'_ T {
type Storage = [u8; size_of::<&'_ ()>()];
}
impl<T> Erasable for &'_ [T] {
type Storage = [u8; size_of::<&'_ [()]>()];
}
impl<T> Erasable for Result<&'_ T, traits::query::NoSolution> {
type Storage = [u8; size_of::<Result<&'_ (), traits::query::NoSolution>>()];
}
impl<T> Erasable for Result<&'_ T, ErrorGuaranteed> {
type Storage = [u8; size_of::<Result<&'_ (), ErrorGuaranteed>>()];
}
impl<T> Erasable for Option<&'_ T> {
type Storage = [u8; size_of::<Option<&'_ ()>>()];
}
impl<T: Erasable> Erasable for ty::EarlyBinder<'_, T> {
type Storage = T::Storage;
}
impl<T0, T1> Erasable for (&'_ T0, &'_ T1) {
type Storage = [u8; size_of::<(&'_ (), &'_ ())>()];
}
impl<T0, T1, T2> Erasable for (&'_ T0, &'_ T1, &'_ T2) {
type Storage = [u8; size_of::<(&'_ (), &'_ (), &'_ ())>()];
}
impl<T0, T1> Erasable for (&'_ [T0], &'_ [T1]) {
type Storage = [u8; size_of::<(&'_ [()], &'_ [()])>()];
}
macro_rules! impl_erasable_for_types_with_no_type_params {
($($ty:ty),+ $(,)?) => {
$(
impl Erasable for $ty {
type Storage = [u8; size_of::<$ty>()];
}
)*
}
}
impl_erasable_for_types_with_no_type_params! {
(&'_ ty::CrateInherentImpls, Result<(), ErrorGuaranteed>),
(),
(traits::solve::QueryResult<'_>, &'_ traits::solve::inspect::Probe<TyCtxt<'_>>, ty::RequiredDepth),
Option<&'_ [crate::rustc_hir::PreciseCapturingArgKind<crate::rustc_span::Symbol, crate::rustc_span::Symbol>]>,
Option<&'_ [u8]>,
Option<(mir::ConstValue, Ty<'_>)>,
Option<(crate::rustc_span::def_id::DefId, crate::rustc_session::config::EntryFnType)>,
Option<crate::rustc_abi::Align>,
Option<crate::rustc_ast::expand::allocator::AllocatorKind>,
Option<crate::rustc_data_structures::svh::Svh>,
Option<crate::rustc_hir::ConstStability>,
Option<crate::rustc_hir::CoroutineKind>,
Option<crate::rustc_hir::DefaultBodyStability>,
Option<crate::rustc_hir::Stability>,
Option<crate::rustc_middle::middle::stability::DeprecationEntry>,
Option<crate::rustc_middle::ty::AsyncDestructor>,
Option<crate::rustc_middle::ty::Destructor>,
Option<crate::rustc_middle::ty::IntrinsicDef>,
Option<crate::rustc_middle::ty::ScalarInt>,
Option<crate::rustc_span::Span>,
Option<crate::rustc_span::def_id::CrateNum>,
Option<crate::rustc_span::def_id::DefId>,
Option<crate::rustc_span::def_id::LocalDefId>,
Option<crate::rustc_target::spec::PanicStrategy>,
Option<ty::EarlyBinder<'_, Ty<'_>>>,
Option<ty::Value<'_>>,
Option<usize>,
Result<&'_ TokenStream, ()>,
Result<&'_ crate::rustc_target::callconv::FnAbi<'_, Ty<'_>>, &'_ ty::layout::FnAbiError<'_>>,
Result<&'_ traits::ImplSource<'_, ()>, traits::CodegenObligationError>,
Result<&'_ ty::List<Ty<'_>>, ty::util::AlwaysRequiresDrop>,
Result<(&'_ Steal<thir::Thir<'_>>, thir::ExprId), ErrorGuaranteed>,
Result<(&'_ [Spanned<MonoItem<'_>>], &'_ [Spanned<MonoItem<'_>>]), NormalizationErrorInMono>,
Result<(), ErrorGuaranteed>,
Result<Option<ty::EarlyBinder<'_, ty::Const<'_>>>, ErrorGuaranteed>,
Result<Option<ty::Instance<'_>>, ErrorGuaranteed>,
Result<bool, &ty::layout::LayoutError<'_>>,
Result<mir::ConstAlloc<'_>, mir::interpret::ErrorHandled>,
Result<mir::ConstValue, mir::interpret::ErrorHandled>,
Result<crate::rustc_abi::TyAndLayout<'_, Ty<'_>>, &ty::layout::LayoutError<'_>>,
Result<crate::rustc_middle::traits::EvaluationResult, crate::rustc_middle::traits::OverflowError>,
Result<crate::rustc_middle::ty::adjustment::CoerceUnsizedInfo, ErrorGuaranteed>,
Result<ty::GenericArg<'_>, traits::query::NoSolution>,
Ty<'_>,
bool,
crate::rustc_crate_store::CrateDepKind,
crate::rustc_data_structures::svh::Svh,
crate::rustc_hir::Constness,
crate::rustc_hir::Defaultness,
crate::rustc_hir::HirId,
crate::rustc_hir::MaybeOwner<'_>,
crate::rustc_hir::OpaqueTyOrigin<crate::rustc_hir::def_id::DefId>,
crate::rustc_hir::def::DefKind,
crate::rustc_hir::def_id::DefId,
crate::rustc_middle::hir::ProjectedMaybeOwner<'_>,
crate::rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs,
crate::rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault,
crate::rustc_middle::mir::ConstQualifs,
crate::rustc_middle::mir::ConstValue,
crate::rustc_middle::mir::interpret::AllocId,
crate::rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'_>,
crate::rustc_middle::mir::interpret::EvalToValTreeResult<'_>,
crate::rustc_middle::mono::MonoItemPartitions<'_>,
crate::rustc_middle::traits::query::MethodAutoderefStepsResult<'_>,
crate::rustc_middle::ty::AdtDef<'_>,
crate::rustc_middle::ty::AnonConstKind,
crate::rustc_middle::ty::AssocItem,
crate::rustc_middle::ty::Asyncness,
crate::rustc_middle::ty::Binder<'_, ty::CoroutineWitnessTypes<TyCtxt<'_>>>,
crate::rustc_middle::ty::Binder<'_, ty::FnSig<'_>>,
crate::rustc_middle::ty::ClosureTypeInfo<'_>,
crate::rustc_middle::ty::Const<'_>,
crate::rustc_middle::ty::ConstConditions<'_>,
crate::rustc_middle::ty::GenericClauses<'_>,
crate::rustc_middle::ty::ImplTraitHeader<'_>,
crate::rustc_middle::ty::ParamEnv<'_>,
crate::rustc_middle::ty::SymbolName<'_>,
crate::rustc_middle::ty::TypingEnv<'_>,
crate::rustc_middle::ty::Visibility<ModId>,
crate::rustc_middle::ty::inhabitedness::InhabitedPredicate<'_>,
crate::rustc_session::Limits,
crate::rustc_session::config::OptLevel,
crate::rustc_session::config::SymbolManglingVersion,
crate::rustc_span::ExpnId,
crate::rustc_span::Span,
crate::rustc_span::Symbol,
crate::rustc_target::spec::PanicStrategy,
usize,
}