diff --git a/crates/hir-def/src/layout.rs b/crates/hir-def/src/layout.rs index 6bb4cd94f8a0..49b1190ad46a 100644 --- a/crates/hir-def/src/layout.rs +++ b/crates/hir-def/src/layout.rs @@ -90,6 +90,7 @@ impl IntegerExt for Integer { pub enum LayoutError { UserError(String), SizeOverflow, + TargetLayoutNotAvailable, HasPlaceholder, NotImplemented, Unknown, diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs index 54b244620fba..d45e2a943add 100644 --- a/crates/hir-ty/src/db.rs +++ b/crates/hir-ty/src/db.rs @@ -65,7 +65,7 @@ pub trait HirDatabase: DefDatabase + Upcast { fn layout_of_adt(&self, def: AdtId, subst: Substitution) -> Result; #[salsa::invoke(crate::layout::target_data_layout_query)] - fn target_data_layout(&self, krate: CrateId) -> Arc; + fn target_data_layout(&self, krate: CrateId) -> Option>; #[salsa::invoke(crate::lower::callable_item_sig)] fn callable_item_signature(&self, def: CallableDefId) -> PolyFnSig; diff --git a/crates/hir-ty/src/layout.rs b/crates/hir-ty/src/layout.rs index 958d3dabe0ed..cd7f1b805c5c 100644 --- a/crates/hir-ty/src/layout.rs +++ b/crates/hir-ty/src/layout.rs @@ -1,7 +1,5 @@ //! Compute the binary representation of a type -use std::sync::Arc; - use base_db::CrateId; use chalk_ir::{AdtId, TyKind}; use hir_def::{ @@ -31,19 +29,19 @@ mod adt; mod target; struct LayoutCx<'a> { - db: &'a dyn HirDatabase, krate: CrateId, + target: &'a TargetDataLayout, } -impl LayoutCalculator for LayoutCx<'_> { - type TargetDataLayoutRef = Arc; +impl<'a> LayoutCalculator for LayoutCx<'a> { + type TargetDataLayoutRef = &'a TargetDataLayout; fn delay_bug(&self, txt: &str) { never!("{}", txt); } - fn current_data_layout(&self) -> Arc { - self.db.target_data_layout(self.krate) + fn current_data_layout(&self) -> &'a TargetDataLayout { + 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 { - 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(); Ok(match ty.kind(Interner) { TyKind::Adt(AdtId(def), subst) => db.layout_of_adt(*def, subst.clone())?, diff --git a/crates/hir-ty/src/layout/adt.rs b/crates/hir-ty/src/layout/adt.rs index 23166a5a5223..cb7968c14465 100644 --- a/crates/hir-ty/src/layout/adt.rs +++ b/crates/hir-ty/src/layout/adt.rs @@ -23,7 +23,9 @@ pub fn layout_of_adt_query( def: AdtId, subst: Substitution, ) -> Result { - 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 handle_variant = |def: VariantId, var: &VariantData| { var.fields() diff --git a/crates/hir-ty/src/layout/target.rs b/crates/hir-ty/src/layout/target.rs index 37b831652f56..93dcd79e120c 100644 --- a/crates/hir-ty/src/layout/target.rs +++ b/crates/hir-ty/src/layout/target.rs @@ -3,34 +3,15 @@ use std::sync::Arc; use base_db::CrateId; -use hir_def::layout::{Endian, Size, TargetDataLayout}; +use hir_def::layout::TargetDataLayout; use crate::db::HirDatabase; -pub fn target_data_layout_query(db: &dyn HirDatabase, krate: CrateId) -> Arc { +pub fn target_data_layout_query( + db: &dyn HirDatabase, + krate: CrateId, +) -> Option> { let crate_graph = db.crate_graph(); - let target_layout = &crate_graph[krate].target_layout; - let cfg_options = &crate_graph[krate].cfg_options; - 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() } - }), - ) + let target_layout = crate_graph[krate].target_layout.as_ref()?; + Some(Arc::new(TargetDataLayout::parse_from_llvm_datalayout_string(&target_layout).ok()?)) }