mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 06:41:48 +00:00
Don't compute layout if TargetDataLayout
is not available
This commit is contained in:
parent
5306eb06cc
commit
77efa0267d
5 changed files with 19 additions and 36 deletions
|
@ -90,6 +90,7 @@ impl IntegerExt for Integer {
|
||||||
pub enum LayoutError {
|
pub enum LayoutError {
|
||||||
UserError(String),
|
UserError(String),
|
||||||
SizeOverflow,
|
SizeOverflow,
|
||||||
|
TargetLayoutNotAvailable,
|
||||||
HasPlaceholder,
|
HasPlaceholder,
|
||||||
NotImplemented,
|
NotImplemented,
|
||||||
Unknown,
|
Unknown,
|
||||||
|
|
|
@ -65,7 +65,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
|
||||||
fn layout_of_adt(&self, def: AdtId, subst: Substitution) -> Result<Layout, LayoutError>;
|
fn layout_of_adt(&self, def: AdtId, subst: Substitution) -> Result<Layout, LayoutError>;
|
||||||
|
|
||||||
#[salsa::invoke(crate::layout::target_data_layout_query)]
|
#[salsa::invoke(crate::layout::target_data_layout_query)]
|
||||||
fn target_data_layout(&self, krate: CrateId) -> Arc<TargetDataLayout>;
|
fn target_data_layout(&self, krate: CrateId) -> Option<Arc<TargetDataLayout>>;
|
||||||
|
|
||||||
#[salsa::invoke(crate::lower::callable_item_sig)]
|
#[salsa::invoke(crate::lower::callable_item_sig)]
|
||||||
fn callable_item_signature(&self, def: CallableDefId) -> PolyFnSig;
|
fn callable_item_signature(&self, def: CallableDefId) -> PolyFnSig;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
//! Compute the binary representation of a type
|
//! Compute the binary representation of a type
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use chalk_ir::{AdtId, TyKind};
|
use chalk_ir::{AdtId, TyKind};
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
|
@ -31,19 +29,19 @@ mod adt;
|
||||||
mod target;
|
mod target;
|
||||||
|
|
||||||
struct LayoutCx<'a> {
|
struct LayoutCx<'a> {
|
||||||
db: &'a dyn HirDatabase,
|
|
||||||
krate: CrateId,
|
krate: CrateId,
|
||||||
|
target: &'a TargetDataLayout,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutCalculator for LayoutCx<'_> {
|
impl<'a> LayoutCalculator for LayoutCx<'a> {
|
||||||
type TargetDataLayoutRef = Arc<TargetDataLayout>;
|
type TargetDataLayoutRef = &'a TargetDataLayout;
|
||||||
|
|
||||||
fn delay_bug(&self, txt: &str) {
|
fn delay_bug(&self, txt: &str) {
|
||||||
never!("{}", txt);
|
never!("{}", txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_data_layout(&self) -> Arc<TargetDataLayout> {
|
fn current_data_layout(&self) -> &'a TargetDataLayout {
|
||||||
self.db.target_data_layout(self.krate)
|
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<Layout, LayoutError> {
|
pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Layout, LayoutError> {
|
||||||
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();
|
let dl = &*cx.current_data_layout();
|
||||||
Ok(match ty.kind(Interner) {
|
Ok(match ty.kind(Interner) {
|
||||||
TyKind::Adt(AdtId(def), subst) => db.layout_of_adt(*def, subst.clone())?,
|
TyKind::Adt(AdtId(def), subst) => db.layout_of_adt(*def, subst.clone())?,
|
||||||
|
|
|
@ -23,7 +23,9 @@ pub fn layout_of_adt_query(
|
||||||
def: AdtId,
|
def: AdtId,
|
||||||
subst: Substitution,
|
subst: Substitution,
|
||||||
) -> Result<Layout, LayoutError> {
|
) -> Result<Layout, LayoutError> {
|
||||||
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 dl = cx.current_data_layout();
|
||||||
let handle_variant = |def: VariantId, var: &VariantData| {
|
let handle_variant = |def: VariantId, var: &VariantData| {
|
||||||
var.fields()
|
var.fields()
|
||||||
|
|
|
@ -3,34 +3,15 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use hir_def::layout::{Endian, Size, TargetDataLayout};
|
use hir_def::layout::TargetDataLayout;
|
||||||
|
|
||||||
use crate::db::HirDatabase;
|
use crate::db::HirDatabase;
|
||||||
|
|
||||||
pub fn target_data_layout_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<TargetDataLayout> {
|
pub fn target_data_layout_query(
|
||||||
|
db: &dyn HirDatabase,
|
||||||
|
krate: CrateId,
|
||||||
|
) -> Option<Arc<TargetDataLayout>> {
|
||||||
let crate_graph = db.crate_graph();
|
let crate_graph = db.crate_graph();
|
||||||
let target_layout = &crate_graph[krate].target_layout;
|
let target_layout = crate_graph[krate].target_layout.as_ref()?;
|
||||||
let cfg_options = &crate_graph[krate].cfg_options;
|
Some(Arc::new(TargetDataLayout::parse_from_llvm_datalayout_string(&target_layout).ok()?))
|
||||||
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() }
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue