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.rs226
1 files changed, 134 insertions, 92 deletions
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index fa63baa5d2..e46490e526 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -32,6 +32,7 @@ use stdx::never;
use syntax::{SyntaxNodePtr, TextRange};
use triomphe::Arc;
+use crate::next_solver::mapping::NextSolverToChalk;
use crate::{
AliasTy, CallableDefId, ClosureId, ComplexMemoryMap, Const, ConstData, ConstScalar, Interner,
MemoryMap, Substitution, ToChalk, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind,
@@ -102,13 +103,13 @@ impl<'db> VTableMap<'db> {
id
}
- pub(crate) fn ty(&self, id: usize) -> Result<crate::next_solver::Ty<'db>> {
+ pub(crate) fn ty(&self, id: usize) -> Result<'db, crate::next_solver::Ty<'db>> {
id.checked_sub(VTableMap::OFFSET)
.and_then(|id| self.id_to_ty.get(id).copied())
.ok_or(MirEvalError::InvalidVTableId(id))
}
- fn ty_of_bytes(&self, bytes: &[u8]) -> Result<crate::next_solver::Ty<'db>> {
+ fn ty_of_bytes(&self, bytes: &[u8]) -> Result<'db, crate::next_solver::Ty<'db>> {
let id = from_bytes!(usize, bytes);
self.ty(id)
}
@@ -134,14 +135,14 @@ impl TlsData {
self.keys.len() - 1
}
- fn get_key(&mut self, key: usize) -> Result<u128> {
+ fn get_key(&mut self, key: usize) -> Result<'static, u128> {
let r = self.keys.get(key).ok_or_else(|| {
MirEvalError::UndefinedBehavior(format!("Getting invalid tls key {key}"))
})?;
Ok(*r)
}
- fn set_key(&mut self, key: usize, value: u128) -> Result<()> {
+ fn set_key(&mut self, key: usize, value: u128) -> Result<'static, ()> {
let r = self.keys.get_mut(key).ok_or_else(|| {
MirEvalError::UndefinedBehavior(format!("Setting invalid tls key {key}"))
})?;
@@ -202,6 +203,7 @@ pub struct Evaluator<'a> {
stack_depth_limit: usize,
/// Maximum count of bytes that heap and stack can grow
memory_limit: usize,
+ interner: DbInterner<'a>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -230,15 +232,19 @@ impl Interval {
Self { addr, size }
}
- fn get<'a, 'db>(&self, memory: &'a Evaluator<'db>) -> Result<&'a [u8]> {
+ fn get<'a, 'db>(&self, memory: &'a Evaluator<'db>) -> Result<'db, &'a [u8]> {
memory.read_memory(self.addr, self.size)
}
- fn write_from_bytes(&self, memory: &mut Evaluator<'_>, bytes: &[u8]) -> Result<()> {
+ fn write_from_bytes<'db>(&self, memory: &mut Evaluator<'db>, bytes: &[u8]) -> Result<'db, ()> {
memory.write_memory(self.addr, bytes)
}
- fn write_from_interval(&self, memory: &mut Evaluator<'_>, interval: Interval) -> Result<()> {
+ fn write_from_interval<'db>(
+ &self,
+ memory: &mut Evaluator<'db>,
+ interval: Interval,
+ ) -> Result<'db, ()> {
memory.copy_from_interval(self.addr, interval)
}
@@ -248,16 +254,16 @@ impl Interval {
}
impl IntervalAndTy {
- fn get<'a, 'db>(&self, memory: &'a Evaluator<'db>) -> Result<&'a [u8]> {
+ fn get<'a, 'db>(&self, memory: &'a Evaluator<'db>) -> Result<'db, &'a [u8]> {
memory.read_memory(self.interval.addr, self.interval.size)
}
- fn new(
+ fn new<'db>(
addr: Address,
ty: Ty,
- evaluator: &Evaluator<'_>,
+ evaluator: &Evaluator<'db>,
locals: &Locals,
- ) -> Result<IntervalAndTy> {
+ ) -> Result<'db, IntervalAndTy> {
let size = evaluator.size_of_sized(&ty, locals, "type of interval")?;
Ok(IntervalAndTy { interval: Interval { addr, size }, ty })
}
@@ -275,7 +281,7 @@ impl From<Interval> for IntervalOrOwned {
}
impl IntervalOrOwned {
- fn get<'a, 'db>(&'a self, memory: &'a Evaluator<'db>) -> Result<&'a [u8]> {
+ fn get<'a, 'db>(&'a self, memory: &'a Evaluator<'db>) -> Result<'db, &'a [u8]> {
Ok(match self {
IntervalOrOwned::Owned(o) => o,
IntervalOrOwned::Borrowed(b) => b.get(memory)?,
@@ -295,7 +301,7 @@ const HEAP_OFFSET: usize = 1 << 29;
impl Address {
#[allow(clippy::double_parens)]
- fn from_bytes(it: &[u8]) -> Result<Self> {
+ fn from_bytes<'db>(it: &[u8]) -> Result<'db, Self> {
Ok(Address::from_usize(from_bytes!(usize, it)))
}
@@ -335,8 +341,8 @@ impl Address {
}
#[derive(Clone, PartialEq, Eq)]
-pub enum MirEvalError {
- ConstEvalError(String, Box<ConstEvalError>),
+pub enum MirEvalError<'db> {
+ ConstEvalError(String, Box<ConstEvalError<'db>>),
LayoutError(LayoutError, Ty),
TargetDataLayoutNotAvailable(TargetLoadError),
/// Means that code had undefined behavior. We don't try to actively detect UB, but if it was detected
@@ -344,12 +350,15 @@ pub enum MirEvalError {
UndefinedBehavior(String),
Panic(String),
// FIXME: This should be folded into ConstEvalError?
- MirLowerError(FunctionId, MirLowerError),
- MirLowerErrorForClosure(ClosureId, MirLowerError),
+ MirLowerError(FunctionId, MirLowerError<'db>),
+ MirLowerErrorForClosure(ClosureId, MirLowerError<'db>),
TypeIsUnsized(Ty, &'static str),
NotSupported(String),
InvalidConst(Const),
- InFunction(Box<MirEvalError>, Vec<(Either<FunctionId, ClosureId>, MirSpan, DefWithBodyId)>),
+ InFunction(
+ Box<MirEvalError<'db>>,
+ Vec<(Either<FunctionId, ClosureId>, MirSpan, DefWithBodyId)>,
+ ),
ExecutionLimitExceeded,
StackOverflow,
/// FIXME: Fold this into InternalError
@@ -360,7 +369,7 @@ pub enum MirEvalError {
InternalError(Box<str>),
}
-impl MirEvalError {
+impl MirEvalError<'_> {
pub fn pretty_print(
&self,
f: &mut String,
@@ -492,7 +501,7 @@ impl MirEvalError {
}
}
-impl std::fmt::Debug for MirEvalError {
+impl std::fmt::Debug for MirEvalError<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::ConstEvalError(arg0, arg1) => {
@@ -534,7 +543,7 @@ impl std::fmt::Debug for MirEvalError {
}
}
-type Result<T> = std::result::Result<T, MirEvalError>;
+type Result<'db, T> = std::result::Result<T, MirEvalError<'db>>;
#[derive(Debug, Default)]
struct DropFlags {
@@ -595,10 +604,10 @@ pub fn interpret_mir<'db>(
// (and probably should) do better here, for example by excluding bindings outside of the target expression.
assert_placeholder_ty_is_unused: bool,
trait_env: Option<Arc<TraitEnvironment<'db>>>,
-) -> Result<(Result<Const>, MirOutput)> {
+) -> Result<'db, (Result<'db, Const>, MirOutput)> {
let ty = body.locals[return_slot()].ty.clone();
let mut evaluator = Evaluator::new(db, body.owner, assert_placeholder_ty_is_unused, trait_env)?;
- let it: Result<Const> = (|| {
+ let it: Result<'db, Const> = (|| {
if evaluator.ptr_size() != size_of::<usize>() {
not_supported!("targets with different pointer size from host");
}
@@ -639,13 +648,14 @@ impl<'db> Evaluator<'db> {
owner: DefWithBodyId,
assert_placeholder_ty_is_unused: bool,
trait_env: Option<Arc<TraitEnvironment<'db>>>,
- ) -> Result<Evaluator<'db>> {
+ ) -> Result<'db, Evaluator<'db>> {
let crate_id = owner.module(db).krate();
let target_data_layout = match db.target_data_layout(crate_id) {
Ok(target_data_layout) => target_data_layout,
Err(e) => return Err(MirEvalError::TargetDataLayoutNotAvailable(e)),
};
let cached_ptr_size = target_data_layout.pointer_size().bytes_usize();
+ let interner = DbInterner::new_with(db, None, None);
Ok(Evaluator {
target_data_layout,
stack: vec![0],
@@ -679,14 +689,15 @@ impl<'db> Evaluator<'db> {
cached_fn_once_trait_func: LangItem::FnOnce.resolve_trait(db, crate_id).and_then(|x| {
x.trait_items(db).method_by_name(&Name::new_symbol_root(sym::call_once))
}),
+ interner,
})
}
- fn place_addr(&self, p: &Place, locals: &Locals) -> Result<Address> {
+ fn place_addr(&self, p: &Place, locals: &Locals) -> Result<'db, Address> {
Ok(self.place_addr_and_ty_and_metadata(p, locals)?.0)
}
- fn place_interval(&self, p: &Place, locals: &Locals) -> Result<Interval> {
+ fn place_interval(&self, p: &Place, locals: &Locals) -> Result<'db, Interval> {
let place_addr_and_ty = self.place_addr_and_ty_and_metadata(p, locals)?;
Ok(Interval {
addr: place_addr_and_ty.0,
@@ -714,14 +725,20 @@ impl<'db> Evaluator<'db> {
|c, subst, f| {
let InternedClosure(def, _) = self.db.lookup_intern_closure(c.into());
let infer = self.db.infer(def);
- let (captures, _) = infer.closure_info(&c);
+ let (captures, _) = infer.closure_info(c.into());
let parent_subst = ClosureSubst(subst).parent_subst(self.db);
captures
.get(f)
.expect("broken closure field")
.ty
- .clone()
- .substitute(Interner, &parent_subst)
+ .instantiate(
+ self.interner,
+ <_ as ChalkToNextSolver<'db, crate::next_solver::GenericArgs<'db>>>::to_nextsolver(
+ &parent_subst,
+ self.interner,
+ ),
+ )
+ .to_chalk(self.interner)
},
self.crate_id,
);
@@ -733,7 +750,7 @@ impl<'db> Evaluator<'db> {
&'a self,
p: &Place,
locals: &'a Locals,
- ) -> Result<(Address, Ty, Option<IntervalOrOwned>)> {
+ ) -> Result<'db, (Address, Ty, Option<IntervalOrOwned>)> {
let interner = DbInterner::new_with(self.db, None, None);
let mut addr = locals.ptr[p.local].addr;
let mut ty: Ty = locals.body.locals[p.local].ty.clone();
@@ -851,7 +868,7 @@ impl<'db> Evaluator<'db> {
Ok((addr, ty, metadata))
}
- fn layout(&self, ty: crate::next_solver::Ty<'db>) -> Result<Arc<Layout>> {
+ fn layout(&self, ty: crate::next_solver::Ty<'db>) -> Result<'db, Arc<Layout>> {
if let Some(x) = self.layout_cache.borrow().get(&ty) {
return Ok(x.clone());
}
@@ -864,7 +881,7 @@ impl<'db> Evaluator<'db> {
Ok(r)
}
- fn layout_adt(&self, adt: AdtId, subst: Substitution) -> Result<Arc<Layout>> {
+ fn layout_adt(&self, adt: AdtId, subst: Substitution) -> Result<'db, Arc<Layout>> {
let interner = DbInterner::new_with(self.db, None, None);
self.layout(crate::next_solver::Ty::new(
interner,
@@ -875,22 +892,27 @@ impl<'db> Evaluator<'db> {
))
}
- fn place_ty<'a>(&'a self, p: &Place, locals: &'a Locals) -> Result<Ty> {
+ fn place_ty<'a>(&'a self, p: &Place, locals: &'a Locals) -> Result<'db, Ty> {
Ok(self.place_addr_and_ty_and_metadata(p, locals)?.1)
}
- fn operand_ty(&self, o: &Operand, locals: &Locals) -> Result<Ty> {
+ fn operand_ty(&self, o: &Operand, locals: &Locals) -> Result<'db, Ty> {
Ok(match &o.kind {
OperandKind::Copy(p) | OperandKind::Move(p) => self.place_ty(p, locals)?,
OperandKind::Constant(c) => c.data(Interner).ty.clone(),
&OperandKind::Static(s) => {
- let ty = self.db.infer(s.into())[self.db.body(s.into()).body_expr].clone();
+ let ty = self.db.infer(s.into())[self.db.body(s.into()).body_expr]
+ .to_chalk(self.interner);
TyKind::Ref(Mutability::Not, static_lifetime(), ty).intern(Interner)
}
})
}
- fn operand_ty_and_eval(&mut self, o: &Operand, locals: &mut Locals) -> Result<IntervalAndTy> {
+ fn operand_ty_and_eval(
+ &mut self,
+ o: &Operand,
+ locals: &mut Locals,
+ ) -> Result<'db, IntervalAndTy> {
Ok(IntervalAndTy {
interval: self.eval_operand(o, locals)?,
ty: self.operand_ty(o, locals)?,
@@ -901,7 +923,7 @@ impl<'db> Evaluator<'db> {
&mut self,
body: Arc<MirBody>,
args: impl Iterator<Item = IntervalOrOwned>,
- ) -> Result<Interval> {
+ ) -> Result<'db, Interval> {
if let Some(it) = self.stack_depth_limit.checked_sub(1) {
self.stack_depth_limit = it;
} else {
@@ -962,7 +984,7 @@ impl<'db> Evaluator<'db> {
let args = args
.iter()
.map(|it| self.operand_ty_and_eval(it, locals))
- .collect::<Result<Vec<_>>>()?;
+ .collect::<Result<'db, Vec<_>>>()?;
let stack_frame = match &fn_ty.kind(Interner) {
TyKind::Function(_) => {
let bytes = self.eval_operand(func, locals)?;
@@ -1066,7 +1088,7 @@ impl<'db> Evaluator<'db> {
body: &MirBody,
locals: &mut Locals,
args: impl Iterator<Item = IntervalOrOwned>,
- ) -> Result<()> {
+ ) -> Result<'db, ()> {
let mut remain_args = body.param_locals.len();
for ((l, interval), value) in locals.ptr.iter().skip(1).zip(args) {
locals.drop_flags.add_place(l.into(), &locals.body.projection_store);
@@ -1089,7 +1111,7 @@ impl<'db> Evaluator<'db> {
&mut self,
body: &Arc<MirBody>,
destination: Option<Interval>,
- ) -> Result<(Locals, usize)> {
+ ) -> Result<'db, (Locals, usize)> {
let mut locals =
match self.unused_locals_store.borrow_mut().entry(body.owner).or_default().pop() {
None => Locals {
@@ -1136,7 +1158,7 @@ impl<'db> Evaluator<'db> {
Ok((locals, prev_stack_pointer))
}
- fn eval_rvalue(&mut self, r: &Rvalue, locals: &mut Locals) -> Result<IntervalOrOwned> {
+ fn eval_rvalue(&mut self, r: &Rvalue, locals: &mut Locals) -> Result<'db, IntervalOrOwned> {
let interner = DbInterner::new_with(self.db, None, None);
use IntervalOrOwned::*;
Ok(match r {
@@ -1450,7 +1472,7 @@ impl<'db> Evaluator<'db> {
let values = values
.iter()
.map(|it| self.eval_operand(it, locals))
- .collect::<Result<Vec<_>>>()?;
+ .collect::<Result<'db, Vec<_>>>()?;
match kind {
AggregateKind::Array(_) => {
let mut r = vec![];
@@ -1649,7 +1671,7 @@ impl<'db> Evaluator<'db> {
})
}
- fn compute_discriminant(&self, ty: Ty, bytes: &[u8]) -> Result<i128> {
+ fn compute_discriminant(&self, ty: Ty, bytes: &[u8]) -> Result<'db, i128> {
let interner = DbInterner::new_with(self.db, None, None);
let layout = self.layout(ty.to_nextsolver(interner))?;
let &TyKind::Adt(chalk_ir::AdtId(AdtId::EnumId(e)), _) = ty.kind(Interner) else {
@@ -1696,7 +1718,7 @@ impl<'db> Evaluator<'db> {
&self,
ty: &Ty,
goal: impl Fn(&TyKind) -> Option<T>,
- ) -> Result<T> {
+ ) -> Result<'db, T> {
let kind = ty.kind(Interner);
if let Some(it) = goal(kind) {
return Ok(it);
@@ -1719,7 +1741,7 @@ impl<'db> Evaluator<'db> {
addr: Interval,
current_ty: &Ty,
target_ty: &Ty,
- ) -> Result<IntervalOrOwned> {
+ ) -> Result<'db, IntervalOrOwned> {
fn for_ptr(it: &TyKind) -> Option<Ty> {
match it {
TyKind::Raw(_, ty) | TyKind::Ref(_, _, ty) => Some(ty.clone()),
@@ -1738,7 +1760,7 @@ impl<'db> Evaluator<'db> {
target_ty: Ty,
current_ty: Ty,
addr: Interval,
- ) -> Result<IntervalOrOwned> {
+ ) -> Result<'db, IntervalOrOwned> {
use IntervalOrOwned::*;
Ok(match &target_ty.kind(Interner) {
TyKind::Slice(_) => match &current_ty.kind(Interner) {
@@ -1806,7 +1828,7 @@ impl<'db> Evaluator<'db> {
it: VariantId,
subst: Substitution,
locals: &Locals,
- ) -> Result<(usize, Arc<Layout>, Option<(usize, usize, i128)>)> {
+ ) -> Result<'db, (usize, Arc<Layout>, Option<(usize, usize, i128)>)> {
let interner = DbInterner::new_with(self.db, None, None);
let adt = it.adt_id(self.db);
if let DefWithBodyId::VariantId(f) = locals.body.owner
@@ -1874,7 +1896,7 @@ impl<'db> Evaluator<'db> {
variant_layout: &Layout,
tag: Option<(usize, usize, i128)>,
values: impl Iterator<Item = IntervalOrOwned>,
- ) -> Result<Vec<u8>> {
+ ) -> Result<'db, Vec<u8>> {
let mut result = vec![0; size];
if let Some((offset, size, value)) = tag {
match result.get_mut(offset..offset + size) {
@@ -1904,7 +1926,7 @@ impl<'db> Evaluator<'db> {
Ok(result)
}
- fn eval_operand(&mut self, it: &Operand, locals: &mut Locals) -> Result<Interval> {
+ fn eval_operand(&mut self, it: &Operand, locals: &mut Locals) -> Result<'db, Interval> {
Ok(match &it.kind {
OperandKind::Copy(p) | OperandKind::Move(p) => {
locals.drop_flags.remove_place(p, &locals.body.projection_store);
@@ -1919,8 +1941,8 @@ impl<'db> Evaluator<'db> {
}
#[allow(clippy::double_parens)]
- fn allocate_const_in_heap(&mut self, locals: &Locals, konst: &Const) -> Result<Interval> {
- let interner = DbInterner::new_with(self.db, None, None);
+ fn allocate_const_in_heap(&mut self, locals: &Locals, konst: &Const) -> Result<'db, Interval> {
+ let interner = self.interner;
let ConstData { ty, value: chalk_ir::ConstValue::Concrete(c) } = &konst.data(Interner)
else {
not_supported!("evaluating non concrete constant");
@@ -1932,9 +1954,14 @@ impl<'db> Evaluator<'db> {
let mut const_id = *const_id;
let mut subst = subst.clone();
if let hir_def::GeneralConstId::ConstId(c) = const_id {
- let (c, s) = lookup_impl_const(self.db, self.trait_env.clone(), c, subst);
+ let (c, s) = lookup_impl_const(
+ self.interner,
+ self.trait_env.clone(),
+ c,
+ subst.to_nextsolver(self.interner),
+ );
const_id = hir_def::GeneralConstId::ConstId(c);
- subst = s;
+ subst = s.to_chalk(self.interner);
}
result_owner = self
.db
@@ -1987,7 +2014,7 @@ impl<'db> Evaluator<'db> {
Ok(Interval::new(addr, size))
}
- fn eval_place(&mut self, p: &Place, locals: &Locals) -> Result<Interval> {
+ fn eval_place(&mut self, p: &Place, locals: &Locals) -> Result<'db, Interval> {
let addr = self.place_addr(p, locals)?;
Ok(Interval::new(
addr,
@@ -1995,7 +2022,7 @@ impl<'db> Evaluator<'db> {
))
}
- fn read_memory(&self, addr: Address, size: usize) -> Result<&[u8]> {
+ fn read_memory(&self, addr: Address, size: usize) -> Result<'db, &[u8]> {
if size == 0 {
return Ok(&[]);
}
@@ -2012,7 +2039,7 @@ impl<'db> Evaluator<'db> {
.ok_or_else(|| MirEvalError::UndefinedBehavior("out of bound memory read".to_owned()))
}
- fn write_memory_using_ref(&mut self, addr: Address, size: usize) -> Result<&mut [u8]> {
+ fn write_memory_using_ref(&mut self, addr: Address, size: usize) -> Result<'db, &mut [u8]> {
let (mem, pos) = match addr {
Stack(it) => (&mut self.stack, it),
Heap(it) => (&mut self.heap, it),
@@ -2026,7 +2053,7 @@ impl<'db> Evaluator<'db> {
.ok_or_else(|| MirEvalError::UndefinedBehavior("out of bound memory write".to_owned()))
}
- fn write_memory(&mut self, addr: Address, r: &[u8]) -> Result<()> {
+ fn write_memory(&mut self, addr: Address, r: &[u8]) -> Result<'db, ()> {
if r.is_empty() {
return Ok(());
}
@@ -2034,14 +2061,18 @@ impl<'db> Evaluator<'db> {
Ok(())
}
- fn copy_from_interval_or_owned(&mut self, addr: Address, r: IntervalOrOwned) -> Result<()> {
+ fn copy_from_interval_or_owned(
+ &mut self,
+ addr: Address,
+ r: IntervalOrOwned,
+ ) -> Result<'db, ()> {
match r {
IntervalOrOwned::Borrowed(r) => self.copy_from_interval(addr, r),
IntervalOrOwned::Owned(r) => self.write_memory(addr, &r),
}
}
- fn copy_from_interval(&mut self, addr: Address, r: Interval) -> Result<()> {
+ fn copy_from_interval(&mut self, addr: Address, r: Interval) -> Result<'db, ()> {
if r.size == 0 {
return Ok(());
}
@@ -2083,7 +2114,7 @@ impl<'db> Evaluator<'db> {
Ok(())
}
- fn size_align_of(&self, ty: &Ty, locals: &Locals) -> Result<Option<(usize, usize)>> {
+ fn size_align_of(&self, ty: &Ty, locals: &Locals) -> Result<'db, Option<(usize, usize)>> {
let interner = DbInterner::new_with(self.db, None, None);
if let Some(layout) = self.layout_cache.borrow().get(&ty.to_nextsolver(interner)) {
return Ok(layout
@@ -2112,7 +2143,7 @@ impl<'db> Evaluator<'db> {
/// A version of `self.size_of` which returns error if the type is unsized. `what` argument should
/// be something that complete this: `error: type {ty} was unsized. {what} should be sized`
- fn size_of_sized(&self, ty: &Ty, locals: &Locals, what: &'static str) -> Result<usize> {
+ fn size_of_sized(&self, ty: &Ty, locals: &Locals, what: &'static str) -> Result<'db, usize> {
match self.size_align_of(ty, locals)? {
Some(it) => Ok(it.0),
None => Err(MirEvalError::TypeIsUnsized(ty.clone(), what)),
@@ -2126,14 +2157,14 @@ impl<'db> Evaluator<'db> {
ty: &Ty,
locals: &Locals,
what: &'static str,
- ) -> Result<(usize, usize)> {
+ ) -> Result<'db, (usize, usize)> {
match self.size_align_of(ty, locals)? {
Some(it) => Ok(it),
None => Err(MirEvalError::TypeIsUnsized(ty.clone(), what)),
}
}
- fn heap_allocate(&mut self, size: usize, align: usize) -> Result<Address> {
+ fn heap_allocate(&mut self, size: usize, align: usize) -> Result<'db, Address> {
if !align.is_power_of_two() || align > 10000 {
return Err(MirEvalError::UndefinedBehavior(format!("Alignment {align} is invalid")));
}
@@ -2166,7 +2197,7 @@ impl<'db> Evaluator<'db> {
bytes: &[u8],
ty: &Ty,
locals: &Locals,
- ) -> Result<ComplexMemoryMap<'db>> {
+ ) -> Result<'db, ComplexMemoryMap<'db>> {
fn rec<'db>(
this: &Evaluator<'db>,
bytes: &[u8],
@@ -2174,7 +2205,7 @@ impl<'db> Evaluator<'db> {
locals: &Locals,
mm: &mut ComplexMemoryMap<'db>,
stack_depth_limit: usize,
- ) -> Result<()> {
+ ) -> Result<'db, ()> {
let interner = DbInterner::new_with(this.db, None, None);
if stack_depth_limit.checked_sub(1).is_none() {
return Err(MirEvalError::StackOverflow);
@@ -2333,11 +2364,11 @@ impl<'db> Evaluator<'db> {
fn patch_addresses(
&mut self,
patch_map: &FxHashMap<usize, usize>,
- ty_of_bytes: impl Fn(&[u8]) -> Result<crate::next_solver::Ty<'db>> + Copy,
+ ty_of_bytes: impl Fn(&[u8]) -> Result<'db, crate::next_solver::Ty<'db>> + Copy,
addr: Address,
ty: crate::next_solver::Ty<'db>,
locals: &Locals,
- ) -> Result<()> {
+ ) -> Result<'db, ()> {
let interner = DbInterner::new_with(self.db, None, None);
// FIXME: support indirect references
let layout = self.layout(ty)?;
@@ -2469,7 +2500,7 @@ impl<'db> Evaluator<'db> {
locals: &Locals,
target_bb: Option<BasicBlockId>,
span: MirSpan,
- ) -> Result<Option<StackFrame>> {
+ ) -> Result<'db, Option<StackFrame>> {
let id = from_bytes!(usize, bytes.get(self)?);
let next_ty = self.vtable_map.ty(id)?;
let interner = DbInterner::new_with(self.db, None, None);
@@ -2506,7 +2537,7 @@ impl<'db> Evaluator<'db> {
args: &[IntervalAndTy],
locals: &Locals,
span: MirSpan,
- ) -> Result<Option<StackFrame>> {
+ ) -> Result<'db, Option<StackFrame>> {
let mir_body = self
.db
.monomorphized_mir_body_for_closure(
@@ -2523,7 +2554,7 @@ impl<'db> Evaluator<'db> {
};
let arg_bytes = iter::once(Ok(closure_data))
.chain(args.iter().map(|it| Ok(it.get(self)?.to_owned())))
- .collect::<Result<Vec<_>>>()?;
+ .collect::<Result<'db, Vec<_>>>()?;
let interval = self
.interpret_mir(mir_body, arg_bytes.into_iter().map(IntervalOrOwned::Owned))
.map_err(|e| {
@@ -2545,7 +2576,7 @@ impl<'db> Evaluator<'db> {
locals: &Locals,
target_bb: Option<BasicBlockId>,
span: MirSpan,
- ) -> Result<Option<StackFrame>> {
+ ) -> Result<'db, Option<StackFrame>> {
let generic_args = generic_args.clone();
match def {
CallableDefId::FunctionId(def) => {
@@ -2603,23 +2634,33 @@ impl<'db> Evaluator<'db> {
generic_args: Substitution,
locals: &Locals,
span: MirSpan,
- ) -> Result<MirOrDynIndex> {
+ ) -> Result<'db, MirOrDynIndex> {
let pair = (def, generic_args);
if let Some(r) = self.mir_or_dyn_index_cache.borrow().get(&pair) {
return Ok(r.clone());
}
let (def, generic_args) = pair;
- let r = if let Some(self_ty_idx) =
- is_dyn_method(self.db, self.trait_env.clone(), def, generic_args.clone())
- {
+ let r = if let Some(self_ty_idx) = is_dyn_method(
+ self.interner,
+ self.trait_env.clone(),
+ def,
+ generic_args.to_nextsolver(self.interner),
+ ) {
MirOrDynIndex::Dyn(self_ty_idx)
} else {
- let (imp, generic_args) =
- self.db.lookup_impl_method(self.trait_env.clone(), def, generic_args.clone());
+ let (imp, generic_args) = self.db.lookup_impl_method(
+ self.trait_env.clone(),
+ def,
+ generic_args.to_nextsolver(self.interner),
+ );
let mir_body = self
.db
- .monomorphized_mir_body(imp.into(), generic_args, self.trait_env.clone())
+ .monomorphized_mir_body(
+ imp.into(),
+ generic_args.to_chalk(self.interner),
+ self.trait_env.clone(),
+ )
.map_err(|e| {
MirEvalError::InFunction(
Box::new(MirEvalError::MirLowerError(imp, e)),
@@ -2641,7 +2682,7 @@ impl<'db> Evaluator<'db> {
destination: Interval,
target_bb: Option<BasicBlockId>,
span: MirSpan,
- ) -> Result<Option<StackFrame>> {
+ ) -> Result<'db, Option<StackFrame>> {
let interner = DbInterner::new_with(self.db, None, None);
if self.detect_and_exec_special_function(
def,
@@ -2713,7 +2754,7 @@ impl<'db> Evaluator<'db> {
span: MirSpan,
destination: Interval,
target_bb: Option<BasicBlockId>,
- ) -> Result<Option<StackFrame>> {
+ ) -> Result<'db, Option<StackFrame>> {
Ok(if let Some(target_bb) = target_bb {
let (mut locals, prev_stack_ptr) =
self.create_locals_for_body(&mir_body, Some(destination))?;
@@ -2741,7 +2782,7 @@ impl<'db> Evaluator<'db> {
destination: Interval,
target_bb: Option<BasicBlockId>,
span: MirSpan,
- ) -> Result<Option<StackFrame>> {
+ ) -> Result<'db, Option<StackFrame>> {
let interner = DbInterner::new_with(self.db, None, None);
let func = args
.first()
@@ -2817,7 +2858,7 @@ impl<'db> Evaluator<'db> {
}
}
- fn eval_static(&mut self, st: StaticId, locals: &Locals) -> Result<Address> {
+ fn eval_static(&mut self, st: StaticId, locals: &Locals) -> Result<'db, Address> {
if let Some(o) = self.static_locations.get(&st) {
return Ok(*o);
};
@@ -2828,8 +2869,9 @@ impl<'db> Evaluator<'db> {
})?;
self.allocate_const_in_heap(locals, &konst)?
} else {
- let ty = &self.db.infer(st.into())[self.db.body(st.into()).body_expr];
- let Some((size, align)) = self.size_align_of(ty, locals)? else {
+ let ty =
+ self.db.infer(st.into())[self.db.body(st.into()).body_expr].to_chalk(self.interner);
+ let Some((size, align)) = self.size_align_of(&ty, locals)? else {
not_supported!("unsized extern static");
};
let addr = self.heap_allocate(size, align)?;
@@ -2841,7 +2883,7 @@ impl<'db> Evaluator<'db> {
Ok(addr)
}
- fn const_eval_discriminant(&self, variant: EnumVariantId) -> Result<i128> {
+ fn const_eval_discriminant(&self, variant: EnumVariantId) -> Result<'db, i128> {
let r = self.db.const_eval_discriminant(variant);
match r {
Ok(r) => Ok(r),
@@ -2863,7 +2905,7 @@ impl<'db> Evaluator<'db> {
}
}
- fn drop_place(&mut self, place: &Place, locals: &mut Locals, span: MirSpan) -> Result<()> {
+ fn drop_place(&mut self, place: &Place, locals: &mut Locals, span: MirSpan) -> Result<'db, ()> {
let (addr, ty, metadata) = self.place_addr_and_ty_and_metadata(place, locals)?;
if !locals.drop_flags.remove_place(place, &locals.body.projection_store) {
return Ok(());
@@ -2882,7 +2924,7 @@ impl<'db> Evaluator<'db> {
addr: Address,
_metadata: &[u8],
span: MirSpan,
- ) -> Result<()> {
+ ) -> Result<'db, ()> {
let Some(drop_fn) = (|| {
let drop_trait = LangItem::Drop.resolve_trait(self.db, self.crate_id)?;
drop_trait.trait_items(self.db).method_by_name(&Name::new_symbol_root(sym::drop))
@@ -2962,22 +3004,22 @@ impl<'db> Evaluator<'db> {
Ok(())
}
- fn write_to_stdout(&mut self, interval: Interval) -> Result<()> {
+ fn write_to_stdout(&mut self, interval: Interval) -> Result<'db, ()> {
self.stdout.extend(interval.get(self)?.to_vec());
Ok(())
}
- fn write_to_stderr(&mut self, interval: Interval) -> Result<()> {
+ fn write_to_stderr(&mut self, interval: Interval) -> Result<'db, ()> {
self.stderr.extend(interval.get(self)?.to_vec());
Ok(())
}
}
-pub fn render_const_using_debug_impl(
- db: &dyn HirDatabase,
+pub fn render_const_using_debug_impl<'db>(
+ db: &'db dyn HirDatabase,
owner: DefWithBodyId,
c: &Const,
-) -> Result<String> {
+) -> Result<'db, String> {
let interner = DbInterner::new_with(db, None, None);
let mut evaluator = Evaluator::new(db, owner, false, None)?;
let locals = &Locals {