Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/layout/target.rs')
| -rw-r--r-- | crates/hir-ty/src/layout/target.rs | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/crates/hir-ty/src/layout/target.rs b/crates/hir-ty/src/layout/target.rs index b2185a03ea..5bfe7bf010 100644 --- a/crates/hir-ty/src/layout/target.rs +++ b/crates/hir-ty/src/layout/target.rs @@ -2,6 +2,7 @@ use base_db::CrateId; use hir_def::layout::TargetDataLayout; +use rustc_abi::{AlignFromBytesError, TargetDataLayoutErrors}; use triomphe::Arc; use crate::db::HirDatabase; @@ -9,15 +10,40 @@ use crate::db::HirDatabase; pub fn target_data_layout_query( db: &dyn HirDatabase, krate: CrateId, -) -> Option<Arc<TargetDataLayout>> { +) -> Result<Arc<TargetDataLayout>, Arc<str>> { let crate_graph = db.crate_graph(); - let target_layout = crate_graph[krate].target_layout.as_ref().ok()?; - let res = TargetDataLayout::parse_from_llvm_datalayout_string(target_layout); - if let Err(_e) = &res { - // FIXME: Print the error here once it implements debug/display - // also logging here is somewhat wrong, but unfortunately this is the earliest place we can - // parse that doesn't impose a dependency to the rust-abi crate for project-model - tracing::error!("Failed to parse target data layout for {krate:?}"); + let res = crate_graph[krate].target_layout.as_deref(); + match res { + Ok(it) => match TargetDataLayout::parse_from_llvm_datalayout_string(it) { + Ok(it) => Ok(Arc::new(it)), + Err(e) => { + Err(match e { + TargetDataLayoutErrors::InvalidAddressSpace { addr_space, cause, err } => { + format!( + r#"invalid address space `{addr_space}` for `{cause}` in "data-layout": {err}"# + ) + } + TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => format!(r#"invalid {kind} `{bit}` for `{cause}` in "data-layout": {err}"#), + TargetDataLayoutErrors::MissingAlignment { cause } => format!(r#"missing alignment for `{cause}` in "data-layout""#), + TargetDataLayoutErrors::InvalidAlignment { cause, err } => format!( + r#"invalid alignment for `{cause}` in "data-layout": `{align}` is {err_kind}"#, + align = err.align(), + err_kind = match err { + AlignFromBytesError::NotPowerOfTwo(_) => "not a power of two", + AlignFromBytesError::TooLarge(_) => "too large", + } + ), + TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => { + format!(r#"inconsistent target specification: "data-layout" claims architecture is {dl}-endian, while "target-endian" is `{target}`"#) + } + TargetDataLayoutErrors::InconsistentTargetPointerWidth { + pointer_size, + target, + } => format!(r#"inconsistent target specification: "data-layout" claims pointers are {pointer_size}-bit, while "target-pointer-width" is `{target}`"#), + TargetDataLayoutErrors::InvalidBitsSize { err } => err, + }.into()) + } + }, + Err(e) => Err(Arc::from(&**e)), } - res.ok().map(Arc::new) } |