mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 13:51:31 +00:00
MIR episode 6
This commit is contained in:
parent
505fd09f9e
commit
51368793b4
35 changed files with 1474 additions and 556 deletions
|
@ -10,6 +10,7 @@ use hir_def::{
|
|||
};
|
||||
use la_arena::RawIdx;
|
||||
use smallvec::SmallVec;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase,
|
||||
|
@ -18,7 +19,7 @@ use crate::{
|
|||
Substitution,
|
||||
};
|
||||
|
||||
use super::{layout_of_ty, LayoutCx};
|
||||
use super::LayoutCx;
|
||||
|
||||
pub(crate) fn struct_variant_idx() -> RustcEnumVariantIdx {
|
||||
RustcEnumVariantIdx(LocalEnumVariantId::from_raw(RawIdx::from(0)))
|
||||
|
@ -29,14 +30,14 @@ pub fn layout_of_adt_query(
|
|||
def: AdtId,
|
||||
subst: Substitution,
|
||||
krate: CrateId,
|
||||
) -> Result<Layout, LayoutError> {
|
||||
) -> Result<Arc<Layout>, LayoutError> {
|
||||
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 handle_variant = |def: VariantId, var: &VariantData| {
|
||||
var.fields()
|
||||
.iter()
|
||||
.map(|(fd, _)| layout_of_ty(db, &field_ty(db, def, fd, &subst), cx.krate))
|
||||
.map(|(fd, _)| db.layout_of_ty(field_ty(db, def, fd, &subst), cx.krate))
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
};
|
||||
let (variants, repr) = match def {
|
||||
|
@ -67,11 +68,13 @@ pub fn layout_of_adt_query(
|
|||
(r, data.repr.unwrap_or_default())
|
||||
}
|
||||
};
|
||||
let variants =
|
||||
variants.iter().map(|x| x.iter().collect::<Vec<_>>()).collect::<SmallVec<[_; 1]>>();
|
||||
let variants = variants
|
||||
.iter()
|
||||
.map(|x| x.iter().map(|x| &**x).collect::<Vec<_>>())
|
||||
.collect::<SmallVec<[_; 1]>>();
|
||||
let variants = variants.iter().map(|x| x.iter().collect()).collect();
|
||||
if matches!(def, AdtId::UnionId(..)) {
|
||||
cx.layout_of_union(&repr, &variants).ok_or(LayoutError::Unknown)
|
||||
let result = if matches!(def, AdtId::UnionId(..)) {
|
||||
cx.layout_of_union(&repr, &variants).ok_or(LayoutError::Unknown)?
|
||||
} else {
|
||||
cx.layout_of_struct_or_enum(
|
||||
&repr,
|
||||
|
@ -103,8 +106,9 @@ pub fn layout_of_adt_query(
|
|||
.and_then(|x| x.last().map(|x| x.is_unsized()))
|
||||
.unwrap_or(true),
|
||||
)
|
||||
.ok_or(LayoutError::SizeOverflow)
|
||||
}
|
||||
.ok_or(LayoutError::SizeOverflow)?
|
||||
};
|
||||
Ok(Arc::new(result))
|
||||
}
|
||||
|
||||
fn layout_scalar_valid_range(db: &dyn HirDatabase, def: AdtId) -> (Bound<u128>, Bound<u128>) {
|
||||
|
@ -129,7 +133,7 @@ pub fn layout_of_adt_recover(
|
|||
_: &AdtId,
|
||||
_: &Substitution,
|
||||
_: &CrateId,
|
||||
) -> Result<Layout, LayoutError> {
|
||||
) -> Result<Arc<Layout>, LayoutError> {
|
||||
user_error!("infinite sized recursive type");
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::collections::HashMap;
|
|||
use base_db::fixture::WithFixture;
|
||||
use chalk_ir::{AdtId, TyKind};
|
||||
use hir_def::db::DefDatabase;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase,
|
||||
|
@ -11,15 +12,13 @@ use crate::{
|
|||
Interner, Substitution,
|
||||
};
|
||||
|
||||
use super::layout_of_ty;
|
||||
|
||||
mod closure;
|
||||
|
||||
fn current_machine_data_layout() -> String {
|
||||
project_model::target_data_layout::get(None, None, &HashMap::default()).unwrap()
|
||||
}
|
||||
|
||||
fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Layout, LayoutError> {
|
||||
fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutError> {
|
||||
let target_data_layout = current_machine_data_layout();
|
||||
let ra_fixture = format!(
|
||||
"{minicore}//- /main.rs crate:test target_data_layout:{target_data_layout}\n{ra_fixture}",
|
||||
|
@ -47,11 +46,11 @@ fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Layout, LayoutError> {
|
|||
})
|
||||
.unwrap();
|
||||
let goal_ty = TyKind::Adt(AdtId(adt_id), Substitution::empty(Interner)).intern(Interner);
|
||||
layout_of_ty(&db, &goal_ty, module_id.krate())
|
||||
db.layout_of_ty(goal_ty, module_id.krate())
|
||||
}
|
||||
|
||||
/// A version of `eval_goal` for types that can not be expressed in ADTs, like closures and `impl Trait`
|
||||
fn eval_expr(ra_fixture: &str, minicore: &str) -> Result<Layout, LayoutError> {
|
||||
fn eval_expr(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutError> {
|
||||
let target_data_layout = current_machine_data_layout();
|
||||
let ra_fixture = format!(
|
||||
"{minicore}//- /main.rs crate:test target_data_layout:{target_data_layout}\nfn main(){{let goal = {{{ra_fixture}}};}}",
|
||||
|
@ -75,7 +74,7 @@ fn eval_expr(ra_fixture: &str, minicore: &str) -> Result<Layout, LayoutError> {
|
|||
let b = hir_body.bindings.iter().find(|x| x.1.name.to_smol_str() == "goal").unwrap().0;
|
||||
let infer = db.infer(adt_id.into());
|
||||
let goal_ty = infer.type_of_binding[b].clone();
|
||||
layout_of_ty(&db, &goal_ty, module_id.krate())
|
||||
db.layout_of_ty(goal_ty, module_id.krate())
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue