|
2 | 2 |
|
3 | 3 | use base_db::CrateId;
|
4 | 4 | use hir_def::layout::TargetDataLayout;
|
| 5 | +use ra_ap_rustc_abi::{AlignFromBytesError, TargetDataLayoutErrors}; |
5 | 6 | use triomphe::Arc;
|
6 | 7 |
|
7 | 8 | use crate::db::HirDatabase;
|
8 | 9 |
|
9 | 10 | pub fn target_data_layout_query(
|
10 | 11 | db: &dyn HirDatabase,
|
11 | 12 | krate: CrateId,
|
12 |
| -) -> Option<Arc<TargetDataLayout>> { |
| 13 | +) -> Result<Arc<TargetDataLayout>, Arc<str>> { |
13 | 14 | let crate_graph = db.crate_graph();
|
14 |
| - let target_layout = crate_graph[krate].target_layout.as_ref().ok()?; |
15 |
| - let res = TargetDataLayout::parse_from_llvm_datalayout_string(target_layout); |
16 |
| - if let Err(_e) = &res { |
17 |
| - // FIXME: Print the error here once it implements debug/display |
18 |
| - // also logging here is somewhat wrong, but unfortunately this is the earliest place we can |
19 |
| - // parse that doesn't impose a dependency to the rust-abi crate for project-model |
20 |
| - tracing::error!("Failed to parse target data layout for {krate:?}"); |
| 15 | + let res = crate_graph[krate].target_layout.as_deref(); |
| 16 | + match res { |
| 17 | + Ok(it) => match TargetDataLayout::parse_from_llvm_datalayout_string(it) { |
| 18 | + Ok(it) => Ok(Arc::new(it)), |
| 19 | + Err(e) => { |
| 20 | + Err(match e { |
| 21 | + TargetDataLayoutErrors::InvalidAddressSpace { addr_space, cause, err } => { |
| 22 | + format!( |
| 23 | + r#"invalid address space `{addr_space}` for `{cause}` in "data-layout": {err}"# |
| 24 | + ) |
| 25 | + } |
| 26 | + TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => format!(r#"invalid {kind} `{bit}` for `{cause}` in "data-layout": {err}"#), |
| 27 | + TargetDataLayoutErrors::MissingAlignment { cause } => format!(r#"missing alignment for `{cause}` in "data-layout""#), |
| 28 | + TargetDataLayoutErrors::InvalidAlignment { cause, err } => format!( |
| 29 | + r#"invalid alignment for `{cause}` in "data-layout": `{align}` is {err_kind}"#, |
| 30 | + align = err.align(), |
| 31 | + err_kind = match err { |
| 32 | + AlignFromBytesError::NotPowerOfTwo(_) => "not a power of two", |
| 33 | + AlignFromBytesError::TooLarge(_) => "too large", |
| 34 | + } |
| 35 | + ), |
| 36 | + TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => { |
| 37 | + format!(r#"inconsistent target specification: "data-layout" claims architecture is {dl}-endian, while "target-endian" is `{target}`"#) |
| 38 | + } |
| 39 | + TargetDataLayoutErrors::InconsistentTargetPointerWidth { |
| 40 | + pointer_size, |
| 41 | + target, |
| 42 | + } => format!(r#"inconsistent target specification: "data-layout" claims pointers are {pointer_size}-bit, while "target-pointer-width" is `{target}`"#), |
| 43 | + TargetDataLayoutErrors::InvalidBitsSize { err } => err, |
| 44 | + }.into()) |
| 45 | + } |
| 46 | + }, |
| 47 | + Err(e) => Err(Arc::from(&**e)), |
21 | 48 | }
|
22 |
| - res.ok().map(Arc::new) |
23 | 49 | }
|
0 commit comments