]>
Commit | Line | Data |
---|---|---|
353b0b11 FG |
1 | use crate::mir; |
2 | use crate::traits; | |
3 | use crate::ty::{self, Ty}; | |
4 | use std::mem::{size_of, transmute_copy, MaybeUninit}; | |
5 | ||
6 | #[derive(Copy, Clone)] | |
7 | pub 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 | ||
13 | pub 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)] | |
19 | pub type Erase<T: EraseType> = Erased<impl Copy>; | |
20 | ||
21 | #[inline(always)] | |
22 | pub 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)] | |
38 | pub 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 | ||
46 | impl<T> EraseType for &'_ T { | |
47 | type Result = [u8; size_of::<*const ()>()]; | |
48 | } | |
49 | ||
50 | impl<T> EraseType for &'_ [T] { | |
51 | type Result = [u8; size_of::<*const [()]>()]; | |
52 | } | |
53 | ||
54 | impl<T> EraseType for &'_ ty::List<T> { | |
55 | type Result = [u8; size_of::<*const ()>()]; | |
56 | } | |
57 | ||
fe692bf9 FG |
58 | impl<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 |
62 | impl<T> EraseType for Result<&'_ T, traits::query::NoSolution> { |
63 | type Result = [u8; size_of::<Result<&'static (), traits::query::NoSolution>>()]; | |
64 | } | |
65 | ||
66 | impl<T> EraseType for Result<&'_ T, rustc_errors::ErrorGuaranteed> { | |
67 | type Result = [u8; size_of::<Result<&'static (), rustc_errors::ErrorGuaranteed>>()]; | |
68 | } | |
69 | ||
70 | impl<T> EraseType for Result<&'_ T, traits::CodegenObligationError> { | |
71 | type Result = [u8; size_of::<Result<&'static (), traits::CodegenObligationError>>()]; | |
72 | } | |
73 | ||
fe692bf9 FG |
74 | impl<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 | ||
78 | impl<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 | ||
84 | impl 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 |
89 | impl 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 | ||
95 | impl 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 |
99 | impl 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 |
103 | impl 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 | ||
114 | impl EraseType for Result<ty::Const<'_>, mir::interpret::LitToConstError> { | |
115 | type Result = [u8; size_of::<Result<ty::Const<'static>, mir::interpret::LitToConstError>>()]; | |
116 | } | |
117 | ||
118 | impl EraseType for Result<mir::ConstantKind<'_>, mir::interpret::LitToConstError> { | |
119 | type Result = | |
120 | [u8; size_of::<Result<mir::ConstantKind<'static>, mir::interpret::LitToConstError>>()]; | |
121 | } | |
122 | ||
123 | impl 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 | ||
129 | impl 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 | ||
135 | impl 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 | ||
140 | impl 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 | ||
145 | impl<T> EraseType for Option<&'_ T> { | |
146 | type Result = [u8; size_of::<Option<&'static ()>>()]; | |
147 | } | |
148 | ||
149 | impl<T> EraseType for Option<&'_ [T]> { | |
150 | type Result = [u8; size_of::<Option<&'static [()]>>()]; | |
151 | } | |
152 | ||
153 | impl EraseType for Option<rustc_middle::hir::Owner<'_>> { | |
154 | type Result = [u8; size_of::<Option<rustc_middle::hir::Owner<'static>>>()]; | |
155 | } | |
156 | ||
157 | impl EraseType for Option<mir::DestructuredConstant<'_>> { | |
158 | type Result = [u8; size_of::<Option<mir::DestructuredConstant<'static>>>()]; | |
159 | } | |
160 | ||
161 | impl EraseType for Option<ty::EarlyBinder<ty::TraitRef<'_>>> { | |
162 | type Result = [u8; size_of::<Option<ty::EarlyBinder<ty::TraitRef<'static>>>>()]; | |
163 | } | |
164 | ||
165 | impl EraseType for Option<ty::EarlyBinder<Ty<'_>>> { | |
166 | type Result = [u8; size_of::<Option<ty::EarlyBinder<Ty<'static>>>>()]; | |
167 | } | |
168 | ||
169 | impl<T> EraseType for rustc_hir::MaybeOwner<&'_ T> { | |
170 | type Result = [u8; size_of::<rustc_hir::MaybeOwner<&'static ()>>()]; | |
171 | } | |
172 | ||
173 | impl<T: EraseType> EraseType for ty::EarlyBinder<T> { | |
174 | type Result = T::Result; | |
175 | } | |
176 | ||
177 | impl EraseType for ty::Binder<'_, ty::FnSig<'_>> { | |
178 | type Result = [u8; size_of::<ty::Binder<'static, ty::FnSig<'static>>>()]; | |
179 | } | |
180 | ||
49aad941 FG |
181 | impl 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 |
185 | impl<T0, T1> EraseType for (&'_ T0, &'_ T1) { |
186 | type Result = [u8; size_of::<(&'static (), &'static ())>()]; | |
187 | } | |
188 | ||
189 | impl<T0, T1> EraseType for (&'_ T0, &'_ [T1]) { | |
190 | type Result = [u8; size_of::<(&'static (), &'static [()])>()]; | |
191 | } | |
192 | ||
193 | macro_rules! trivial { | |
194 | ($($ty:ty),+ $(,)?) => { | |
195 | $( | |
196 | impl EraseType for $ty { | |
197 | type Result = [u8; size_of::<$ty>()]; | |
198 | } | |
199 | )* | |
200 | } | |
201 | } | |
202 | ||
203 | trivial! { | |
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 | ||
300 | macro_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 | ||
310 | tcx_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 | } |