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.rs55
1 files changed, 21 insertions, 34 deletions
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 78b70edeee..f0e2218cde 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -56,8 +56,8 @@ use crate::{
use super::{
AggregateKind, BasicBlockId, BinOp, CastKind, LocalId, MirBody, MirLowerError, MirSpan,
- Operand, OperandKind, Place, PlaceElem, PlaceRef, ProjectionElem, Rvalue, StatementKind,
- TerminatorKind, UnOp, return_slot,
+ Operand, OperandKind, Place, PlaceElem, PlaceRef, PlaceTy, ProjectionElem, Rvalue,
+ StatementKind, TerminatorKind, UnOp, return_slot,
};
mod shim;
@@ -187,7 +187,7 @@ pub struct Evaluator<'a, 'db> {
stdout: Vec<u8>,
stderr: Vec<u8>,
layout_cache: RefCell<FxHashMap<Ty<'db>, Arc<Layout>>>,
- projected_ty_cache: RefCell<FxHashMap<(Ty<'db>, PlaceElem), Ty<'db>>>,
+ projected_ty_cache: RefCell<FxHashMap<(PlaceTy<'db>, PlaceElem), PlaceTy<'db>>>,
not_special_fn_cache: RefCell<FxHashSet<FunctionId>>,
mir_or_dyn_index_cache: RefCell<FxHashMap<(FunctionId, GenericArgs<'db>), MirOrDynIndex<'a>>>,
/// Constantly dropping and creating `Locals` is very costly. We store
@@ -738,13 +738,13 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
self.cached_ptr_size
}
- fn projected_ty(&self, ty: Ty<'db>, proj: PlaceElem) -> Ty<'db> {
+ fn projected_ty(&self, ty: PlaceTy<'db>, proj: PlaceElem) -> PlaceTy<'db> {
let pair = (ty, proj);
if let Some(r) = self.projected_ty_cache.borrow().get(&pair) {
return *r;
}
let (ty, proj) = pair;
- let r = proj.projected_ty(&self.infcx, self.param_env.param_env, ty, self.crate_id);
+ let r = ty.projection_ty(&self.infcx, &proj, self.param_env.param_env);
self.projected_ty_cache.borrow_mut().insert((ty, proj), r);
r
}
@@ -755,14 +755,14 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
locals: &'b Locals<'a>,
) -> Result<'db, (Address, Ty<'db>, Option<IntervalOrOwned>)> {
let mut addr = locals.ptr[p.local].addr;
- let mut ty: Ty<'db> = locals.body.locals[p.local].ty.as_ref();
+ let mut ty = PlaceTy::from_ty(locals.body.locals[p.local].ty.as_ref());
let mut metadata: Option<IntervalOrOwned> = None; // locals are always sized
for proj in p.projection.lookup() {
let prev_ty = ty;
ty = self.projected_ty(ty, *proj);
match proj {
ProjectionElem::Deref => {
- metadata = if self.size_align_of(ty, locals)?.is_none() {
+ metadata = if self.size_align_of(ty.ty, locals)?.is_none() {
Some(
Interval { addr: addr.offset(self.ptr_size()), size: self.ptr_size() }
.into(),
@@ -780,12 +780,12 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
);
metadata = None; // Result of index is always sized
let ty_size =
- self.size_of_sized(ty, locals, "array inner type should be sized")?;
+ self.size_of_sized(ty.ty, locals, "array inner type should be sized")?;
addr = addr.offset(ty_size * offset);
}
&ProjectionElem::ConstantIndex { from_end, offset } => {
let offset = if from_end {
- let len = match prev_ty.kind() {
+ let len = match prev_ty.ty.kind() {
TyKind::Array(_, c) => match try_const_usize(self.db, c) {
Some(it) => it as u64,
None => {
@@ -804,11 +804,11 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
};
metadata = None; // Result of index is always sized
let ty_size =
- self.size_of_sized(ty, locals, "array inner type should be sized")?;
+ self.size_of_sized(ty.ty, locals, "array inner type should be sized")?;
addr = addr.offset(ty_size * offset);
}
&ProjectionElem::Subslice { from, to } => {
- let inner_ty = match ty.kind() {
+ let inner_ty = match ty.ty.kind() {
TyKind::Array(inner, _) | TyKind::Slice(inner) => inner,
_ => Ty::new_error(self.interner(), ErrorGuaranteed),
};
@@ -825,25 +825,13 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
self.size_of_sized(inner_ty, locals, "array inner type should be sized")?;
addr = addr.offset(ty_size * (from as usize));
}
- &ProjectionElem::ClosureField(f) => {
- let layout = self.layout(prev_ty)?;
- let offset = layout.fields.offset(f).bytes_usize();
- addr = addr.offset(offset);
- metadata = None;
- }
- ProjectionElem::Field(Either::Right(f)) => {
- let layout = self.layout(prev_ty)?;
- let offset = layout.fields.offset(f.index as usize).bytes_usize();
- addr = addr.offset(offset);
- metadata = None; // tuple field is always sized FIXME: This is wrong, the tail can be unsized
- }
- ProjectionElem::Field(Either::Left(f)) => {
- let layout = self.layout(prev_ty)?;
+ ProjectionElem::Field(f) => {
+ let layout = self.layout(prev_ty.ty)?;
let variant_layout = match &layout.variants {
Variants::Single { .. } | Variants::Empty => &layout,
Variants::Multiple { variants, .. } => {
- &variants[match f.parent {
- hir_def::VariantId::EnumVariantId(it) => {
+ &variants[match prev_ty.variant_id {
+ Some(hir_def::VariantId::EnumVariantId(it)) => {
RustcEnumVariantIdx(it.index(self.db))
}
_ => {
@@ -854,20 +842,19 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
}]
}
};
- let offset = variant_layout
- .fields
- .offset(u32::from(f.local_id.into_raw()) as usize)
- .bytes_usize();
+ let offset = variant_layout.fields.offset(f.0 as usize).bytes_usize();
addr = addr.offset(offset);
// Unsized field metadata is equal to the metadata of the struct
- if self.size_align_of(ty, locals)?.is_some() {
+ if self.size_align_of(ty.ty, locals)?.is_some() {
metadata = None;
}
}
- ProjectionElem::OpaqueCast(_) => not_supported!("opaque cast"),
+ ProjectionElem::Downcast(_) => {
+ // no runtime effect
+ }
}
}
- Ok((addr, ty, metadata))
+ Ok((addr, ty.ty, metadata))
}
fn layout(&self, ty: Ty<'db>) -> Result<'db, Arc<Layout>> {