mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 05:15:04 +00:00
MIR episode 6
This commit is contained in:
parent
505fd09f9e
commit
51368793b4
35 changed files with 1474 additions and 556 deletions
|
@ -14,9 +14,9 @@ use stdx::never;
|
|||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase, infer::InferenceContext, layout::layout_of_ty, lower::ParamLoweringMode,
|
||||
to_placeholder_idx, utils::Generics, Const, ConstData, ConstScalar, ConstValue, GenericArg,
|
||||
Interner, MemoryMap, Substitution, Ty, TyBuilder,
|
||||
db::HirDatabase, infer::InferenceContext, lower::ParamLoweringMode,
|
||||
mir::monomorphize_mir_body_bad, to_placeholder_idx, utils::Generics, Const, ConstData,
|
||||
ConstScalar, ConstValue, GenericArg, Interner, MemoryMap, Substitution, Ty, TyBuilder,
|
||||
};
|
||||
|
||||
use super::mir::{interpret_mir, lower_to_mir, pad16, MirEvalError, MirLowerError};
|
||||
|
@ -130,14 +130,15 @@ pub fn intern_const_scalar(value: ConstScalar, ty: Ty) -> Const {
|
|||
|
||||
/// Interns a constant scalar with the given type
|
||||
pub fn intern_const_ref(db: &dyn HirDatabase, value: &ConstRef, ty: Ty, krate: CrateId) -> Const {
|
||||
let layout = db.layout_of_ty(ty.clone(), krate);
|
||||
let bytes = match value {
|
||||
ConstRef::Int(i) => {
|
||||
// FIXME: We should handle failure of layout better.
|
||||
let size = layout_of_ty(db, &ty, krate).map(|x| x.size.bytes_usize()).unwrap_or(16);
|
||||
let size = layout.map(|x| x.size.bytes_usize()).unwrap_or(16);
|
||||
ConstScalar::Bytes(i.to_le_bytes()[0..size].to_vec(), MemoryMap::default())
|
||||
}
|
||||
ConstRef::UInt(i) => {
|
||||
let size = layout_of_ty(db, &ty, krate).map(|x| x.size.bytes_usize()).unwrap_or(16);
|
||||
let size = layout.map(|x| x.size.bytes_usize()).unwrap_or(16);
|
||||
ConstScalar::Bytes(i.to_le_bytes()[0..size].to_vec(), MemoryMap::default())
|
||||
}
|
||||
ConstRef::Bool(b) => ConstScalar::Bytes(vec![*b as u8], MemoryMap::default()),
|
||||
|
@ -206,15 +207,22 @@ pub(crate) fn const_eval_query(
|
|||
subst: Substitution,
|
||||
) -> Result<Const, ConstEvalError> {
|
||||
let body = match def {
|
||||
GeneralConstId::ConstId(c) => db.mir_body(c.into())?,
|
||||
GeneralConstId::ConstId(c) => {
|
||||
db.monomorphized_mir_body(c.into(), subst, db.trait_environment(c.into()))?
|
||||
}
|
||||
GeneralConstId::AnonymousConstId(c) => {
|
||||
let (def, root) = db.lookup_intern_anonymous_const(c);
|
||||
let body = db.body(def);
|
||||
let infer = db.infer(def);
|
||||
Arc::new(lower_to_mir(db, def, &body, &infer, root)?)
|
||||
Arc::new(monomorphize_mir_body_bad(
|
||||
db,
|
||||
lower_to_mir(db, def, &body, &infer, root)?,
|
||||
subst,
|
||||
db.trait_environment_for_body(def),
|
||||
)?)
|
||||
}
|
||||
};
|
||||
let c = interpret_mir(db, &body, subst, false).0?;
|
||||
let c = interpret_mir(db, &body, false).0?;
|
||||
Ok(c)
|
||||
}
|
||||
|
||||
|
@ -222,8 +230,12 @@ pub(crate) fn const_eval_static_query(
|
|||
db: &dyn HirDatabase,
|
||||
def: StaticId,
|
||||
) -> Result<Const, ConstEvalError> {
|
||||
let body = db.mir_body(def.into())?;
|
||||
let c = interpret_mir(db, &body, Substitution::empty(Interner), false).0?;
|
||||
let body = db.monomorphized_mir_body(
|
||||
def.into(),
|
||||
Substitution::empty(Interner),
|
||||
db.trait_environment_for_body(def.into()),
|
||||
)?;
|
||||
let c = interpret_mir(db, &body, false).0?;
|
||||
Ok(c)
|
||||
}
|
||||
|
||||
|
@ -245,8 +257,12 @@ pub(crate) fn const_eval_discriminant_variant(
|
|||
};
|
||||
return Ok(value);
|
||||
}
|
||||
let mir_body = db.mir_body(def)?;
|
||||
let c = interpret_mir(db, &mir_body, Substitution::empty(Interner), false).0?;
|
||||
let mir_body = db.monomorphized_mir_body(
|
||||
def,
|
||||
Substitution::empty(Interner),
|
||||
db.trait_environment_for_body(def),
|
||||
)?;
|
||||
let c = interpret_mir(db, &mir_body, false).0?;
|
||||
let c = try_const_usize(db, &c).unwrap() as i128;
|
||||
Ok(c)
|
||||
}
|
||||
|
@ -271,7 +287,7 @@ pub(crate) fn eval_to_const(
|
|||
}
|
||||
let infer = ctx.clone().resolve_all();
|
||||
if let Ok(mir_body) = lower_to_mir(ctx.db, ctx.owner, &ctx.body, &infer, expr) {
|
||||
if let Ok(result) = interpret_mir(db, &mir_body, Substitution::empty(Interner), true).0 {
|
||||
if let Ok(result) = interpret_mir(db, &mir_body, true).0 {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue