Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/mir.rs')
-rw-r--r--crates/hir-ty/src/mir.rs71
1 files changed, 48 insertions, 23 deletions
diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs
index fef0077119..4846bbfe5f 100644
--- a/crates/hir-ty/src/mir.rs
+++ b/crates/hir-ty/src/mir.rs
@@ -3,13 +3,14 @@
use std::{fmt::Display, iter};
use crate::{
- db::HirDatabase, display::HirDisplay, infer::PointerCast, lang_items::is_box, ClosureId, Const,
- ConstScalar, InferenceResult, Interner, MemoryMap, Substitution, Ty, TyKind,
+ db::HirDatabase, display::HirDisplay, infer::PointerCast, lang_items::is_box, mapping::ToChalk,
+ CallableDefId, ClosureId, Const, ConstScalar, InferenceResult, Interner, MemoryMap,
+ Substitution, Ty, TyKind,
};
use chalk_ir::Mutability;
use hir_def::{
hir::{BindingId, Expr, ExprId, Ordering, PatId},
- DefWithBodyId, FieldId, UnionId, VariantId,
+ DefWithBodyId, FieldId, StaticId, UnionId, VariantId,
};
use la_arena::{Arena, ArenaMap, Idx, RawIdx};
@@ -19,7 +20,7 @@ mod borrowck;
mod pretty;
pub use borrowck::{borrowck_query, BorrowckResult, MutabilityReason};
-pub use eval::{interpret_mir, pad16, Evaluator, MirEvalError};
+pub use eval::{interpret_mir, pad16, Evaluator, MirEvalError, VTableMap};
pub use lower::{
lower_to_mir, mir_body_for_closure_query, mir_body_query, mir_body_recover, MirLowerError,
};
@@ -76,6 +77,9 @@ pub enum Operand {
Move(Place),
/// Constants are already semantically values, and remain unchanged.
Constant(Const),
+ /// NON STANDARD: This kind of operand returns an immutable reference to that static memory. Rustc
+ /// handles it with the `Constant` variant somehow.
+ Static(StaticId),
}
impl Operand {
@@ -90,6 +94,17 @@ impl Operand {
fn const_zst(ty: Ty) -> Operand {
Self::from_bytes(vec![], ty)
}
+
+ fn from_fn(
+ db: &dyn HirDatabase,
+ func_id: hir_def::FunctionId,
+ generic_args: Substitution,
+ ) -> Operand {
+ let ty =
+ chalk_ir::TyKind::FnDef(CallableDefId::FunctionId(func_id).to_chalk(db), generic_args)
+ .intern(Interner);
+ Operand::from_bytes(vec![], ty)
+ }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -110,7 +125,7 @@ impl<V, T> ProjectionElem<V, T> {
&self,
base: Ty,
db: &dyn HirDatabase,
- closure_field: impl FnOnce(ClosureId, usize) -> Ty,
+ closure_field: impl FnOnce(ClosureId, &Substitution, usize) -> Ty,
) -> Ty {
match self {
ProjectionElem::Deref => match &base.data(Interner).kind {
@@ -142,7 +157,7 @@ impl<V, T> ProjectionElem<V, T> {
never!("Out of bound tuple field");
TyKind::Error.intern(Interner)
}),
- TyKind::Closure(id, _) => closure_field(*id, *f),
+ TyKind::Closure(id, subst) => closure_field(*id, subst, *f),
_ => {
never!("Only tuple or closure has tuple or closure field");
return TyKind::Error.intern(Interner);
@@ -261,7 +276,13 @@ impl SwitchTargets {
}
#[derive(Debug, PartialEq, Eq, Clone)]
-pub enum Terminator {
+pub struct Terminator {
+ span: MirSpan,
+ kind: TerminatorKind,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub enum TerminatorKind {
/// Block has one successor; we continue execution there.
Goto { target: BasicBlockId },
@@ -836,6 +857,9 @@ pub enum Rvalue {
/// affects alias analysis.
ShallowInitBox(Operand, Ty),
+ /// NON STANDARD: allocates memory with the type's layout, and shallow init the box with the resulting pointer.
+ ShallowInitBoxWithAlloc(Ty),
+
/// A CopyForDeref is equivalent to a read from a place at the
/// codegen level, but is treated specially by drop elaboration. When such a read happens, it
/// is guaranteed (via nature of the mir_opt `Derefer` in rustc_mir_transform/src/deref_separator)
@@ -918,7 +942,7 @@ impl MirBody {
Operand::Copy(p) | Operand::Move(p) => {
f(p);
}
- Operand::Constant(_) => (),
+ Operand::Constant(_) | Operand::Static(_) => (),
}
}
for (_, block) in self.basic_blocks.iter_mut() {
@@ -927,6 +951,7 @@ impl MirBody {
StatementKind::Assign(p, r) => {
f(p);
match r {
+ Rvalue::ShallowInitBoxWithAlloc(_) => (),
Rvalue::ShallowInitBox(o, _)
| Rvalue::UnaryOp(_, o)
| Rvalue::Cast(_, o, _)
@@ -954,32 +979,32 @@ impl MirBody {
}
}
match &mut block.terminator {
- Some(x) => match x {
- Terminator::SwitchInt { discr, .. } => for_operand(discr, &mut f),
- Terminator::FalseEdge { .. }
- | Terminator::FalseUnwind { .. }
- | Terminator::Goto { .. }
- | Terminator::Resume
- | Terminator::GeneratorDrop
- | Terminator::Abort
- | Terminator::Return
- | Terminator::Unreachable => (),
- Terminator::Drop { place, .. } => {
+ Some(x) => match &mut x.kind {
+ TerminatorKind::SwitchInt { discr, .. } => for_operand(discr, &mut f),
+ TerminatorKind::FalseEdge { .. }
+ | TerminatorKind::FalseUnwind { .. }
+ | TerminatorKind::Goto { .. }
+ | TerminatorKind::Resume
+ | TerminatorKind::GeneratorDrop
+ | TerminatorKind::Abort
+ | TerminatorKind::Return
+ | TerminatorKind::Unreachable => (),
+ TerminatorKind::Drop { place, .. } => {
f(place);
}
- Terminator::DropAndReplace { place, value, .. } => {
+ TerminatorKind::DropAndReplace { place, value, .. } => {
f(place);
for_operand(value, &mut f);
}
- Terminator::Call { func, args, destination, .. } => {
+ TerminatorKind::Call { func, args, destination, .. } => {
for_operand(func, &mut f);
args.iter_mut().for_each(|x| for_operand(x, &mut f));
f(destination);
}
- Terminator::Assert { cond, .. } => {
+ TerminatorKind::Assert { cond, .. } => {
for_operand(cond, &mut f);
}
- Terminator::Yield { value, resume_arg, .. } => {
+ TerminatorKind::Yield { value, resume_arg, .. } => {
for_operand(value, &mut f);
f(resume_arg);
}