Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
-rw-r--r--crates/hir/src/lib.rs59
1 files changed, 47 insertions, 12 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 38add4eda1..5c0320f733 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -62,7 +62,7 @@ use hir_ty::{
consteval::{try_const_usize, unknown_const_as_generic, ConstEvalError, ConstExt},
diagnostics::BodyValidationDiagnostic,
display::HexifiedConst,
- layout::{Layout, LayoutError, RustcEnumVariantIdx, TagEncoding},
+ layout::{Layout as TyLayout, LayoutError, RustcEnumVariantIdx, TagEncoding},
method_resolution::{self, TyFingerprint},
mir::{self, interpret_mir},
primitive::UintTy,
@@ -961,8 +961,8 @@ impl Field {
Type::new(db, var_id, ty)
}
- pub fn layout(&self, db: &dyn HirDatabase) -> Result<Arc<Layout>, LayoutError> {
- db.layout_of_ty(self.ty(db).ty.clone(), self.parent.module(db).krate().into())
+ pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
+ db.layout_of_ty(self.ty(db).ty.clone(), self.parent.module(db).krate().into()).map(Layout)
}
pub fn parent_def(&self, _db: &dyn HirDatabase) -> VariantDef {
@@ -1135,10 +1135,10 @@ impl Enum {
self.variants(db).iter().any(|v| !matches!(v.kind(db), StructKind::Unit))
}
- pub fn layout(self, db: &dyn HirDatabase) -> Result<(Arc<Layout>, usize), LayoutError> {
+ pub fn layout(self, db: &dyn HirDatabase) -> Result<(Layout, usize), LayoutError> {
let layout = Adt::from(self).layout(db)?;
let tag_size =
- if let layout::Variants::Multiple { tag, tag_encoding, .. } = &layout.variants {
+ if let layout::Variants::Multiple { tag, tag_encoding, .. } = &layout.0.variants {
match tag_encoding {
TagEncoding::Direct => {
let target_data_layout = db
@@ -1219,11 +1219,11 @@ impl Variant {
let parent_enum = self.parent_enum(db);
let (parent_layout, tag_size) = parent_enum.layout(db)?;
Ok((
- match &parent_layout.variants {
+ match &parent_layout.0.variants {
layout::Variants::Multiple { variants, .. } => {
- variants[RustcEnumVariantIdx(self.id)].clone()
+ Layout(Arc::new(variants[RustcEnumVariantIdx(self.id)].clone()))
}
- _ => (*parent_layout).clone(),
+ _ => parent_layout,
},
tag_size,
))
@@ -1255,11 +1255,11 @@ impl Adt {
})
}
- pub fn layout(self, db: &dyn HirDatabase) -> Result<Arc<Layout>, LayoutError> {
+ pub fn layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
if db.generic_params(self.into()).iter().count() != 0 {
return Err(LayoutError::HasPlaceholder);
}
- db.layout_of_adt(self.into(), Substitution::empty(Interner), self.krate(db).id)
+ db.layout_of_adt(self.into(), Substitution::empty(Interner), self.krate(db).id).map(Layout)
}
/// Turns this ADT into a type. Any type parameters of the ADT will be
@@ -4243,8 +4243,8 @@ impl Type {
.collect()
}
- pub fn layout(&self, db: &dyn HirDatabase) -> Result<Arc<Layout>, LayoutError> {
- db.layout_of_ty(self.ty.clone(), self.env.krate)
+ pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
+ db.layout_of_ty(self.ty.clone(), self.env.krate).map(Layout)
}
}
@@ -4355,6 +4355,35 @@ fn closure_source(db: &dyn HirDatabase, closure: ClosureId) -> Option<ast::Closu
}
}
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Layout(Arc<TyLayout>);
+
+impl Layout {
+ pub fn size(&self) -> u64 {
+ self.0.size.bytes()
+ }
+
+ pub fn align(&self) -> u64 {
+ self.0.align.abi.bytes()
+ }
+
+ pub fn niches(&self, db: &dyn HirDatabase, krate: Crate) -> Option<u128> {
+ Some(self.0.largest_niche?.available(&*db.target_data_layout(krate.id)?))
+ }
+
+ pub fn field_offset(&self, idx: usize) -> Option<u64> {
+ match self.0.fields {
+ layout::FieldsShape::Primitive => None,
+ layout::FieldsShape::Union(_) => Some(0),
+ layout::FieldsShape::Array { stride, count } => {
+ let i = u64::try_from(idx).ok()?;
+ (i < count).then_some((stride * i).bytes())
+ }
+ layout::FieldsShape::Arbitrary { ref offsets, .. } => Some(offsets.get(idx)?.bytes()),
+ }
+ }
+}
+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum BindingMode {
Move,
@@ -4506,6 +4535,12 @@ impl HasCrate for Union {
}
}
+impl HasCrate for Enum {
+ fn krate(&self, db: &dyn HirDatabase) -> Crate {
+ self.module(db).krate()
+ }
+}
+
impl HasCrate for Field {
fn krate(&self, db: &dyn HirDatabase) -> Crate {
self.parent_def(db).module(db).krate()