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