From 631cd5845e8de329d0e227aaa707d7ea228b8f8f Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:20:29 +0200 Subject: Merging upstream version 1.70.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_middle/src/query/erase.rs | 336 +++++++++++++++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 compiler/rustc_middle/src/query/erase.rs (limited to 'compiler/rustc_middle/src/query/erase.rs') diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs new file mode 100644 index 000000000..7d9aea022 --- /dev/null +++ b/compiler/rustc_middle/src/query/erase.rs @@ -0,0 +1,336 @@ +use crate::mir; +use crate::traits; +use crate::ty::{self, Ty}; +use std::mem::{size_of, transmute_copy, MaybeUninit}; + +#[derive(Copy, Clone)] +pub struct Erased { + // We use `MaybeUninit` here so we can store any value + // in `data` since we aren't actually storing a `T`. + data: MaybeUninit, +} + +pub trait EraseType: Copy { + type Result: Copy; +} + +// Allow `type_alias_bounds` since compilation will fail without `EraseType`. +#[allow(type_alias_bounds)] +pub type Erase = Erased; + +#[inline(always)] +pub fn erase(src: T) -> Erase { + // Ensure the sizes match + const { + if std::mem::size_of::() != std::mem::size_of::() { + panic!("size of T must match erased type T::Result") + } + }; + + Erased::<::Result> { + // SAFETY: Is it safe to transmute to MaybeUninit for types with the same sizes. + data: unsafe { transmute_copy(&src) }, + } +} + +/// Restores an erased value. +#[inline(always)] +pub fn restore(value: Erase) -> T { + let value: Erased<::Result> = value; + // SAFETY: Due to the use of impl Trait in `Erase` the only way to safely create an instance + // of `Erase` is to call `erase`, so we know that `value.data` is a valid instance of `T` of + // the right size. + unsafe { transmute_copy(&value.data) } +} + +impl EraseType for &'_ T { + type Result = [u8; size_of::<*const ()>()]; +} + +impl EraseType for &'_ [T] { + type Result = [u8; size_of::<*const [()]>()]; +} + +impl EraseType for &'_ ty::List { + type Result = [u8; size_of::<*const ()>()]; +} + +impl EraseType for Result<&'_ T, traits::query::NoSolution> { + type Result = [u8; size_of::>()]; +} + +impl EraseType for Result<&'_ T, rustc_errors::ErrorGuaranteed> { + type Result = [u8; size_of::>()]; +} + +impl EraseType for Result<&'_ T, traits::CodegenObligationError> { + type Result = [u8; size_of::>()]; +} + +impl EraseType for Result<&'_ T, ty::layout::FnAbiError<'_>> { + type Result = [u8; size_of::>>()]; +} + +impl EraseType for Result<(&'_ T, rustc_middle::thir::ExprId), rustc_errors::ErrorGuaranteed> { + type Result = [u8; size_of::< + Result<(&'static (), rustc_middle::thir::ExprId), rustc_errors::ErrorGuaranteed>, + >()]; +} + +impl EraseType for Result>, rustc_errors::ErrorGuaranteed> { + type Result = + [u8; size_of::>, rustc_errors::ErrorGuaranteed>>()]; +} + +impl EraseType for Result>, rustc_errors::ErrorGuaranteed> { + type Result = + [u8; size_of::>, rustc_errors::ErrorGuaranteed>>()]; +} + +impl EraseType for Result, traits::query::NoSolution> { + type Result = [u8; size_of::, traits::query::NoSolution>>()]; +} + +impl EraseType for Result> { + type Result = [u8; size_of::>>()]; +} + +impl EraseType for Result>, ty::layout::LayoutError<'_>> { + type Result = [u8; size_of::< + Result< + rustc_target::abi::TyAndLayout<'static, Ty<'static>>, + ty::layout::LayoutError<'static>, + >, + >()]; +} + +impl EraseType for Result, mir::interpret::LitToConstError> { + type Result = [u8; size_of::, mir::interpret::LitToConstError>>()]; +} + +impl EraseType for Result, mir::interpret::LitToConstError> { + type Result = + [u8; size_of::, mir::interpret::LitToConstError>>()]; +} + +impl EraseType for Result, mir::interpret::ErrorHandled> { + type Result = [u8; size_of::< + Result, mir::interpret::ErrorHandled>, + >()]; +} + +impl EraseType for Result, mir::interpret::ErrorHandled> { + type Result = [u8; size_of::< + Result, mir::interpret::ErrorHandled>, + >()]; +} + +impl EraseType for Result>, mir::interpret::ErrorHandled> { + type Result = + [u8; size_of::>, mir::interpret::ErrorHandled>>()]; +} + +impl EraseType for Result<&'_ ty::List>, ty::util::AlwaysRequiresDrop> { + type Result = + [u8; size_of::>, ty::util::AlwaysRequiresDrop>>()]; +} + +impl EraseType for Option<&'_ T> { + type Result = [u8; size_of::>()]; +} + +impl EraseType for Option<&'_ [T]> { + type Result = [u8; size_of::>()]; +} + +impl EraseType for Option> { + type Result = [u8; size_of::>>()]; +} + +impl EraseType for Option> { + type Result = [u8; size_of::>>()]; +} + +impl EraseType for Option>> { + type Result = [u8; size_of::>>>()]; +} + +impl EraseType for Option>> { + type Result = [u8; size_of::>>>()]; +} + +impl EraseType for rustc_hir::MaybeOwner<&'_ T> { + type Result = [u8; size_of::>()]; +} + +impl EraseType for ty::EarlyBinder { + type Result = T::Result; +} + +impl EraseType for ty::Binder<'_, ty::FnSig<'_>> { + type Result = [u8; size_of::>>()]; +} + +impl EraseType for (&'_ T0, &'_ T1) { + type Result = [u8; size_of::<(&'static (), &'static ())>()]; +} + +impl EraseType for (&'_ T0, &'_ [T1]) { + type Result = [u8; size_of::<(&'static (), &'static [()])>()]; +} + +macro_rules! trivial { + ($($ty:ty),+ $(,)?) => { + $( + impl EraseType for $ty { + type Result = [u8; size_of::<$ty>()]; + } + )* + } +} + +trivial! { + (), + bool, + Option<(rustc_span::def_id::DefId, rustc_session::config::EntryFnType)>, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + Option, + Result<(), rustc_errors::ErrorGuaranteed>, + Result<(), rustc_middle::traits::query::NoSolution>, + Result, + rustc_ast::expand::allocator::AllocatorKind, + rustc_attr::ConstStability, + rustc_attr::DefaultBodyStability, + rustc_attr::Deprecation, + rustc_attr::Stability, + rustc_data_structures::svh::Svh, + rustc_errors::ErrorGuaranteed, + rustc_hir::Constness, + rustc_hir::def_id::DefId, + rustc_hir::def_id::DefIndex, + rustc_hir::def_id::LocalDefId, + rustc_hir::def::DefKind, + rustc_hir::Defaultness, + rustc_hir::definitions::DefKey, + rustc_hir::GeneratorKind, + rustc_hir::HirId, + rustc_hir::IsAsync, + rustc_hir::ItemLocalId, + rustc_hir::LangItem, + rustc_hir::OwnerId, + rustc_hir::Upvar, + rustc_index::bit_set::FiniteBitSet, + rustc_middle::middle::dependency_format::Linkage, + rustc_middle::middle::exported_symbols::SymbolExportInfo, + rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault, + rustc_middle::middle::resolve_bound_vars::ResolvedArg, + rustc_middle::middle::stability::DeprecationEntry, + rustc_middle::mir::ConstQualifs, + rustc_middle::mir::interpret::AllocId, + rustc_middle::mir::interpret::ErrorHandled, + rustc_middle::mir::interpret::LitToConstError, + rustc_middle::thir::ExprId, + rustc_middle::traits::CodegenObligationError, + rustc_middle::traits::EvaluationResult, + rustc_middle::traits::OverflowError, + rustc_middle::traits::query::NoSolution, + rustc_middle::traits::WellFormedLoc, + rustc_middle::ty::adjustment::CoerceUnsizedInfo, + rustc_middle::ty::AssocItem, + rustc_middle::ty::AssocItemContainer, + rustc_middle::ty::BoundVariableKind, + rustc_middle::ty::DeducedParamAttrs, + rustc_middle::ty::Destructor, + rustc_middle::ty::fast_reject::SimplifiedType, + rustc_middle::ty::ImplPolarity, + rustc_middle::ty::Representability, + rustc_middle::ty::ReprOptions, + rustc_middle::ty::UnusedGenericParams, + rustc_middle::ty::util::AlwaysRequiresDrop, + rustc_middle::ty::Visibility, + rustc_session::config::CrateType, + rustc_session::config::EntryFnType, + rustc_session::config::OptLevel, + rustc_session::config::SymbolManglingVersion, + rustc_session::cstore::CrateDepKind, + rustc_session::cstore::ExternCrate, + rustc_session::cstore::LinkagePreference, + rustc_session::Limits, + rustc_session::lint::LintExpectationId, + rustc_span::def_id::CrateNum, + rustc_span::def_id::DefPathHash, + rustc_span::ExpnHash, + rustc_span::ExpnId, + rustc_span::Span, + rustc_span::Symbol, + rustc_span::symbol::Ident, + rustc_target::spec::PanicStrategy, + rustc_type_ir::Variance, + u32, + usize, +} + +macro_rules! tcx_lifetime { + ($($($fake_path:ident)::+),+ $(,)?) => { + $( + impl<'tcx> EraseType for $($fake_path)::+<'tcx> { + type Result = [u8; size_of::<$($fake_path)::+<'static>>()]; + } + )* + } +} + +tcx_lifetime! { + rustc_middle::hir::Owner, + rustc_middle::middle::exported_symbols::ExportedSymbol, + rustc_middle::mir::ConstantKind, + rustc_middle::mir::DestructuredConstant, + rustc_middle::mir::interpret::ConstAlloc, + rustc_middle::mir::interpret::ConstValue, + rustc_middle::mir::interpret::GlobalId, + rustc_middle::mir::interpret::LitToConstInput, + rustc_middle::traits::ChalkEnvironmentAndGoal, + rustc_middle::traits::query::MethodAutoderefStepsResult, + rustc_middle::traits::query::type_op::AscribeUserType, + rustc_middle::traits::query::type_op::Eq, + rustc_middle::traits::query::type_op::ProvePredicate, + rustc_middle::traits::query::type_op::Subtype, + rustc_middle::ty::AdtDef, + rustc_middle::ty::AliasTy, + rustc_middle::ty::Clause, + rustc_middle::ty::ClosureTypeInfo, + rustc_middle::ty::Const, + rustc_middle::ty::DestructuredConst, + rustc_middle::ty::ExistentialTraitRef, + rustc_middle::ty::FnSig, + rustc_middle::ty::GenericArg, + rustc_middle::ty::GenericPredicates, + rustc_middle::ty::inhabitedness::InhabitedPredicate, + rustc_middle::ty::Instance, + rustc_middle::ty::InstanceDef, + rustc_middle::ty::layout::FnAbiError, + rustc_middle::ty::layout::LayoutError, + rustc_middle::ty::ParamEnv, + rustc_middle::ty::Predicate, + rustc_middle::ty::SymbolName, + rustc_middle::ty::TraitRef, + rustc_middle::ty::Ty, + rustc_middle::ty::UnevaluatedConst, + rustc_middle::ty::ValTree, + rustc_middle::ty::VtblEntry, +} -- cgit v1.2.3