Skip to main content

hir_ty/layout/
target.rs

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