Don't compute layout if TargetDataLayout is not available

This commit is contained in:
hkalbasi 2023-01-16 22:43:27 +03:30
parent 5306eb06cc
commit 77efa0267d
5 changed files with 19 additions and 36 deletions

View file

@ -90,6 +90,7 @@ impl IntegerExt for Integer {
pub enum LayoutError { pub enum LayoutError {
UserError(String), UserError(String),
SizeOverflow, SizeOverflow,
TargetLayoutNotAvailable,
HasPlaceholder, HasPlaceholder,
NotImplemented, NotImplemented,
Unknown, Unknown,

View file

@ -65,7 +65,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
fn layout_of_adt(&self, def: AdtId, subst: Substitution) -> Result<Layout, LayoutError>; fn layout_of_adt(&self, def: AdtId, subst: Substitution) -> Result<Layout, LayoutError>;
#[salsa::invoke(crate::layout::target_data_layout_query)] #[salsa::invoke(crate::layout::target_data_layout_query)]
fn target_data_layout(&self, krate: CrateId) -> Arc<TargetDataLayout>; fn target_data_layout(&self, krate: CrateId) -> Option<Arc<TargetDataLayout>>;
#[salsa::invoke(crate::lower::callable_item_sig)] #[salsa::invoke(crate::lower::callable_item_sig)]
fn callable_item_signature(&self, def: CallableDefId) -> PolyFnSig; fn callable_item_signature(&self, def: CallableDefId) -> PolyFnSig;

View file

@ -1,7 +1,5 @@
//! Compute the binary representation of a type //! Compute the binary representation of a type
use std::sync::Arc;
use base_db::CrateId; use base_db::CrateId;
use chalk_ir::{AdtId, TyKind}; use chalk_ir::{AdtId, TyKind};
use hir_def::{ use hir_def::{
@ -31,19 +29,19 @@ mod adt;
mod target; mod target;
struct LayoutCx<'a> { struct LayoutCx<'a> {
db: &'a dyn HirDatabase,
krate: CrateId, krate: CrateId,
target: &'a TargetDataLayout,
} }
impl LayoutCalculator for LayoutCx<'_> { impl<'a> LayoutCalculator for LayoutCx<'a> {
type TargetDataLayoutRef = Arc<TargetDataLayout>; type TargetDataLayoutRef = &'a TargetDataLayout;
fn delay_bug(&self, txt: &str) { fn delay_bug(&self, txt: &str) {
never!("{}", txt); never!("{}", txt);
} }
fn current_data_layout(&self) -> Arc<TargetDataLayout> { fn current_data_layout(&self) -> &'a TargetDataLayout {
self.db.target_data_layout(self.krate) self.target
} }
} }
@ -56,7 +54,8 @@ fn scalar(dl: &TargetDataLayout, value: Primitive) -> Layout {
} }
pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Layout, LayoutError> { pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Layout, LayoutError> {
let cx = LayoutCx { db, krate }; let Some(target) = db.target_data_layout(krate) else { return Err(LayoutError::TargetLayoutNotAvailable) };
let cx = LayoutCx { krate, target: &target };
let dl = &*cx.current_data_layout(); let dl = &*cx.current_data_layout();
Ok(match ty.kind(Interner) { Ok(match ty.kind(Interner) {
TyKind::Adt(AdtId(def), subst) => db.layout_of_adt(*def, subst.clone())?, TyKind::Adt(AdtId(def), subst) => db.layout_of_adt(*def, subst.clone())?,

View file

@ -23,7 +23,9 @@ pub fn layout_of_adt_query(
def: AdtId, def: AdtId,
subst: Substitution, subst: Substitution,
) -> Result<Layout, LayoutError> { ) -> Result<Layout, LayoutError> {
let cx = LayoutCx { db, krate: def.module(db.upcast()).krate() }; let krate = def.module(db.upcast()).krate();
let Some(target) = db.target_data_layout(krate) else { return Err(LayoutError::TargetLayoutNotAvailable) };
let cx = LayoutCx { krate, target: &target };
let dl = cx.current_data_layout(); let dl = cx.current_data_layout();
let handle_variant = |def: VariantId, var: &VariantData| { let handle_variant = |def: VariantId, var: &VariantData| {
var.fields() var.fields()

View file

@ -3,34 +3,15 @@
use std::sync::Arc; use std::sync::Arc;
use base_db::CrateId; use base_db::CrateId;
use hir_def::layout::{Endian, Size, TargetDataLayout}; use hir_def::layout::TargetDataLayout;
use crate::db::HirDatabase; use crate::db::HirDatabase;
pub fn target_data_layout_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<TargetDataLayout> { pub fn target_data_layout_query(
db: &dyn HirDatabase,
krate: CrateId,
) -> Option<Arc<TargetDataLayout>> {
let crate_graph = db.crate_graph(); let crate_graph = db.crate_graph();
let target_layout = &crate_graph[krate].target_layout; let target_layout = crate_graph[krate].target_layout.as_ref()?;
let cfg_options = &crate_graph[krate].cfg_options; Some(Arc::new(TargetDataLayout::parse_from_llvm_datalayout_string(&target_layout).ok()?))
Arc::new(
target_layout
.as_ref()
.and_then(|it| TargetDataLayout::parse_from_llvm_datalayout_string(it).ok())
.unwrap_or_else(|| {
let endian = match cfg_options.get_cfg_values("target_endian").next() {
Some(x) if x.as_str() == "big" => Endian::Big,
_ => Endian::Little,
};
let pointer_size = Size::from_bytes(
match cfg_options.get_cfg_values("target_pointer_width").next() {
Some(x) => match x.as_str() {
"16" => 2,
"32" => 4,
_ => 8,
},
_ => 8,
},
);
TargetDataLayout { endian, pointer_size, ..TargetDataLayout::default() }
}),
)
} }