1use base_db::Crate;
4use hir_def::layout::TargetDataLayout;
5use rustc_abi::{AddressSpace, AlignFromBytesError, TargetDataLayoutErrors};
6use triomphe::Arc;
7
8use crate::db::HirDatabase;
9
10pub fn target_data_layout_query(
11 db: &dyn HirDatabase,
12 krate: Crate,
13) -> Result<Arc<TargetDataLayout>, Arc<str>> {
14 match &krate.workspace_data(db).data_layout {
15 Ok(it) => match TargetDataLayout::parse_from_llvm_datalayout_string(it, AddressSpace::ZERO) {
16 Ok(it) => Ok(Arc::new(it)),
17 Err(e) => {
18 Err(match e {
19 TargetDataLayoutErrors::InvalidAddressSpace { addr_space, cause, err } => {
20 format!(
21 r#"invalid address space `{addr_space}` for `{cause}` in "data-layout": {err}"#
22 )
23 }
24 TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => format!(r#"invalid {kind} `{bit}` for `{cause}` in "data-layout": {err}"#),
25 TargetDataLayoutErrors::MissingAlignment { cause } => format!(r#"missing alignment for `{cause}` in "data-layout""#),
26 TargetDataLayoutErrors::InvalidAlignment { cause, err } => format!(
27 r#"invalid alignment for `{cause}` in "data-layout": `{align}` is {err_kind}"#,
28 align = err.align(),
29 err_kind = match err {
30 AlignFromBytesError::NotPowerOfTwo(_) => "not a power of two",
31 AlignFromBytesError::TooLarge(_) => "too large",
32 }
33 ),
34 TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
35 format!(r#"inconsistent target specification: "data-layout" claims architecture is {dl}-endian, while "target-endian" is `{target}`"#)
36 }
37 TargetDataLayoutErrors::InconsistentTargetPointerWidth {
38 pointer_size,
39 target,
40 } => format!(r#"inconsistent target specification: "data-layout" claims pointers are {pointer_size}-bit, while "target-pointer-width" is `{target}`"#),
41 TargetDataLayoutErrors::InvalidBitsSize { err } => err,
42 TargetDataLayoutErrors::UnknownPointerSpecification { err } => format!(r#"use of unknown pointer specifer in "data-layout": {err}"#),
43 }.into())
44 }
45 },
46 Err(e) => Err(e.clone()),
47 }
48}