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