Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 133 additions & 95 deletions compiler/rustc_middle/src/query/erase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,44 @@ use std::ffi::OsStr;
use std::intrinsics::transmute_unchecked;
use std::marker::PhantomData;
use std::mem::MaybeUninit;
use std::sync::Arc;

use rustc_abi::Align;
use rustc_ast as ast;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_ast::tokenstream::TokenStream;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::steal::Steal;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_span::{ErrorGuaranteed, Spanned};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefIdMap;
use rustc_index::IndexVec;
use rustc_middle::traits::solve::QueryResult;
use rustc_middle::traits::solve::inspect::Probe;
use rustc_session::Limits;
use rustc_session::config::{EntryFnType, OptLevel, SymbolManglingVersion};
use rustc_session::cstore::CrateDepKind;
use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
use rustc_span::{ErrorGuaranteed, ExpnId, Span, Spanned, Symbol};
use rustc_target::callconv::FnAbi;
use rustc_target::spec::PanicStrategy;

use crate::infer::canonical::{Canonical, QueryResponse};
use crate::middle::codegen_fn_attrs::SanitizerFnAttrs;
use crate::middle::resolve_bound_vars::ObjectLifetimeDefault;
use crate::middle::stability::DeprecationEntry;
use crate::mir::mono::{MonoItem, NormalizationErrorInMono};
use crate::traits::query::{
DropckOutlivesResult, MethodAutoderefStepsResult, NoSolution, NormalizationResult,
OutlivesBound,
};
use crate::traits::{
CodegenObligationError, EvaluationResult, ImplSource, OverflowError, specialization_graph,
};
use crate::ty::{self, Ty, TyCtxt};
use crate::{mir, thir, traits};
use crate::{mir, thir};

unsafe extern "C" {
type NoAutoTraits;
Expand All @@ -42,6 +71,11 @@ unsafe impl<Storage: Copy> DynSend for ErasedData<Storage> {}
///
/// Erasing and unerasing values is performed by [`erase_val`] and [`restore_val`].
///
/// Most impls are done via the `impl_erasable_for_types_with_no_type_params!`
/// macro. A small number of hand-written generic impls are used for common
/// types like `&T` and `Option<&T>`; these generic impls avoid many concrete
/// entries being needed in the macro.
///
/// FIXME: This whole trait could potentially be replaced by `T: Copy` and the
/// storage type `[u8; size_of::<T>()]` when support for that is more mature.
pub trait Erasable: Copy {
Expand Down Expand Up @@ -117,36 +151,10 @@ impl<T> Erasable for &'_ [T] {
type Storage = [u8; size_of::<&'_ [()]>()];
}

// Note: this impl does not overlap with the impl for `&'_ T` above because `RawList` is unsized
// and does not satisfy the implicit `T: Sized` bound.
//
// Furthermore, even if that implicit bound was removed (by adding `T: ?Sized`) this impl still
// wouldn't overlap because `?Sized` is equivalent to `MetaSized` and `RawList` does not satisfy
// `MetaSized` because it contains an extern type.
impl<H, T> Erasable for &'_ ty::RawList<H, T> {
type Storage = [u8; size_of::<&'_ ty::RawList<(), ()>>()];
}

impl<T> Erasable for Result<&'_ T, traits::query::NoSolution> {
type Storage = [u8; size_of::<Result<&'_ (), traits::query::NoSolution>>()];
}

impl<T> Erasable for Result<&'_ T, ErrorGuaranteed> {
type Storage = [u8; size_of::<Result<&'_ (), ErrorGuaranteed>>()];
}

impl<T> Erasable for Option<&'_ T> {
type Storage = [u8; size_of::<Option<&'_ ()>>()];
}

impl<T: Erasable> Erasable for ty::EarlyBinder<'_, T> {
type Storage = T::Storage;
}

impl<T0, T1> Erasable for (&'_ T0, &'_ T1) {
type Storage = [u8; size_of::<(&'_ (), &'_ ())>()];
}

macro_rules! impl_erasable_for_types_with_no_type_params {
($($ty:ty),+ $(,)?) => {
$(
Expand All @@ -161,92 +169,122 @@ macro_rules! impl_erasable_for_types_with_no_type_params {
// `[u8; size_of::<Foo>()]`. ('_ lifetimes are allowed.)
impl_erasable_for_types_with_no_type_params! {
// tidy-alphabetical-start
// Note: these `List` impls do not overlap with the impl for `&'_ T` above because `List` is
// unsized and does not satisfy the implicit `T: Sized` bound.
//
// Furthermore, even if that implicit bound was removed (by adding `T: ?Sized`) these impls
// still wouldn't overlap because `?Sized` is equivalent to `MetaSized` and `RawList` does not
// satisfy `MetaSized` because it contains an extern type.
&'_ ty::List<DefId>,
&'_ ty::List<LocalDefId>,
&'_ ty::List<Ty<'_>>,
&'_ ty::ListWithCachedTypeInfo<ty::Clause<'_>>,
(&'_ Steal<(ty::ResolverAstLowering<'_>, Arc<ast::Crate>)>, &'_ ty::ResolverGlobalCtxt),
(&'_ Steal<mir::Body<'_>>, &'_ Steal<IndexVec<mir::Promoted, mir::Body<'_>>>),
(&'_ ty::CrateInherentImpls, Result<(), ErrorGuaranteed>),
(),
(traits::solve::QueryResult<'_>, &'_ traits::solve::inspect::Probe<TyCtxt<'_>>),
(QueryResult<'_>, &'_ Probe<TyCtxt<'_>>),
CrateDepKind,
DefId,
DefKind,
ExpnId,
Limits,
MethodAutoderefStepsResult<'_>,
ObjectLifetimeDefault,
OptLevel,
Option<&'_ OsStr>,
Option<&'_ [rustc_hir::PreciseCapturingArgKind<rustc_span::Symbol, rustc_span::Symbol>]>,
Option<&'_ [hir::PreciseCapturingArgKind<Symbol, Symbol>]>,
Option<(DefId, EntryFnType)>,
Option<(mir::ConstValue, Ty<'_>)>,
Option<(rustc_span::def_id::DefId, rustc_session::config::EntryFnType)>,
Option<rustc_abi::Align>,
Option<rustc_ast::expand::allocator::AllocatorKind>,
Option<rustc_data_structures::svh::Svh>,
Option<rustc_hir::ConstStability>,
Option<rustc_hir::CoroutineKind>,
Option<rustc_hir::DefaultBodyStability>,
Option<rustc_hir::Stability>,
Option<rustc_middle::middle::stability::DeprecationEntry>,
Option<rustc_middle::ty::AsyncDestructor>,
Option<rustc_middle::ty::Destructor>,
Option<rustc_middle::ty::IntrinsicDef>,
Option<rustc_middle::ty::ScalarInt>,
Option<rustc_span::Span>,
Option<rustc_span::def_id::CrateNum>,
Option<rustc_span::def_id::DefId>,
Option<rustc_span::def_id::LocalDefId>,
Option<rustc_target::spec::PanicStrategy>,
Option<Align>,
Option<AllocatorKind>,
Option<CrateNum>,
Option<DefId>,
Option<DeprecationEntry>,
Option<LocalDefId>,
Option<PanicStrategy>,
Option<Span>,
Option<Svh>,
Option<hir::ConstStability>,
Option<hir::CoroutineKind>,
Option<hir::DefaultBodyStability>,
Option<hir::Stability>,
Option<ty::AsyncDestructor>,
Option<ty::Destructor>,
Option<ty::EarlyBinder<'_, Ty<'_>>>,
Option<ty::IntrinsicDef>,
Option<ty::ScalarInt>,
Option<ty::Value<'_>>,
Option<usize>,
PanicStrategy,
Result<&'_ Canonical<'_, QueryResponse<'_, ()>>, NoSolution>,
Result<&'_ Canonical<'_, QueryResponse<'_, DropckOutlivesResult<'_>>>, NoSolution>,
Result<&'_ Canonical<'_, QueryResponse<'_, NormalizationResult<'_>>>, NoSolution>,
Result<&'_ Canonical<'_, QueryResponse<'_, Ty<'_>>>, NoSolution>,
Result<&'_ Canonical<'_, QueryResponse<'_, Vec<OutlivesBound<'_>>>>, NoSolution>,
Result<&'_ Canonical<'_, QueryResponse<'_, ty::Clause<'_>>>, NoSolution>,
Result<&'_ Canonical<'_, QueryResponse<'_, ty::FnSig<'_>>>, NoSolution>,
Result<&'_ Canonical<'_, QueryResponse<'_, ty::PolyFnSig<'_>>>, NoSolution>,
Result<&'_ DefIdMap<ty::EarlyBinder<'_, Ty<'_>>>, ErrorGuaranteed>,
Result<&'_ FnAbi<'_, Ty<'_>>, &'_ ty::layout::FnAbiError<'_>>,
Result<&'_ FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'_>>, ErrorGuaranteed>,
Result<&'_ ImplSource<'_, ()>, CodegenObligationError>,
Result<&'_ TokenStream, ()>,
Result<&'_ rustc_target::callconv::FnAbi<'_, Ty<'_>>, &'_ ty::layout::FnAbiError<'_>>,
Result<&'_ traits::ImplSource<'_, ()>, traits::CodegenObligationError>,
Result<&'_ specialization_graph::Graph, ErrorGuaranteed>,
Result<&'_ ty::List<Ty<'_>>, ty::util::AlwaysRequiresDrop>,
Result<(&'_ Steal<thir::Thir<'_>>, thir::ExprId), ErrorGuaranteed>,
Result<(&'_ [Spanned<MonoItem<'_>>], &'_ [Spanned<MonoItem<'_>>]), NormalizationErrorInMono>,
Result<(), ErrorGuaranteed>,
Result<EvaluationResult, OverflowError>,
Result<Option<ty::EarlyBinder<'_, ty::Const<'_>>>, ErrorGuaranteed>,
Result<Option<ty::Instance<'_>>, ErrorGuaranteed>,
Result<bool, &ty::layout::LayoutError<'_>>,
Result<mir::ConstAlloc<'_>, mir::interpret::ErrorHandled>,
Result<mir::ConstValue, mir::interpret::ErrorHandled>,
Result<rustc_abi::TyAndLayout<'_, Ty<'_>>, &ty::layout::LayoutError<'_>>,
Result<rustc_middle::traits::EvaluationResult, rustc_middle::traits::OverflowError>,
Result<rustc_middle::ty::adjustment::CoerceUnsizedInfo, ErrorGuaranteed>,
Result<ty::GenericArg<'_>, traits::query::NoSolution>,
Result<ty::GenericArg<'_>, NoSolution>,
Result<ty::adjustment::CoerceUnsizedInfo, ErrorGuaranteed>,
Result<ty::layout::TyAndLayout<'_>, &ty::layout::LayoutError<'_>>,
SanitizerFnAttrs,
Span,
Svh,
Symbol,
SymbolManglingVersion,
Ty<'_>,
bool,
rustc_data_structures::svh::Svh,
rustc_hir::Constness,
rustc_hir::Defaultness,
rustc_hir::HirId,
rustc_hir::MaybeOwner<'_>,
rustc_hir::OpaqueTyOrigin<rustc_hir::def_id::DefId>,
rustc_hir::def::DefKind,
rustc_hir::def_id::DefId,
rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs,
rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault,
rustc_middle::mir::ConstQualifs,
rustc_middle::mir::ConstValue,
rustc_middle::mir::interpret::AllocId,
rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'_>,
rustc_middle::mir::interpret::EvalToValTreeResult<'_>,
rustc_middle::mir::mono::MonoItemPartitions<'_>,
rustc_middle::traits::query::MethodAutoderefStepsResult<'_>,
rustc_middle::ty::AdtDef<'_>,
rustc_middle::ty::AnonConstKind,
rustc_middle::ty::AssocItem,
rustc_middle::ty::Asyncness,
rustc_middle::ty::Binder<'_, ty::CoroutineWitnessTypes<TyCtxt<'_>>>,
rustc_middle::ty::Binder<'_, ty::FnSig<'_>>,
rustc_middle::ty::ClosureTypeInfo<'_>,
rustc_middle::ty::Const<'_>,
rustc_middle::ty::ConstConditions<'_>,
rustc_middle::ty::GenericPredicates<'_>,
rustc_middle::ty::ImplTraitHeader<'_>,
rustc_middle::ty::ParamEnv<'_>,
rustc_middle::ty::SymbolName<'_>,
rustc_middle::ty::TypingEnv<'_>,
rustc_middle::ty::Visibility<rustc_span::def_id::DefId>,
rustc_middle::ty::inhabitedness::InhabitedPredicate<'_>,
rustc_session::Limits,
rustc_session::config::OptLevel,
rustc_session::config::SymbolManglingVersion,
rustc_session::cstore::CrateDepKind,
rustc_span::ExpnId,
rustc_span::Span,
rustc_span::Symbol,
rustc_target::spec::PanicStrategy,
hir::Constness,
hir::Defaultness,
hir::HirId,
hir::MaybeOwner<'_>,
hir::OpaqueTyOrigin<DefId>,
mir::ConstQualifs,
mir::ConstValue,
mir::interpret::AllocId,
mir::interpret::EvalStaticInitializerRawResult<'_>,
mir::interpret::EvalToValTreeResult<'_>,
mir::mono::MonoItemPartitions<'_>,
ty::AdtDef<'_>,
ty::AnonConstKind,
ty::AssocItem,
ty::Asyncness,
ty::Binder<'_, ty::CoroutineWitnessTypes<TyCtxt<'_>>>,
ty::Binder<'_, ty::FnSig<'_>>,
ty::ClosureTypeInfo<'_>,
ty::Const<'_>,
ty::ConstConditions<'_>,
ty::EarlyBinder<'_, &'_ [(ty::Clause<'_>, Span)]>,
ty::EarlyBinder<'_, &'_ [(ty::PolyTraitRef<'_>, Span)]>,
ty::EarlyBinder<'_, Ty<'_>>,
ty::EarlyBinder<'_, ty::Binder<'_, ty::CoroutineWitnessTypes<TyCtxt<'_>>>>,
ty::EarlyBinder<'_, ty::Clauses<'_>>,
ty::EarlyBinder<'_, ty::Const<'_>>,
ty::EarlyBinder<'_, ty::PolyFnSig<'_>>,
ty::GenericPredicates<'_>,
ty::ImplTraitHeader<'_>,
ty::ParamEnv<'_>,
ty::SymbolName<'_>,
ty::TypingEnv<'_>,
ty::Visibility<DefId>,
ty::inhabitedness::InhabitedPredicate<'_>,
usize,
// tidy-alphabetical-end
}
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ pub use self::context::{
};
pub use self::fold::*;
pub use self::instance::{Instance, InstanceKind, ReifyReason};
pub(crate) use self::list::RawList;
pub use self::list::{List, ListWithCachedTypeInfo};
pub use self::opaque_types::OpaqueTypeKey;
pub use self::pattern::{Pattern, PatternKind};
Expand Down
Loading