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.rs67
1 files changed, 34 insertions, 33 deletions
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 3372f6ec2e..78b70edeee 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -56,7 +56,7 @@ use crate::{
use super::{
AggregateKind, BasicBlockId, BinOp, CastKind, LocalId, MirBody, MirLowerError, MirSpan,
- Operand, OperandKind, Place, PlaceElem, ProjectionElem, ProjectionStore, Rvalue, StatementKind,
+ Operand, OperandKind, Place, PlaceElem, PlaceRef, ProjectionElem, Rvalue, StatementKind,
TerminatorKind, UnOp, return_slot,
};
@@ -567,26 +567,26 @@ impl std::fmt::Debug for MirEvalError {
type Result<'db, T> = std::result::Result<T, MirEvalError>;
#[derive(Debug, Default)]
-struct DropFlags {
- need_drop: FxHashSet<Place>,
+struct DropFlags<'db> {
+ need_drop: FxHashSet<PlaceRef<'db>>,
}
-impl DropFlags {
- fn add_place(&mut self, p: Place, store: &ProjectionStore) {
- if p.iterate_over_parents(store).any(|it| self.need_drop.contains(&it)) {
+impl<'db> DropFlags<'db> {
+ fn add_place(&mut self, p: PlaceRef<'db>) {
+ if p.iterate_over_parents().any(|it| self.need_drop.contains(&it)) {
return;
}
- self.need_drop.retain(|it| !p.is_parent(it, store));
+ self.need_drop.retain(|it| !p.is_parent(*it));
self.need_drop.insert(p);
}
- fn remove_place(&mut self, p: &Place, store: &ProjectionStore) -> bool {
+ fn remove_place(&mut self, p: PlaceRef<'db>) -> bool {
// FIXME: replace parents with parts
- if let Some(parent) = p.iterate_over_parents(store).find(|it| self.need_drop.contains(it)) {
+ if let Some(parent) = p.iterate_over_parents().find(|it| self.need_drop.contains(it)) {
self.need_drop.remove(&parent);
return true;
}
- self.need_drop.remove(p)
+ self.need_drop.remove(&p)
}
fn clear(&mut self) {
@@ -598,7 +598,7 @@ impl DropFlags {
struct Locals<'a> {
ptr: ArenaMap<LocalId, Interval>,
body: &'a MirBody,
- drop_flags: DropFlags,
+ drop_flags: DropFlags<'a>,
}
pub struct MirOutput {
@@ -685,7 +685,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
db,
random_state: oorandom::Rand64::new(0),
param_env: trait_env.unwrap_or_else(|| ParamEnvAndCrate {
- param_env: db.trait_environment(owner.expression_store_owner(db)),
+ param_env: db.trait_environment(owner.generic_def(db)),
krate: crate_id,
}),
crate_id,
@@ -757,9 +757,9 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
let mut addr = locals.ptr[p.local].addr;
let mut ty: Ty<'db> = locals.body.locals[p.local].ty.as_ref();
let mut metadata: Option<IntervalOrOwned> = None; // locals are always sized
- for proj in p.projection.lookup(&locals.body.projection_store) {
+ for proj in p.projection.lookup() {
let prev_ty = ty;
- ty = self.projected_ty(ty, proj.clone());
+ ty = self.projected_ty(ty, *proj);
match proj {
ProjectionElem::Deref => {
metadata = if self.size_align_of(ty, locals)?.is_none() {
@@ -844,7 +844,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
Variants::Multiple { variants, .. } => {
&variants[match f.parent {
hir_def::VariantId::EnumVariantId(it) => {
- RustcEnumVariantIdx(it.lookup(self.db).index as usize)
+ RustcEnumVariantIdx(it.index(self.db))
}
_ => {
return Err(MirEvalError::InternalError(
@@ -955,7 +955,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
let addr = self.place_addr(l, locals)?;
let result = self.eval_rvalue(r, locals)?;
self.copy_from_interval_or_owned(addr, result)?;
- locals.drop_flags.add_place(*l, &locals.body.projection_store);
+ locals.drop_flags.add_place(l.as_ref());
}
StatementKind::Deinit(_) => not_supported!("de-init statement"),
StatementKind::StorageLive(_)
@@ -1008,9 +1008,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
)?,
it => not_supported!("unknown function type {it:?}"),
};
- locals
- .drop_flags
- .add_place(*destination, &locals.body.projection_store);
+ locals.drop_flags.add_place(destination.as_ref());
if let Some(stack_frame) = stack_frame {
self.code_stack.push(my_stack_frame);
current_block_idx = stack_frame.locals.body.start_block;
@@ -1091,7 +1089,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
) -> 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);
+ locals.drop_flags.add_place(l.into());
match value {
IntervalOrOwned::Owned(value) => interval.write_from_bytes(self, &value)?,
IntervalOrOwned::Borrowed(value) => interval.write_from_interval(self, value)?,
@@ -1594,7 +1592,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
let max = 1i128 << (dest_bits - 1);
(max - 1, -max)
} else {
- (1i128 << dest_bits, 0)
+ ((1i128 << dest_bits) - 1, 0)
};
let value = (value as i128).min(max).max(min);
let result = value.to_le_bytes();
@@ -1709,15 +1707,19 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
if let Some(it) = goal(kind) {
return Ok(it);
}
- if let TyKind::Adt(adt_ef, subst) = kind
- && let AdtId::StructId(struct_id) = adt_ef.def_id()
- {
- let field_types = self.db.field_types(struct_id.into());
- if let Some(ty) =
- field_types.iter().last().map(|it| it.1.get().instantiate(self.interner(), subst))
- {
- return self.coerce_unsized_look_through_fields(ty.skip_norm_wip(), goal);
+ match kind {
+ TyKind::Adt(adt_ef, subst) if let AdtId::StructId(struct_id) = adt_ef.def_id() => {
+ let field_types = self.db.field_types(struct_id.into());
+ if let Some(ty) = field_types
+ .iter()
+ .last()
+ .map(|it| it.1.get().instantiate(self.interner(), subst))
+ {
+ return self.coerce_unsized_look_through_fields(ty.skip_norm_wip(), goal);
+ }
}
+ TyKind::Pat(ty, _) => return self.coerce_unsized_look_through_fields(ty, goal),
+ _ => (),
}
Err(MirEvalError::CoerceUnsizedError(ty.store()))
}
@@ -1837,8 +1839,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
_ => not_supported!("multi variant layout for non-enums"),
};
let mut discriminant = self.const_eval_discriminant(enum_variant_id)?;
- let lookup = enum_variant_id.lookup(self.db);
- let rustc_enum_variant_idx = RustcEnumVariantIdx(lookup.index as usize);
+ let rustc_enum_variant_idx = RustcEnumVariantIdx(enum_variant_id.index(self.db));
let variant_layout = variants[rustc_enum_variant_idx].clone();
let have_tag = match tag_encoding {
TagEncoding::Direct => true,
@@ -1912,7 +1913,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
fn eval_operand(&mut self, it: &Operand, locals: &mut Locals<'a>) -> Result<'db, Interval> {
Ok(match &it.kind {
OperandKind::Copy(p) | OperandKind::Move(p) => {
- locals.drop_flags.remove_place(p, &locals.body.projection_store);
+ locals.drop_flags.remove_place(p.as_ref());
self.eval_place(p, locals)?
}
OperandKind::Static(st) => {
@@ -3033,7 +3034,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
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) {
+ if !locals.drop_flags.remove_place(place.as_ref()) {
return Ok(());
}
let metadata = match metadata {