Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/mir/eval.rs')
-rw-r--r--crates/hir-ty/src/mir/eval.rs36
1 files changed, 22 insertions, 14 deletions
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 1ec32010a1..c5d843d9eb 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -29,7 +29,7 @@ use crate::{
use super::{
const_as_usize, return_slot, AggregateKind, BinOp, CastKind, LocalId, MirBody, MirLowerError,
- Operand, Place, ProjectionElem, Rvalue, Statement, Terminator, UnOp,
+ Operand, Place, ProjectionElem, Rvalue, StatementKind, Terminator, UnOp,
};
pub struct Evaluator<'a> {
@@ -263,12 +263,14 @@ impl Evaluator<'_> {
for proj in &p.projection {
match proj {
ProjectionElem::Deref => {
- match &ty.data(Interner).kind {
- TyKind::Ref(_, _, inner) => {
- ty = inner.clone();
+ ty = match &ty.data(Interner).kind {
+ TyKind::Raw(_, inner) | TyKind::Ref(_, _, inner) => inner.clone(),
+ _ => {
+ return Err(MirEvalError::TypeError(
+ "Overloaded deref in MIR is disallowed",
+ ))
}
- _ => not_supported!("dereferencing smart pointers"),
- }
+ };
let x = from_bytes!(usize, self.read_memory(addr, self.ptr_size())?);
addr = Address::from_usize(x);
}
@@ -395,7 +397,8 @@ impl Evaluator<'_> {
.locals
.iter()
.map(|(id, x)| {
- let size = self.size_of_sized(&x.ty, &locals, "no unsized local")?;
+ let size =
+ self.size_of_sized(&x.ty, &locals, "no unsized local in extending stack")?;
let my_ptr = stack_ptr;
stack_ptr += size;
Ok((id, Stack(my_ptr)))
@@ -425,16 +428,16 @@ impl Evaluator<'_> {
return Err(MirEvalError::ExecutionLimitExceeded);
}
for statement in &current_block.statements {
- match statement {
- Statement::Assign(l, r) => {
+ match &statement.kind {
+ StatementKind::Assign(l, r) => {
let addr = self.place_addr(l, &locals)?;
let result = self.eval_rvalue(r, &locals)?.to_vec(&self)?;
self.write_memory(addr, &result)?;
}
- Statement::Deinit(_) => not_supported!("de-init statement"),
- Statement::StorageLive(_) => not_supported!("storage-live statement"),
- Statement::StorageDead(_) => not_supported!("storage-dead statement"),
- Statement::Nop => (),
+ StatementKind::Deinit(_) => not_supported!("de-init statement"),
+ StatementKind::StorageLive(_)
+ | StatementKind::StorageDead(_)
+ | StatementKind::Nop => (),
}
}
let Some(terminator) = current_block.terminator.as_ref() else {
@@ -1121,7 +1124,12 @@ impl Evaluator<'_> {
}
fn detect_lang_function(&self, def: FunctionId) -> Option<LangItem> {
- lang_attr(self.db.upcast(), def)
+ let candidate = lang_attr(self.db.upcast(), def)?;
+ // filter normal lang functions out
+ if [LangItem::IntoIterIntoIter, LangItem::IteratorNext].contains(&candidate) {
+ return None;
+ }
+ Some(candidate)
}
fn create_memory_map(&self, bytes: &[u8], ty: &Ty, locals: &Locals<'_>) -> Result<MemoryMap> {