diff options
| author | Moulins <arthur.heuillard@orange.fr> | 2023-06-19 15:29:31 +0200 |
|---|---|---|
| committer | Moulins <arthur.heuillard@orange.fr> | 2023-07-21 03:31:45 +0200 |
| commit | cb8b1d1bc98bf4a8af38bfc751fa150af4571c10 (patch) | |
| tree | 390b0e517b0f4c82a80966bab749ba70d756ef0d /compiler/rustc_middle/src | |
| parent | e2a7ba2771a70439cd546fdae676abe11dacf6f9 (diff) | |
| download | rust-cb8b1d1bc98bf4a8af38bfc751fa150af4571c10.tar.gz rust-cb8b1d1bc98bf4a8af38bfc751fa150af4571c10.zip | |
add `naive_layout_of` query
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/query/erase.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/query/mod.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs | 67 |
3 files changed, 83 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 2c481745d98..a0cb23b5a4c 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -111,6 +111,11 @@ impl EraseType >()]; } +impl EraseType for Result<ty::layout::TyAndNaiveLayout<'_>, &ty::layout::LayoutError<'_>> { + type Result = + [u8; size_of::<Result<ty::layout::TyAndNaiveLayout<'_>, &ty::layout::LayoutError<'_>>>()]; +} + impl EraseType for Result<ty::Const<'_>, mir::interpret::LitToConstError> { type Result = [u8; size_of::<Result<ty::Const<'static>, mir::interpret::LitToConstError>>()]; } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b36f0df78f1..c728cc0b39f 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1394,6 +1394,17 @@ rustc_queries! { desc { "computing layout of `{}`", key.value } } + /// Computes the naive layout estimate of a type. Note that this implicitly + /// executes in "reveal all" mode, and will normalize the input type. + /// + /// Unlike `layout_of`, this doesn't recurse behind reference types. + query naive_layout_of( + key: ty::ParamEnvAnd<'tcx, Ty<'tcx>> + ) -> Result<ty::layout::TyAndNaiveLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> { + depth_limit + desc { "computing layout (naive) of `{}`", key.value } + } + /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers. /// /// NB: this doesn't handle virtual calls - those should use `fn_abi_of_instance` diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 62805d1e8b5..31005bdd64a 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -621,6 +621,61 @@ impl<T, E> MaybeResult<T> for Result<T, E> { pub type TyAndLayout<'tcx> = rustc_target::abi::TyAndLayout<'tcx, Ty<'tcx>>; +#[derive(Copy, Clone, Debug, HashStable)] +pub struct TyAndNaiveLayout<'tcx> { + pub ty: Ty<'tcx>, + pub layout: NaiveLayout, +} + +impl std::ops::Deref for TyAndNaiveLayout<'_> { + type Target = NaiveLayout; + fn deref(&self) -> &Self::Target { + &self.layout + } +} + +impl std::ops::DerefMut for TyAndNaiveLayout<'_> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.layout + } +} + +/// A naive underestimation of the layout of a type. +#[derive(Copy, Clone, Debug, HashStable)] +pub struct NaiveLayout { + pub min_size: Size, + pub min_align: Align, +} + +impl NaiveLayout { + pub const EMPTY: Self = Self { min_size: Size::ZERO, min_align: Align::ONE }; + + pub fn is_underestimate_of(&self, layout: Layout<'_>) -> bool { + self.min_size <= layout.size() && self.min_align <= layout.align().abi + } + + #[must_use] + pub fn pad_to_align(self) -> Self { + Self { min_size: self.min_size.align_to(self.min_align), min_align: self.min_align } + } + + #[must_use] + pub fn concat<C: HasDataLayout>(&self, other: &Self, cx: &C) -> Option<Self> { + Some(Self { + min_size: self.min_size.checked_add(other.min_size, cx)?, + min_align: std::cmp::max(self.min_align, other.min_align), + }) + } + + #[must_use] + pub fn union(&self, other: &Self) -> Self { + Self { + min_size: std::cmp::max(self.min_size, other.min_size), + min_align: std::cmp::max(self.min_align, other.min_align), + } + } +} + /// Trait for contexts that want to be able to compute layouts of types. /// This automatically gives access to `LayoutOf`, through a blanket `impl`. pub trait LayoutOfHelpers<'tcx>: HasDataLayout + HasTyCtxt<'tcx> + HasParamEnv<'tcx> { @@ -673,6 +728,18 @@ pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> { .map_err(|err| self.handle_layout_err(*err, span, ty)), ) } + + /// Computes the naive layout estimate of a type. Note that this implicitly + /// executes in "reveal all" mode, and will normalize the input type. + /// + /// Unlike `layout_of`, this doesn't recurse behind reference types. + #[inline] + fn naive_layout_of( + &self, + ty: Ty<'tcx>, + ) -> Result<TyAndNaiveLayout<'tcx>, &'tcx LayoutError<'tcx>> { + self.tcx().naive_layout_of(self.param_env().and(ty)) + } } impl<'tcx, C: LayoutOfHelpers<'tcx>> LayoutOf<'tcx> for C {} |
