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.rs62
1 files changed, 34 insertions, 28 deletions
diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs
index a8865cd54e..a8e06f3a2b 100644
--- a/crates/hir-ty/src/mir.rs
+++ b/crates/hir-ty/src/mir.rs
@@ -6,8 +6,7 @@ use base_db::Crate;
use either::Either;
use hir_def::{
DefWithBodyId, FieldId, StaticId, TupleFieldId, UnionId, VariantId,
- expr_store::ExpressionStore,
- hir::{BindingAnnotation, BindingId, Expr, ExprId, Ordering, PatId},
+ hir::{BindingId, Expr, ExprId, Ordering, PatId},
};
use la_arena::{Arena, ArenaMap, Idx, RawIdx};
use rustc_ast_ir::Mutability;
@@ -23,8 +22,8 @@ use crate::{
display::{DisplayTarget, HirDisplay},
infer::PointerCast,
next_solver::{
- Const, DbInterner, ErrorGuaranteed, GenericArgs, ParamEnv, StoredConst, StoredGenericArgs,
- StoredTy, Ty, TyKind,
+ Allocation, AllocationData, DbInterner, ErrorGuaranteed, GenericArgs, ParamEnv,
+ StoredAllocation, StoredConst, StoredGenericArgs, StoredTy, Ty, TyKind,
infer::{InferCtxt, traits::ObligationCause},
obligation_ctxt::ObligationCtxt,
},
@@ -107,7 +106,13 @@ pub enum OperandKind {
/// [UCG#188]: https://github.com/rust-lang/unsafe-code-guidelines/issues/188
Move(Place),
/// Constants are already semantically values, and remain unchanged.
- Constant { konst: StoredConst, ty: StoredTy },
+ Constant {
+ konst: StoredConst,
+ ty: StoredTy,
+ },
+ Allocation {
+ allocation: StoredAllocation,
+ },
/// NON STANDARD: This kind of operand returns an immutable reference to that static memory. Rustc
/// handles it with the `Constant` variant somehow.
Static(StaticId),
@@ -115,11 +120,10 @@ pub enum OperandKind {
impl<'db> Operand {
fn from_concrete_const(data: Box<[u8]>, memory_map: MemoryMap<'db>, ty: Ty<'db>) -> Self {
- let interner = DbInterner::conjure();
Operand {
- kind: OperandKind::Constant {
- konst: Const::new_valtree(interner, ty, data, memory_map).store(),
- ty: ty.store(),
+ kind: OperandKind::Allocation {
+ allocation: Allocation::new(AllocationData { ty, memory: data, memory_map })
+ .store(),
},
span: None,
}
@@ -163,7 +167,6 @@ impl<V: PartialEq> ProjectionElem<V> {
infcx: &InferCtxt<'db>,
env: ParamEnv<'db>,
mut base: Ty<'db>,
- closure_field: impl FnOnce(InternedClosureId, GenericArgs<'db>, usize) -> Ty<'db>,
krate: Crate,
) -> Ty<'db> {
let interner = infcx.interner;
@@ -218,7 +221,7 @@ impl<V: PartialEq> ProjectionElem<V> {
}
},
ProjectionElem::ClosureField(f) => match base.kind() {
- TyKind::Closure(id, subst) => closure_field(id.0, subst, *f),
+ TyKind::Closure(_, args) => args.as_closure().tupled_upvars_ty().tuple_fields()[*f],
_ => {
never!("Only closure has closure field");
Ty::new_error(interner, ErrorGuaranteed)
@@ -706,19 +709,31 @@ pub enum MutBorrowKind {
}
impl BorrowKind {
- fn from_hir(m: hir_def::type_ref::Mutability) -> Self {
+ fn from_hir_mutability(m: hir_def::type_ref::Mutability) -> Self {
match m {
hir_def::type_ref::Mutability::Shared => BorrowKind::Shared,
hir_def::type_ref::Mutability::Mut => BorrowKind::Mut { kind: MutBorrowKind::Default },
}
}
- fn from_rustc(m: rustc_ast_ir::Mutability) -> Self {
+ fn from_rustc_mutability(m: rustc_ast_ir::Mutability) -> Self {
match m {
rustc_ast_ir::Mutability::Not => BorrowKind::Shared,
rustc_ast_ir::Mutability::Mut => BorrowKind::Mut { kind: MutBorrowKind::Default },
}
}
+
+ fn from_hir(bk: crate::infer::closure::analysis::BorrowKind) -> Self {
+ match bk {
+ crate::closure_analysis::BorrowKind::Immutable => Self::Shared,
+ crate::closure_analysis::BorrowKind::UniqueImmutable => {
+ Self::Mut { kind: MutBorrowKind::ClosureCapture }
+ }
+ crate::closure_analysis::BorrowKind::Mutable => {
+ Self::Mut { kind: MutBorrowKind::Default }
+ }
+ }
+ }
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -1074,6 +1089,7 @@ pub struct MirBody {
pub start_block: BasicBlockId,
pub owner: DefWithBodyId,
pub binding_locals: ArenaMap<BindingId, LocalId>,
+ pub upvar_locals: FxHashMap<BindingId, Vec<(LocalId, crate::closure_analysis::Place)>>,
pub param_locals: Vec<LocalId>,
/// This field stores the closures directly owned by this body. It is used
/// in traversing every mir body.
@@ -1095,7 +1111,9 @@ impl MirBody {
OperandKind::Copy(p) | OperandKind::Move(p) => {
f(p, store);
}
- OperandKind::Constant { .. } | OperandKind::Static(_) => (),
+ OperandKind::Constant { .. }
+ | OperandKind::Static(_)
+ | OperandKind::Allocation { .. } => (),
}
}
for (_, block) in self.basic_blocks.iter_mut() {
@@ -1183,6 +1201,7 @@ impl MirBody {
start_block: _,
owner: _,
binding_locals,
+ upvar_locals,
param_locals,
closures,
projection_store,
@@ -1191,6 +1210,7 @@ impl MirBody {
basic_blocks.shrink_to_fit();
locals.shrink_to_fit();
binding_locals.shrink_to_fit();
+ upvar_locals.shrink_to_fit();
param_locals.shrink_to_fit();
closures.shrink_to_fit();
for (_, b) in basic_blocks.iter_mut() {
@@ -1208,20 +1228,6 @@ pub enum MirSpan {
SelfParam,
Unknown,
}
-
-impl MirSpan {
- pub fn is_ref_span(&self, store: &ExpressionStore) -> bool {
- match *self {
- MirSpan::ExprId(expr) => matches!(store[expr], Expr::Ref { .. }),
- // FIXME: Figure out if this is correct wrt. match ergonomics.
- MirSpan::BindingId(binding) => {
- matches!(store[binding].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut)
- }
- MirSpan::PatId(_) | MirSpan::SelfParam | MirSpan::Unknown => false,
- }
- }
-}
-
impl_from!(ExprId, PatId for MirSpan);
impl From<&ExprId> for MirSpan {