1use std::intrinsics::transmute_unchecked;
2use std::mem::MaybeUninit;
3
4use rustc_span::ErrorGuaranteed;
5
6use crate::query::CyclePlaceholder;
7use crate::ty::adjustment::CoerceUnsizedInfo;
8use crate::ty::{self, Ty};
9use crate::{mir, traits};
10
11#[derive(Copy, Clone)]
12pub struct Erased<T: Copy> {
13 data: MaybeUninit<T>,
16}
17
18pub trait EraseType: Copy {
19 type Result: Copy;
20}
21
22#[allow(type_alias_bounds)]
24pub type Erase<T: EraseType> = Erased<impl Copy>;
25
26#[inline(always)]
27pub fn erase<T: EraseType>(src: T) -> Erase<T> {
28 const {
30 if std::mem::size_of::<T>() != std::mem::size_of::<T::Result>() {
31 panic!("size of T must match erased type T::Result")
32 }
33 };
34
35 Erased::<<T as EraseType>::Result> {
36 data: unsafe { transmute_unchecked::<T, MaybeUninit<T::Result>>(src) },
45 }
46}
47
48#[inline(always)]
50pub fn restore<T: EraseType>(value: Erase<T>) -> T {
51 let value: Erased<<T as EraseType>::Result> = value;
52 unsafe { transmute_unchecked::<MaybeUninit<T::Result>, T>(value.data) }
58}
59
60impl<T> EraseType for &'_ T {
61 type Result = [u8; size_of::<&'static ()>()];
62}
63
64impl<T> EraseType for &'_ [T] {
65 type Result = [u8; size_of::<&'static [()]>()];
66}
67
68impl<T> EraseType for &'_ ty::List<T> {
69 type Result = [u8; size_of::<&'static ty::List<()>>()];
70}
71
72impl<T> EraseType for &'_ ty::ListWithCachedTypeInfo<T> {
73 type Result = [u8; size_of::<&'static ty::ListWithCachedTypeInfo<()>>()];
74}
75
76impl<I: rustc_index::Idx, T> EraseType for &'_ rustc_index::IndexSlice<I, T> {
77 type Result = [u8; size_of::<&'static rustc_index::IndexSlice<u32, ()>>()];
78}
79
80impl<T> EraseType for Result<&'_ T, traits::query::NoSolution> {
81 type Result = [u8; size_of::<Result<&'static (), traits::query::NoSolution>>()];
82}
83
84impl<T> EraseType for Result<&'_ [T], traits::query::NoSolution> {
85 type Result = [u8; size_of::<Result<&'static [()], traits::query::NoSolution>>()];
86}
87
88impl<T> EraseType for Result<&'_ T, rustc_errors::ErrorGuaranteed> {
89 type Result = [u8; size_of::<Result<&'static (), rustc_errors::ErrorGuaranteed>>()];
90}
91
92impl<T> EraseType for Result<&'_ [T], rustc_errors::ErrorGuaranteed> {
93 type Result = [u8; size_of::<Result<&'static [()], rustc_errors::ErrorGuaranteed>>()];
94}
95
96impl<T> EraseType for Result<&'_ T, traits::CodegenObligationError> {
97 type Result = [u8; size_of::<Result<&'static (), traits::CodegenObligationError>>()];
98}
99
100impl<T> EraseType for Result<&'_ T, &'_ ty::layout::FnAbiError<'_>> {
101 type Result = [u8; size_of::<Result<&'static (), &'static ty::layout::FnAbiError<'static>>>()];
102}
103
104impl<T> EraseType for Result<(&'_ T, crate::thir::ExprId), rustc_errors::ErrorGuaranteed> {
105 type Result = [u8; size_of::<
106 Result<(&'static (), crate::thir::ExprId), rustc_errors::ErrorGuaranteed>,
107 >()];
108}
109
110impl EraseType for Result<Option<ty::Instance<'_>>, rustc_errors::ErrorGuaranteed> {
111 type Result =
112 [u8; size_of::<Result<Option<ty::Instance<'static>>, rustc_errors::ErrorGuaranteed>>()];
113}
114
115impl EraseType for Result<CoerceUnsizedInfo, rustc_errors::ErrorGuaranteed> {
116 type Result = [u8; size_of::<Result<CoerceUnsizedInfo, rustc_errors::ErrorGuaranteed>>()];
117}
118
119impl EraseType
120 for Result<Option<ty::EarlyBinder<'_, ty::Const<'_>>>, rustc_errors::ErrorGuaranteed>
121{
122 type Result = [u8; size_of::<
123 Result<Option<ty::EarlyBinder<'static, ty::Const<'static>>>, rustc_errors::ErrorGuaranteed>,
124 >()];
125}
126
127impl EraseType for Result<ty::GenericArg<'_>, traits::query::NoSolution> {
128 type Result = [u8; size_of::<Result<ty::GenericArg<'static>, traits::query::NoSolution>>()];
129}
130
131impl EraseType for Result<bool, &ty::layout::LayoutError<'_>> {
132 type Result = [u8; size_of::<Result<bool, &'static ty::layout::LayoutError<'static>>>()];
133}
134
135impl EraseType for Result<rustc_abi::TyAndLayout<'_, Ty<'_>>, &ty::layout::LayoutError<'_>> {
136 type Result = [u8; size_of::<
137 Result<
138 rustc_abi::TyAndLayout<'static, Ty<'static>>,
139 &'static ty::layout::LayoutError<'static>,
140 >,
141 >()];
142}
143
144impl EraseType for Result<mir::ConstAlloc<'_>, mir::interpret::ErrorHandled> {
145 type Result = [u8; size_of::<Result<mir::ConstAlloc<'static>, mir::interpret::ErrorHandled>>()];
146}
147
148impl EraseType for Result<mir::ConstValue<'_>, mir::interpret::ErrorHandled> {
149 type Result = [u8; size_of::<Result<mir::ConstValue<'static>, mir::interpret::ErrorHandled>>()];
150}
151
152impl EraseType for Result<Result<ty::ValTree<'_>, Ty<'_>>, mir::interpret::ErrorHandled> {
153 type Result = [u8; size_of::<
154 Result<Result<ty::ValTree<'static>, Ty<'static>>, mir::interpret::ErrorHandled>,
155 >()];
156}
157
158impl EraseType for Result<&'_ ty::List<Ty<'_>>, ty::util::AlwaysRequiresDrop> {
159 type Result =
160 [u8; size_of::<Result<&'static ty::List<Ty<'static>>, ty::util::AlwaysRequiresDrop>>()];
161}
162
163impl EraseType for Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
164 type Result = [u8; size_of::<Result<ty::EarlyBinder<'static, Ty<'_>>, CyclePlaceholder>>()];
165}
166
167impl<T> EraseType for Option<&'_ T> {
168 type Result = [u8; size_of::<Option<&'static ()>>()];
169}
170
171impl<T> EraseType for Option<&'_ [T]> {
172 type Result = [u8; size_of::<Option<&'static [()]>>()];
173}
174
175impl EraseType for Option<mir::DestructuredConstant<'_>> {
176 type Result = [u8; size_of::<Option<mir::DestructuredConstant<'static>>>()];
177}
178
179impl EraseType for Option<ty::ImplTraitHeader<'_>> {
180 type Result = [u8; size_of::<Option<ty::ImplTraitHeader<'static>>>()];
181}
182
183impl EraseType for Option<ty::EarlyBinder<'_, Ty<'_>>> {
184 type Result = [u8; size_of::<Option<ty::EarlyBinder<'static, Ty<'static>>>>()];
185}
186
187impl EraseType for rustc_hir::MaybeOwner<'_> {
188 type Result = [u8; size_of::<rustc_hir::MaybeOwner<'static>>()];
189}
190
191impl<T: EraseType> EraseType for ty::EarlyBinder<'_, T> {
192 type Result = T::Result;
193}
194
195impl EraseType for ty::Binder<'_, ty::FnSig<'_>> {
196 type Result = [u8; size_of::<ty::Binder<'static, ty::FnSig<'static>>>()];
197}
198
199impl EraseType for ty::Binder<'_, &'_ ty::List<Ty<'_>>> {
200 type Result = [u8; size_of::<ty::Binder<'static, &'static ty::List<Ty<'static>>>>()];
201}
202
203impl<T0, T1> EraseType for (&'_ T0, &'_ T1) {
204 type Result = [u8; size_of::<(&'static (), &'static ())>()];
205}
206
207impl<T0, T1> EraseType for (&'_ T0, &'_ [T1]) {
208 type Result = [u8; size_of::<(&'static (), &'static [()])>()];
209}
210
211impl<T0, T1> EraseType for (&'_ [T0], &'_ [T1]) {
212 type Result = [u8; size_of::<(&'static [()], &'static [()])>()];
213}
214
215impl<T0> EraseType for (&'_ T0, Result<(), ErrorGuaranteed>) {
216 type Result = [u8; size_of::<(&'static (), Result<(), ErrorGuaranteed>)>()];
217}
218
219macro_rules! trivial {
220 ($($ty:ty),+ $(,)?) => {
221 $(
222 impl EraseType for $ty {
223 type Result = [u8; size_of::<$ty>()];
224 }
225 )*
226 }
227}
228
229trivial! {
230 (),
231 bool,
232 Option<(rustc_span::def_id::DefId, rustc_session::config::EntryFnType)>,
233 Option<rustc_ast::expand::allocator::AllocatorKind>,
234 Option<rustc_attr_parsing::ConstStability>,
235 Option<rustc_attr_parsing::DefaultBodyStability>,
236 Option<rustc_attr_parsing::Stability>,
237 Option<rustc_data_structures::svh::Svh>,
238 Option<rustc_hir::def::DefKind>,
239 Option<rustc_hir::CoroutineKind>,
240 Option<rustc_hir::HirId>,
241 Option<rustc_middle::middle::stability::DeprecationEntry>,
242 Option<rustc_middle::ty::AsyncDestructor>,
243 Option<rustc_middle::ty::Destructor>,
244 Option<rustc_middle::ty::ImplTraitInTraitData>,
245 Option<rustc_middle::ty::ScalarInt>,
246 Option<rustc_span::def_id::CrateNum>,
247 Option<rustc_span::def_id::DefId>,
248 Option<rustc_span::def_id::LocalDefId>,
249 Option<rustc_span::Span>,
250 Option<rustc_abi::FieldIdx>,
251 Option<rustc_target::spec::PanicStrategy>,
252 Option<usize>,
253 Option<rustc_middle::ty::IntrinsicDef>,
254 Result<(), rustc_errors::ErrorGuaranteed>,
255 Result<(), rustc_middle::traits::query::NoSolution>,
256 Result<rustc_middle::traits::EvaluationResult, rustc_middle::traits::OverflowError>,
257 rustc_abi::ReprOptions,
258 rustc_ast::expand::allocator::AllocatorKind,
259 rustc_attr_parsing::ConstStability,
260 rustc_attr_parsing::DefaultBodyStability,
261 rustc_attr_parsing::Deprecation,
262 rustc_attr_parsing::Stability,
263 rustc_data_structures::svh::Svh,
264 rustc_errors::ErrorGuaranteed,
265 rustc_hir::Constness,
266 rustc_hir::def_id::DefId,
267 rustc_hir::def_id::DefIndex,
268 rustc_hir::def_id::LocalDefId,
269 rustc_hir::def_id::LocalModDefId,
270 rustc_hir::def::DefKind,
271 rustc_hir::Defaultness,
272 rustc_hir::definitions::DefKey,
273 rustc_hir::CoroutineKind,
274 rustc_hir::HirId,
275 rustc_hir::IsAsync,
276 rustc_hir::ItemLocalId,
277 rustc_hir::LangItem,
278 rustc_hir::OpaqueTyOrigin<rustc_hir::def_id::DefId>,
279 rustc_hir::OwnerId,
280 rustc_hir::Upvar,
281 rustc_index::bit_set::FiniteBitSet<u32>,
282 rustc_middle::middle::dependency_format::Linkage,
283 rustc_middle::middle::exported_symbols::SymbolExportInfo,
284 rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault,
285 rustc_middle::middle::resolve_bound_vars::ResolvedArg,
286 rustc_middle::middle::stability::DeprecationEntry,
287 rustc_middle::mir::ConstQualifs,
288 rustc_middle::mir::interpret::AllocId,
289 rustc_middle::mir::interpret::CtfeProvenance,
290 rustc_middle::mir::interpret::ErrorHandled,
291 rustc_middle::thir::ExprId,
292 rustc_middle::traits::CodegenObligationError,
293 rustc_middle::traits::EvaluationResult,
294 rustc_middle::traits::OverflowError,
295 rustc_middle::traits::query::NoSolution,
296 rustc_middle::traits::WellFormedLoc,
297 rustc_middle::ty::adjustment::CoerceUnsizedInfo,
298 rustc_middle::ty::AssocItem,
299 rustc_middle::ty::AssocItemContainer,
300 rustc_middle::ty::Asyncness,
301 rustc_middle::ty::AsyncDestructor,
302 rustc_middle::ty::BoundVariableKind,
303 rustc_middle::ty::DeducedParamAttrs,
304 rustc_middle::ty::Destructor,
305 rustc_middle::ty::fast_reject::SimplifiedType,
306 rustc_middle::ty::ImplPolarity,
307 rustc_middle::ty::Representability,
308 rustc_middle::ty::UnusedGenericParams,
309 rustc_middle::ty::util::AlwaysRequiresDrop,
310 rustc_middle::ty::Visibility<rustc_span::def_id::DefId>,
311 rustc_session::config::CrateType,
312 rustc_session::config::EntryFnType,
313 rustc_session::config::OptLevel,
314 rustc_session::config::SymbolManglingVersion,
315 rustc_session::cstore::CrateDepKind,
316 rustc_session::cstore::ExternCrate,
317 rustc_session::cstore::LinkagePreference,
318 rustc_session::Limits,
319 rustc_session::lint::LintExpectationId,
320 rustc_span::def_id::CrateNum,
321 rustc_span::def_id::DefPathHash,
322 rustc_span::ExpnHash,
323 rustc_span::ExpnId,
324 rustc_span::Span,
325 rustc_span::Symbol,
326 rustc_span::Ident,
327 rustc_target::spec::PanicStrategy,
328 rustc_type_ir::Variance,
329 u32,
330 usize,
331}
332
333macro_rules! tcx_lifetime {
334 ($($($fake_path:ident)::+),+ $(,)?) => {
335 $(
336 impl<'tcx> EraseType for $($fake_path)::+<'tcx> {
337 type Result = [u8; size_of::<$($fake_path)::+<'static>>()];
338 }
339 )*
340 }
341}
342
343tcx_lifetime! {
344 rustc_middle::middle::exported_symbols::ExportedSymbol,
345 rustc_middle::mir::Const,
346 rustc_middle::mir::DestructuredConstant,
347 rustc_middle::mir::ConstAlloc,
348 rustc_middle::mir::ConstValue,
349 rustc_middle::mir::interpret::GlobalId,
350 rustc_middle::mir::interpret::LitToConstInput,
351 rustc_middle::mir::interpret::EvalStaticInitializerRawResult,
352 rustc_middle::mir::mono::MonoItemPartitions,
353 rustc_middle::traits::query::MethodAutoderefStepsResult,
354 rustc_middle::traits::query::type_op::AscribeUserType,
355 rustc_middle::traits::query::type_op::Eq,
356 rustc_middle::traits::query::type_op::ProvePredicate,
357 rustc_middle::traits::query::type_op::Subtype,
358 rustc_middle::ty::AdtDef,
359 rustc_middle::ty::AliasTy,
360 rustc_middle::ty::ClauseKind,
361 rustc_middle::ty::ClosureTypeInfo,
362 rustc_middle::ty::Const,
363 rustc_middle::ty::DestructuredConst,
364 rustc_middle::ty::ExistentialTraitRef,
365 rustc_middle::ty::FnSig,
366 rustc_middle::ty::GenericArg,
367 rustc_middle::ty::GenericPredicates,
368 rustc_middle::ty::ConstConditions,
369 rustc_middle::ty::inhabitedness::InhabitedPredicate,
370 rustc_middle::ty::Instance,
371 rustc_middle::ty::InstanceKind,
372 rustc_middle::ty::layout::FnAbiError,
373 rustc_middle::ty::layout::LayoutError,
374 rustc_middle::ty::ParamEnv,
375 rustc_middle::ty::Predicate,
376 rustc_middle::ty::SymbolName,
377 rustc_middle::ty::TraitRef,
378 rustc_middle::ty::Ty,
379 rustc_middle::ty::UnevaluatedConst,
380 rustc_middle::ty::ValTree,
381 rustc_middle::ty::VtblEntry,
382}