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