]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/query/erase.rs
New upstream version 1.73.0+dfsg1
[rustc.git] / compiler / rustc_middle / src / query / erase.rs
CommitLineData
353b0b11
FG
1use crate::mir;
2use crate::traits;
3use crate::ty::{self, Ty};
4use std::mem::{size_of, transmute_copy, MaybeUninit};
5
6#[derive(Copy, Clone)]
7pub struct Erased<T: Copy> {
8 // We use `MaybeUninit` here so we can store any value
9 // in `data` since we aren't actually storing a `T`.
10 data: MaybeUninit<T>,
11}
12
13pub trait EraseType: Copy {
14 type Result: Copy;
15}
16
17// Allow `type_alias_bounds` since compilation will fail without `EraseType`.
18#[allow(type_alias_bounds)]
19pub type Erase<T: EraseType> = Erased<impl Copy>;
20
21#[inline(always)]
22pub fn erase<T: EraseType>(src: T) -> Erase<T> {
23 // Ensure the sizes match
24 const {
25 if std::mem::size_of::<T>() != std::mem::size_of::<T::Result>() {
26 panic!("size of T must match erased type T::Result")
27 }
28 };
29
30 Erased::<<T as EraseType>::Result> {
49aad941 31 // SAFETY: It is safe to transmute to MaybeUninit for types with the same sizes.
353b0b11
FG
32 data: unsafe { transmute_copy(&src) },
33 }
34}
35
36/// Restores an erased value.
37#[inline(always)]
38pub fn restore<T: EraseType>(value: Erase<T>) -> T {
39 let value: Erased<<T as EraseType>::Result> = value;
40 // SAFETY: Due to the use of impl Trait in `Erase` the only way to safely create an instance
41 // of `Erase` is to call `erase`, so we know that `value.data` is a valid instance of `T` of
42 // the right size.
43 unsafe { transmute_copy(&value.data) }
44}
45
46impl<T> EraseType for &'_ T {
47 type Result = [u8; size_of::<*const ()>()];
48}
49
50impl<T> EraseType for &'_ [T] {
51 type Result = [u8; size_of::<*const [()]>()];
52}
53
54impl<T> EraseType for &'_ ty::List<T> {
55 type Result = [u8; size_of::<*const ()>()];
56}
57
fe692bf9
FG
58impl<I: rustc_index::Idx, T> EraseType for &'_ rustc_index::IndexSlice<I, T> {
59 type Result = [u8; size_of::<&'static rustc_index::IndexSlice<u32, ()>>()];
60}
61
353b0b11
FG
62impl<T> EraseType for Result<&'_ T, traits::query::NoSolution> {
63 type Result = [u8; size_of::<Result<&'static (), traits::query::NoSolution>>()];
64}
65
66impl<T> EraseType for Result<&'_ T, rustc_errors::ErrorGuaranteed> {
67 type Result = [u8; size_of::<Result<&'static (), rustc_errors::ErrorGuaranteed>>()];
68}
69
70impl<T> EraseType for Result<&'_ T, traits::CodegenObligationError> {
71 type Result = [u8; size_of::<Result<&'static (), traits::CodegenObligationError>>()];
72}
73
fe692bf9
FG
74impl<T> EraseType for Result<&'_ T, &'_ ty::layout::FnAbiError<'_>> {
75 type Result = [u8; size_of::<Result<&'static (), &'static ty::layout::FnAbiError<'static>>>()];
353b0b11
FG
76}
77
78impl<T> EraseType for Result<(&'_ T, rustc_middle::thir::ExprId), rustc_errors::ErrorGuaranteed> {
79 type Result = [u8; size_of::<
80 Result<(&'static (), rustc_middle::thir::ExprId), rustc_errors::ErrorGuaranteed>,
81 >()];
82}
83
84impl EraseType for Result<Option<ty::Instance<'_>>, rustc_errors::ErrorGuaranteed> {
85 type Result =
86 [u8; size_of::<Result<Option<ty::Instance<'static>>, rustc_errors::ErrorGuaranteed>>()];
87}
88
49aad941
FG
89impl EraseType for Result<Option<ty::EarlyBinder<ty::Const<'_>>>, rustc_errors::ErrorGuaranteed> {
90 type Result = [u8; size_of::<
91 Result<Option<ty::EarlyBinder<ty::Const<'static>>>, rustc_errors::ErrorGuaranteed>,
92 >()];
353b0b11
FG
93}
94
95impl EraseType for Result<ty::GenericArg<'_>, traits::query::NoSolution> {
96 type Result = [u8; size_of::<Result<ty::GenericArg<'static>, traits::query::NoSolution>>()];
97}
98
fe692bf9
FG
99impl EraseType for Result<bool, &ty::layout::LayoutError<'_>> {
100 type Result = [u8; size_of::<Result<bool, &'static ty::layout::LayoutError<'static>>>()];
353b0b11
FG
101}
102
fe692bf9
FG
103impl EraseType
104 for Result<rustc_target::abi::TyAndLayout<'_, Ty<'_>>, &ty::layout::LayoutError<'_>>
105{
353b0b11
FG
106 type Result = [u8; size_of::<
107 Result<
108 rustc_target::abi::TyAndLayout<'static, Ty<'static>>,
fe692bf9 109 &'static ty::layout::LayoutError<'static>,
353b0b11
FG
110 >,
111 >()];
112}
113
114impl EraseType for Result<ty::Const<'_>, mir::interpret::LitToConstError> {
115 type Result = [u8; size_of::<Result<ty::Const<'static>, mir::interpret::LitToConstError>>()];
116}
117
118impl EraseType for Result<mir::ConstantKind<'_>, mir::interpret::LitToConstError> {
119 type Result =
120 [u8; size_of::<Result<mir::ConstantKind<'static>, mir::interpret::LitToConstError>>()];
121}
122
123impl EraseType for Result<mir::interpret::ConstAlloc<'_>, mir::interpret::ErrorHandled> {
124 type Result = [u8; size_of::<
125 Result<mir::interpret::ConstAlloc<'static>, mir::interpret::ErrorHandled>,
126 >()];
127}
128
129impl EraseType for Result<mir::interpret::ConstValue<'_>, mir::interpret::ErrorHandled> {
130 type Result = [u8; size_of::<
131 Result<mir::interpret::ConstValue<'static>, mir::interpret::ErrorHandled>,
132 >()];
133}
134
135impl EraseType for Result<Option<ty::ValTree<'_>>, mir::interpret::ErrorHandled> {
136 type Result =
137 [u8; size_of::<Result<Option<ty::ValTree<'static>>, mir::interpret::ErrorHandled>>()];
138}
139
140impl EraseType for Result<&'_ ty::List<Ty<'_>>, ty::util::AlwaysRequiresDrop> {
141 type Result =
142 [u8; size_of::<Result<&'static ty::List<Ty<'static>>, ty::util::AlwaysRequiresDrop>>()];
143}
144
145impl<T> EraseType for Option<&'_ T> {
146 type Result = [u8; size_of::<Option<&'static ()>>()];
147}
148
149impl<T> EraseType for Option<&'_ [T]> {
150 type Result = [u8; size_of::<Option<&'static [()]>>()];
151}
152
153impl EraseType for Option<rustc_middle::hir::Owner<'_>> {
154 type Result = [u8; size_of::<Option<rustc_middle::hir::Owner<'static>>>()];
155}
156
157impl EraseType for Option<mir::DestructuredConstant<'_>> {
158 type Result = [u8; size_of::<Option<mir::DestructuredConstant<'static>>>()];
159}
160
161impl EraseType for Option<ty::EarlyBinder<ty::TraitRef<'_>>> {
162 type Result = [u8; size_of::<Option<ty::EarlyBinder<ty::TraitRef<'static>>>>()];
163}
164
165impl EraseType for Option<ty::EarlyBinder<Ty<'_>>> {
166 type Result = [u8; size_of::<Option<ty::EarlyBinder<Ty<'static>>>>()];
167}
168
169impl<T> EraseType for rustc_hir::MaybeOwner<&'_ T> {
170 type Result = [u8; size_of::<rustc_hir::MaybeOwner<&'static ()>>()];
171}
172
173impl<T: EraseType> EraseType for ty::EarlyBinder<T> {
174 type Result = T::Result;
175}
176
177impl EraseType for ty::Binder<'_, ty::FnSig<'_>> {
178 type Result = [u8; size_of::<ty::Binder<'static, ty::FnSig<'static>>>()];
179}
180
49aad941
FG
181impl EraseType for ty::Binder<'_, &'_ ty::List<Ty<'_>>> {
182 type Result = [u8; size_of::<ty::Binder<'static, &'static ty::List<Ty<'static>>>>()];
183}
184
353b0b11
FG
185impl<T0, T1> EraseType for (&'_ T0, &'_ T1) {
186 type Result = [u8; size_of::<(&'static (), &'static ())>()];
187}
188
189impl<T0, T1> EraseType for (&'_ T0, &'_ [T1]) {
190 type Result = [u8; size_of::<(&'static (), &'static [()])>()];
191}
192
193macro_rules! trivial {
194 ($($ty:ty),+ $(,)?) => {
195 $(
196 impl EraseType for $ty {
197 type Result = [u8; size_of::<$ty>()];
198 }
199 )*
200 }
201}
202
203trivial! {
204 (),
205 bool,
206 Option<(rustc_span::def_id::DefId, rustc_session::config::EntryFnType)>,
207 Option<rustc_ast::expand::allocator::AllocatorKind>,
208 Option<rustc_attr::ConstStability>,
209 Option<rustc_attr::DefaultBodyStability>,
210 Option<rustc_attr::Stability>,
211 Option<rustc_data_structures::svh::Svh>,
212 Option<rustc_hir::def::DefKind>,
213 Option<rustc_hir::GeneratorKind>,
214 Option<rustc_hir::HirId>,
215 Option<rustc_middle::middle::stability::DeprecationEntry>,
216 Option<rustc_middle::ty::Destructor>,
217 Option<rustc_middle::ty::ImplTraitInTraitData>,
218 Option<rustc_span::def_id::CrateNum>,
219 Option<rustc_span::def_id::DefId>,
220 Option<rustc_span::def_id::LocalDefId>,
221 Option<rustc_span::Span>,
222 Option<rustc_target::spec::PanicStrategy>,
223 Option<usize>,
224 Result<(), rustc_errors::ErrorGuaranteed>,
225 Result<(), rustc_middle::traits::query::NoSolution>,
226 Result<rustc_middle::traits::EvaluationResult, rustc_middle::traits::OverflowError>,
227 rustc_ast::expand::allocator::AllocatorKind,
228 rustc_attr::ConstStability,
229 rustc_attr::DefaultBodyStability,
230 rustc_attr::Deprecation,
231 rustc_attr::Stability,
232 rustc_data_structures::svh::Svh,
233 rustc_errors::ErrorGuaranteed,
234 rustc_hir::Constness,
235 rustc_hir::def_id::DefId,
236 rustc_hir::def_id::DefIndex,
237 rustc_hir::def_id::LocalDefId,
add651ee 238 rustc_hir::def_id::LocalModDefId,
353b0b11
FG
239 rustc_hir::def::DefKind,
240 rustc_hir::Defaultness,
241 rustc_hir::definitions::DefKey,
242 rustc_hir::GeneratorKind,
243 rustc_hir::HirId,
244 rustc_hir::IsAsync,
245 rustc_hir::ItemLocalId,
246 rustc_hir::LangItem,
247 rustc_hir::OwnerId,
248 rustc_hir::Upvar,
249 rustc_index::bit_set::FiniteBitSet<u32>,
250 rustc_middle::middle::dependency_format::Linkage,
251 rustc_middle::middle::exported_symbols::SymbolExportInfo,
252 rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault,
253 rustc_middle::middle::resolve_bound_vars::ResolvedArg,
254 rustc_middle::middle::stability::DeprecationEntry,
255 rustc_middle::mir::ConstQualifs,
256 rustc_middle::mir::interpret::AllocId,
257 rustc_middle::mir::interpret::ErrorHandled,
258 rustc_middle::mir::interpret::LitToConstError,
259 rustc_middle::thir::ExprId,
260 rustc_middle::traits::CodegenObligationError,
261 rustc_middle::traits::EvaluationResult,
262 rustc_middle::traits::OverflowError,
263 rustc_middle::traits::query::NoSolution,
264 rustc_middle::traits::WellFormedLoc,
265 rustc_middle::ty::adjustment::CoerceUnsizedInfo,
266 rustc_middle::ty::AssocItem,
267 rustc_middle::ty::AssocItemContainer,
268 rustc_middle::ty::BoundVariableKind,
269 rustc_middle::ty::DeducedParamAttrs,
270 rustc_middle::ty::Destructor,
271 rustc_middle::ty::fast_reject::SimplifiedType,
272 rustc_middle::ty::ImplPolarity,
273 rustc_middle::ty::Representability,
274 rustc_middle::ty::ReprOptions,
275 rustc_middle::ty::UnusedGenericParams,
276 rustc_middle::ty::util::AlwaysRequiresDrop,
277 rustc_middle::ty::Visibility<rustc_span::def_id::DefId>,
278 rustc_session::config::CrateType,
279 rustc_session::config::EntryFnType,
280 rustc_session::config::OptLevel,
281 rustc_session::config::SymbolManglingVersion,
282 rustc_session::cstore::CrateDepKind,
283 rustc_session::cstore::ExternCrate,
284 rustc_session::cstore::LinkagePreference,
285 rustc_session::Limits,
286 rustc_session::lint::LintExpectationId,
287 rustc_span::def_id::CrateNum,
288 rustc_span::def_id::DefPathHash,
289 rustc_span::ExpnHash,
290 rustc_span::ExpnId,
291 rustc_span::Span,
292 rustc_span::Symbol,
293 rustc_span::symbol::Ident,
294 rustc_target::spec::PanicStrategy,
295 rustc_type_ir::Variance,
296 u32,
297 usize,
298}
299
300macro_rules! tcx_lifetime {
301 ($($($fake_path:ident)::+),+ $(,)?) => {
302 $(
303 impl<'tcx> EraseType for $($fake_path)::+<'tcx> {
304 type Result = [u8; size_of::<$($fake_path)::+<'static>>()];
305 }
306 )*
307 }
308}
309
310tcx_lifetime! {
311 rustc_middle::hir::Owner,
312 rustc_middle::middle::exported_symbols::ExportedSymbol,
313 rustc_middle::mir::ConstantKind,
314 rustc_middle::mir::DestructuredConstant,
315 rustc_middle::mir::interpret::ConstAlloc,
316 rustc_middle::mir::interpret::ConstValue,
317 rustc_middle::mir::interpret::GlobalId,
318 rustc_middle::mir::interpret::LitToConstInput,
353b0b11
FG
319 rustc_middle::traits::query::MethodAutoderefStepsResult,
320 rustc_middle::traits::query::type_op::AscribeUserType,
321 rustc_middle::traits::query::type_op::Eq,
322 rustc_middle::traits::query::type_op::ProvePredicate,
323 rustc_middle::traits::query::type_op::Subtype,
324 rustc_middle::ty::AdtDef,
325 rustc_middle::ty::AliasTy,
fe692bf9 326 rustc_middle::ty::ClauseKind,
353b0b11
FG
327 rustc_middle::ty::ClosureTypeInfo,
328 rustc_middle::ty::Const,
329 rustc_middle::ty::DestructuredConst,
330 rustc_middle::ty::ExistentialTraitRef,
331 rustc_middle::ty::FnSig,
332 rustc_middle::ty::GenericArg,
333 rustc_middle::ty::GenericPredicates,
334 rustc_middle::ty::inhabitedness::InhabitedPredicate,
335 rustc_middle::ty::Instance,
336 rustc_middle::ty::InstanceDef,
337 rustc_middle::ty::layout::FnAbiError,
338 rustc_middle::ty::layout::LayoutError,
339 rustc_middle::ty::ParamEnv,
340 rustc_middle::ty::Predicate,
341 rustc_middle::ty::SymbolName,
342 rustc_middle::ty::TraitRef,
343 rustc_middle::ty::Ty,
344 rustc_middle::ty::UnevaluatedConst,
345 rustc_middle::ty::ValTree,
346 rustc_middle::ty::VtblEntry,
347}