1use 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_span::def_id::ModId;
17use rustc_span::{ErrorGuaranteed, Spanned};
18
19use crate::mono::{MonoItem, NormalizationErrorInMono};
20use crate::ty::{self, Ty, TyCtxt};
21use crate::{mir, thir, traits};
22
23unsafe extern "C" {
24 type NoAutoTraits;
25}
26
27#[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)]
29pub struct ErasedData<Storage: Copy> {
30 data: MaybeUninit<Storage>,
33 no_auto_traits: PhantomData<NoAutoTraits>,
36}
37
38unsafe impl<Storage: Copy> DynSync for ErasedData<Storage> {}
40unsafe impl<Storage: Copy> DynSend for ErasedData<Storage> {}
41
42pub trait Erasable: Copy {
49 type Storage: Copy;
55}
56
57pub type Erased<T: Erasable> = ErasedData<impl Copy>;
66
67#[inline(always)]
72#[define_opaque(Erased)]
73pub fn erase_val<T: Erasable + DynSend + DynSync>(value: T) -> Erased<T> {
76 const {
78 if size_of::<T>() != size_of::<T::Storage>() {
79 {
::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")
80 }
81 };
82
83 ErasedData::<<T as Erasable>::Storage> {
84 data: unsafe { transmute_unchecked::<T, MaybeUninit<T::Storage>>(value) },
93 no_auto_traits: PhantomData,
94 }
95}
96
97#[inline(always)]
102#[define_opaque(Erased)]
103pub fn restore_val<T: Erasable>(erased_value: Erased<T>) -> T {
104 let ErasedData { data, .. }: ErasedData<<T as Erasable>::Storage> = erased_value;
105 unsafe { transmute_unchecked::<MaybeUninit<T::Storage>, T>(data) }
111}
112
113impl<T> Erasable for &'_ T {
114 type Storage = [u8; size_of::<&'_ ()>()];
115}
116
117impl<T> Erasable for &'_ [T] {
118 type Storage = [u8; size_of::<&'_ [()]>()];
119}
120
121impl<H, T> Erasable for &'_ ty::RawList<H, T> {
128 type Storage = [u8; size_of::<&'_ ty::RawList<(), ()>>()];
129}
130
131impl<T> Erasable for Result<&'_ T, traits::query::NoSolution> {
132 type Storage = [u8; size_of::<Result<&'_ (), traits::query::NoSolution>>()];
133}
134
135impl<T> Erasable for Result<&'_ T, ErrorGuaranteed> {
136 type Storage = [u8; size_of::<Result<&'_ (), ErrorGuaranteed>>()];
137}
138
139impl<T> Erasable for Option<&'_ T> {
140 type Storage = [u8; size_of::<Option<&'_ ()>>()];
141}
142
143impl<T: Erasable> Erasable for ty::EarlyBinder<'_, T> {
144 type Storage = T::Storage;
145}
146
147impl<T0, T1> Erasable for (&'_ T0, &'_ T1) {
148 type Storage = [u8; size_of::<(&'_ (), &'_ ())>()];
149}
150
151impl<T0, T1, T2> Erasable for (&'_ T0, &'_ T1, &'_ T2) {
152 type Storage = [u8; size_of::<(&'_ (), &'_ (), &'_ ())>()];
153}
154
155impl<T0, T1> Erasable for (&'_ [T0], &'_ [T1]) {
156 type Storage = [u8; size_of::<(&'_ [()], &'_ [()])>()];
157}
158
159macro_rules! impl_erasable_for_types_with_no_type_params {
160 ($($ty:ty),+ $(,)?) => {
161 $(
162 impl Erasable for $ty {
163 type Storage = [u8; size_of::<$ty>()];
164 }
165 )*
166 }
167}
168
169impl Erasable for usize {
type Storage = [u8; size_of::<usize>()];
}impl_erasable_for_types_with_no_type_params! {
172 (&'_ ty::CrateInherentImpls, Result<(), ErrorGuaranteed>),
174 (),
175 (traits::solve::QueryResult<'_>, &'_ traits::solve::inspect::Probe<TyCtxt<'_>>),
176 Option<&'_ OsStr>,
177 Option<&'_ [rustc_hir::PreciseCapturingArgKind<rustc_span::Symbol, rustc_span::Symbol>]>,
178 Option<(mir::ConstValue, Ty<'_>)>,
179 Option<(rustc_span::def_id::DefId, rustc_session::config::EntryFnType)>,
180 Option<rustc_abi::Align>,
181 Option<rustc_ast::expand::allocator::AllocatorKind>,
182 Option<rustc_data_structures::svh::Svh>,
183 Option<rustc_hir::ConstStability>,
184 Option<rustc_hir::CoroutineKind>,
185 Option<rustc_hir::DefaultBodyStability>,
186 Option<rustc_hir::Stability>,
187 Option<rustc_middle::middle::stability::DeprecationEntry>,
188 Option<rustc_middle::ty::AsyncDestructor>,
189 Option<rustc_middle::ty::Destructor>,
190 Option<rustc_middle::ty::IntrinsicDef>,
191 Option<rustc_middle::ty::ScalarInt>,
192 Option<rustc_span::Span>,
193 Option<rustc_span::def_id::CrateNum>,
194 Option<rustc_span::def_id::DefId>,
195 Option<rustc_span::def_id::LocalDefId>,
196 Option<rustc_target::spec::PanicStrategy>,
197 Option<ty::EarlyBinder<'_, Ty<'_>>>,
198 Option<ty::Value<'_>>,
199 Option<usize>,
200 Result<&'_ TokenStream, ()>,
201 Result<&'_ rustc_target::callconv::FnAbi<'_, Ty<'_>>, &'_ ty::layout::FnAbiError<'_>>,
202 Result<&'_ traits::ImplSource<'_, ()>, traits::CodegenObligationError>,
203 Result<&'_ ty::List<Ty<'_>>, ty::util::AlwaysRequiresDrop>,
204 Result<(&'_ Steal<thir::Thir<'_>>, thir::ExprId), ErrorGuaranteed>,
205 Result<(&'_ [Spanned<MonoItem<'_>>], &'_ [Spanned<MonoItem<'_>>]), NormalizationErrorInMono>,
206 Result<(), ErrorGuaranteed>,
207 Result<Option<ty::EarlyBinder<'_, ty::Const<'_>>>, ErrorGuaranteed>,
208 Result<Option<ty::Instance<'_>>, ErrorGuaranteed>,
209 Result<bool, &ty::layout::LayoutError<'_>>,
210 Result<mir::ConstAlloc<'_>, mir::interpret::ErrorHandled>,
211 Result<mir::ConstValue, mir::interpret::ErrorHandled>,
212 Result<rustc_abi::TyAndLayout<'_, Ty<'_>>, &ty::layout::LayoutError<'_>>,
213 Result<rustc_middle::traits::EvaluationResult, rustc_middle::traits::OverflowError>,
214 Result<rustc_middle::ty::adjustment::CoerceUnsizedInfo, ErrorGuaranteed>,
215 Result<ty::GenericArg<'_>, traits::query::NoSolution>,
216 Ty<'_>,
217 bool,
218 rustc_data_structures::svh::Svh,
219 rustc_hir::Constness,
220 rustc_hir::Defaultness,
221 rustc_hir::HirId,
222 rustc_hir::MaybeOwner<'_>,
223 rustc_hir::OpaqueTyOrigin<rustc_hir::def_id::DefId>,
224 rustc_hir::def::DefKind,
225 rustc_hir::def_id::DefId,
226 rustc_middle::hir::ProjectedMaybeOwner<'_>,
227 rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs,
228 rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault,
229 rustc_middle::mir::ConstQualifs,
230 rustc_middle::mir::ConstValue,
231 rustc_middle::mir::interpret::AllocId,
232 rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'_>,
233 rustc_middle::mir::interpret::EvalToValTreeResult<'_>,
234 rustc_middle::mono::MonoItemPartitions<'_>,
235 rustc_middle::traits::query::MethodAutoderefStepsResult<'_>,
236 rustc_middle::ty::AdtDef<'_>,
237 rustc_middle::ty::AnonConstKind,
238 rustc_middle::ty::AssocItem,
239 rustc_middle::ty::Asyncness,
240 rustc_middle::ty::Binder<'_, ty::CoroutineWitnessTypes<TyCtxt<'_>>>,
241 rustc_middle::ty::Binder<'_, ty::FnSig<'_>>,
242 rustc_middle::ty::ClosureTypeInfo<'_>,
243 rustc_middle::ty::Const<'_>,
244 rustc_middle::ty::ConstConditions<'_>,
245 rustc_middle::ty::GenericClauses<'_>,
246 rustc_middle::ty::ImplTraitHeader<'_>,
247 rustc_middle::ty::ParamEnv<'_>,
248 rustc_middle::ty::SymbolName<'_>,
249 rustc_middle::ty::TypingEnv<'_>,
250 rustc_middle::ty::Visibility<ModId>,
251 rustc_middle::ty::inhabitedness::InhabitedPredicate<'_>,
252 rustc_session::Limits,
253 rustc_session::config::OptLevel,
254 rustc_session::config::SymbolManglingVersion,
255 rustc_session::cstore::CrateDepKind,
256 rustc_span::ExpnId,
257 rustc_span::Span,
258 rustc_span::Symbol,
259 rustc_target::spec::PanicStrategy,
260 usize,
261 }