Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/mir/lower.rs')
-rw-r--r--crates/hir-ty/src/mir/lower.rs182
1 files changed, 96 insertions, 86 deletions
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index 394cac8065..4e52c1f7c3 100644
--- a/crates/hir-ty/src/mir/lower.rs
+++ b/crates/hir-ty/src/mir/lower.rs
@@ -45,9 +45,9 @@ use crate::{
mir::{
AggregateKind, Arena, BasicBlock, BasicBlockId, BinOp, BorrowKind, CastKind, Either, Expr,
FieldId, GenericArgs, Idx, InferenceResult, Local, LocalId, MemoryMap, MirBody, MirSpan,
- Mutability, Operand, Place, PlaceElem, PointerCast, ProjectionElem, ProjectionStore,
- RawIdx, Rvalue, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind,
- TupleFieldId, Ty, UnOp, VariantId, return_slot,
+ Mutability, Operand, Place, PlaceElem, PointerCast, Projection, ProjectionElem, RawIdx,
+ Rvalue, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind, TupleFieldId,
+ Ty, UnOp, VariantId, return_slot,
},
next_solver::{
Const, DbInterner, ParamConst, ParamEnv, Region, StoredGenericArgs, StoredTy, TyKind,
@@ -57,7 +57,7 @@ use crate::{
},
};
-use super::OperandKind;
+use super::{OperandKind, PlaceRef};
mod as_place;
mod pattern_matching;
@@ -303,7 +303,6 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
let locals = Arena::new();
let binding_locals: ArenaMap<BindingId, LocalId> = ArenaMap::new();
let mir = MirBody {
- projection_store: ProjectionStore::default(),
basic_blocks,
locals,
start_block,
@@ -371,13 +370,16 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
let Some((p, current)) = self.lower_expr_as_place(current, expr_id, true)? else {
return Ok(None);
};
- Ok(Some((Operand { kind: OperandKind::Copy(p), span: Some(expr_id.into()) }, current)))
+ Ok(Some((
+ Operand { kind: OperandKind::Copy(p.store()), span: Some(expr_id.into()) },
+ current,
+ )))
}
fn lower_expr_to_place_with_adjust(
&mut self,
expr_id: ExprId,
- place: Place,
+ place: PlaceRef<'db>,
current: BasicBlockId,
adjustments: &[Adjustment],
) -> Result<'db, Option<BasicBlockId>> {
@@ -396,7 +398,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
self.push_assignment(
current,
place,
- Operand { kind: OperandKind::Copy(p), span: None }.into(),
+ Operand { kind: OperandKind::Copy(p.store()), span: None }.into(),
expr_id.into(),
);
Ok(Some(current))
@@ -422,7 +424,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
place,
Rvalue::Cast(
CastKind::PointerCoercion(*cast),
- Operand { kind: OperandKind::Copy(p), span: None },
+ Operand { kind: OperandKind::Copy(p.store()), span: None },
last.target.clone(),
),
expr_id.into(),
@@ -437,7 +439,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
fn lower_expr_to_place_with_borrow_adjust(
&mut self,
expr_id: ExprId,
- place: Place,
+ place: PlaceRef<'db>,
current: BasicBlockId,
rest: &[Adjustment],
m: Mutability,
@@ -448,14 +450,14 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
return Ok(None);
};
let bk = BorrowKind::from_rustc_mutability(m);
- self.push_assignment(current, place, Rvalue::Ref(bk, p), expr_id.into());
+ self.push_assignment(current, place, Rvalue::Ref(bk, p.store()), expr_id.into());
Ok(Some(current))
}
fn lower_expr_to_place(
&mut self,
expr_id: ExprId,
- place: Place,
+ place: PlaceRef<'db>,
prev_block: BasicBlockId,
) -> Result<'db, Option<BasicBlockId>> {
if let Some(adjustments) = self.infer.expr_adjustments.get(&expr_id) {
@@ -467,7 +469,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
fn lower_expr_to_place_without_adjust(
&mut self,
expr_id: ExprId,
- place: Place,
+ place: PlaceRef<'db>,
mut current: BasicBlockId,
) -> Result<'db, Option<BasicBlockId>> {
match &self.store[expr_id] {
@@ -535,7 +537,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
self.push_assignment(
current,
place,
- Operand { kind: OperandKind::Copy(temp), span: None }.into(),
+ Operand { kind: OperandKind::Copy(temp.store()), span: None }.into(),
expr_id.into(),
);
Ok(Some(current))
@@ -831,7 +833,9 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
.as_ref()
.ok_or(MirLowerError::BreakWithoutLoop)?,
};
- let Some(c) = self.lower_expr_to_place(expr, loop_data.place, current)? else {
+ let Some(c) =
+ self.lower_expr_to_place(expr, loop_data.place.as_ref(), current)?
+ else {
return Ok(None);
};
current = c;
@@ -921,16 +925,18 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
.map(|(i, it)| match it {
Some(it) => it,
None => {
- let p = sp.project(
- ProjectionElem::Field(Either::Left(FieldId {
+ let p = sp.project(ProjectionElem::Field(
+ Either::Left(FieldId {
parent: variant_id,
local_id: LocalFieldId::from_raw(RawIdx::from(
i as u32,
)),
- })),
- &mut self.result.projection_store,
- );
- Operand { kind: OperandKind::Copy(p), span: None }
+ }),
+ ));
+ Operand {
+ kind: OperandKind::Copy(p.store()),
+ span: None,
+ }
}
})
.collect(),
@@ -948,13 +954,10 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
};
let local_id =
variant_fields.field(name).ok_or(MirLowerError::UnresolvedField)?;
- let place = place.project(
- PlaceElem::Field(Either::Left(FieldId {
- parent: union_id.into(),
- local_id,
- })),
- &mut self.result.projection_store,
- );
+ let place = place.project(PlaceElem::Field(Either::Left(FieldId {
+ parent: union_id.into(),
+ local_id,
+ })));
self.lower_expr_to_place(*expr, place, current)
}
}
@@ -1001,7 +1004,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
return Ok(None);
};
let bk = BorrowKind::from_hir_mutability(*mutability);
- self.push_assignment(current, place, Rvalue::Ref(bk, p), expr_id.into());
+ self.push_assignment(current, place, Rvalue::Ref(bk, p.store()), expr_id.into());
Ok(Some(current))
}
Expr::Box { expr } => {
@@ -1016,7 +1019,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
else {
return Ok(None);
};
- let p = place.project(ProjectionElem::Deref, &mut self.result.projection_store);
+ let p = place.project(ProjectionElem::Deref);
self.push_assignment(current, p, operand.into(), expr_id.into());
Ok(Some(current))
}
@@ -1031,7 +1034,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
self.push_assignment(
current,
place,
- Operand { kind: OperandKind::Copy(p), span: None }.into(),
+ Operand { kind: OperandKind::Copy(p.store()), span: None }.into(),
expr_id.into(),
);
Ok(Some(current))
@@ -1124,7 +1127,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
};
let r_value = Rvalue::CheckedBinaryOp(
op.into(),
- Operand { kind: OperandKind::Copy(lhs_place), span: None },
+ Operand { kind: OperandKind::Copy(lhs_place.store()), span: None },
rhs_op,
);
self.push_assignment(current, lhs_place, r_value, expr_id.into());
@@ -1273,16 +1276,16 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
};
Ok(Place {
local: this.binding_local(local)?,
- projection: this
- .result
- .projection_store
- .intern(convert_closure_capture_projections(self.db, place).collect()),
+ projection: Projection::new_from_iter(convert_closure_capture_projections(
+ self.db, place,
+ ))
+ .store(),
})
};
for (place, _, sources) in &closure_data.fake_reads {
let p = convert_place(self, place)?;
- self.push_fake_read(current, p, span(sources));
+ self.push_fake_read(current, p.as_ref(), span(sources));
}
let captures = closure_data.min_captures.values().flatten();
@@ -1294,14 +1297,15 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
let tmp_ty = capture.captured_ty(self.db);
// FIXME: Handle more than one span.
let capture_span = span(&capture.info.sources);
- let tmp: Place = self.temp(tmp_ty, current, capture_span)?.into();
+ let tmp = self.temp(tmp_ty, current, capture_span)?.into();
self.push_assignment(
current,
tmp,
Rvalue::Ref(BorrowKind::from_hir(bk), p),
capture_span,
);
- operands.push(Operand { kind: OperandKind::Move(tmp), span: None });
+ operands
+ .push(Operand { kind: OperandKind::Move(tmp.store()), span: None });
}
UpvarCapture::ByValue => {
operands.push(Operand { kind: OperandKind::Move(p), span: None })
@@ -1396,24 +1400,24 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
}
}
- fn push_field_projection(&mut self, place: &mut Place, expr_id: ExprId) -> Result<'db, ()> {
+ fn push_field_projection(
+ &mut self,
+ place: &mut PlaceRef<'db>,
+ expr_id: ExprId,
+ ) -> Result<'db, ()> {
if let Expr::Field { expr, name } = &self.store[expr_id] {
if let TyKind::Tuple(..) = self.expr_ty_after_adjustments(*expr).kind() {
let index =
name.as_tuple_index().ok_or(MirLowerError::TypeError("named field on tuple"))?
as u32;
- *place = place.project(
- ProjectionElem::Field(Either::Right(TupleFieldId {
- tuple: TupleId(!0), // dummy as its unused
- index,
- })),
- &mut self.result.projection_store,
- )
+ *place = place.project(ProjectionElem::Field(Either::Right(TupleFieldId {
+ tuple: TupleId(!0), // dummy as its unused
+ index,
+ })))
} else {
let field =
self.infer.field_resolution(expr_id).ok_or(MirLowerError::UnresolvedField)?;
- *place =
- place.project(ProjectionElem::Field(field), &mut self.result.projection_store);
+ *place = place.project(ProjectionElem::Field(field));
}
} else {
not_supported!("")
@@ -1528,7 +1532,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
&mut self,
const_id: GeneralConstId,
prev_block: BasicBlockId,
- place: Place,
+ place: PlaceRef<'db>,
subst: GenericArgs<'db>,
span: MirSpan,
) -> Result<'db, ()> {
@@ -1561,7 +1565,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
fn write_bytes_to_place(
&mut self,
prev_block: BasicBlockId,
- place: Place,
+ place: PlaceRef<'db>,
cv: Box<[u8]>,
ty: Ty<'db>,
span: MirSpan,
@@ -1574,7 +1578,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
&mut self,
variant_id: EnumVariantId,
prev_block: BasicBlockId,
- place: Place,
+ place: PlaceRef<'db>,
ty: Ty<'db>,
fields: Box<[Operand]>,
span: MirSpan,
@@ -1596,7 +1600,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
&mut self,
func: Operand,
args: impl Iterator<Item = ExprId>,
- place: Place,
+ place: PlaceRef<'db>,
mut current: BasicBlockId,
is_uninhabited: bool,
span: MirSpan,
@@ -1621,7 +1625,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
&mut self,
func: Operand,
args: Box<[Operand]>,
- place: Place,
+ place: PlaceRef<'db>,
current: BasicBlockId,
is_uninhabited: bool,
span: MirSpan,
@@ -1632,7 +1636,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
TerminatorKind::Call {
func,
args,
- destination: place,
+ destination: place.store(),
target: b,
cleanup: None,
from_hir_call: true,
@@ -1672,31 +1676,31 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
self.result.basic_blocks[block].statements.push(statement);
}
- fn push_fake_read(&mut self, block: BasicBlockId, p: Place, span: MirSpan) {
- self.push_statement(block, StatementKind::FakeRead(p).with_span(span));
+ fn push_fake_read(&mut self, block: BasicBlockId, p: PlaceRef<'db>, span: MirSpan) {
+ self.push_statement(block, StatementKind::FakeRead(p.store()).with_span(span));
}
fn push_assignment(
&mut self,
block: BasicBlockId,
- place: Place,
+ place: PlaceRef<'db>,
rvalue: Rvalue,
span: MirSpan,
) {
- self.push_statement(block, StatementKind::Assign(place, rvalue).with_span(span));
+ self.push_statement(block, StatementKind::Assign(place.store(), rvalue).with_span(span));
}
- fn discr_temp_place(&mut self, current: BasicBlockId) -> Place {
+ fn discr_temp_place(&mut self, current: BasicBlockId) -> PlaceRef<'db> {
match &self.discr_temp {
- Some(it) => *it,
+ Some(it) => it.as_ref(),
None => {
// FIXME: rustc's ty is dependent on the adt type, maybe we need to do that as well
let discr_ty = Ty::new_int(self.interner(), rustc_type_ir::IntTy::I128);
- let tmp: Place = self
+ let tmp: PlaceRef<'_> = self
.temp(discr_ty, current, MirSpan::Unknown)
.expect("discr_ty is never unsized")
.into();
- self.discr_temp = Some(tmp);
+ self.discr_temp = Some(tmp.store());
tmp
}
}
@@ -1705,7 +1709,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
fn lower_loop(
&mut self,
prev_block: BasicBlockId,
- place: Place,
+ place: PlaceRef<'db>,
label: Option<LabelId>,
span: MirSpan,
f: impl FnOnce(&mut MirLowerCtx<'_, 'db>, BasicBlockId) -> Result<'db, ()>,
@@ -1714,7 +1718,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
let prev = self.current_loop_blocks.replace(LoopBlocks {
begin,
end: None,
- place,
+ place: place.store(),
drop_scope_index: self.drop_scopes.len(),
});
let prev_label = if let Some(label) = label {
@@ -1816,7 +1820,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
statements: &[hir_def::hir::Statement],
mut current: BasicBlockId,
tail: Option<ExprId>,
- place: Place,
+ place: PlaceRef<'db>,
span: MirSpan,
) -> Result<'db, Option<Idx<BasicBlock>>> {
let scope = self.push_drop_scope();
@@ -2068,7 +2072,11 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
let prev = std::mem::replace(current, self.new_basic_block());
self.set_terminator(
prev,
- TerminatorKind::Drop { place: l.into(), target: *current, unwind: None },
+ TerminatorKind::Drop {
+ place: PlaceRef::from(l).store(),
+ target: *current,
+ unwind: None,
+ },
span,
);
}
@@ -2202,15 +2210,18 @@ pub fn mir_body_for_closure_query<'db>(
projections.push(ProjectionElem::ClosureField(capture_idx));
let capture_param_place = Place {
local: closure_local,
- projection: ctx.result.projection_store.intern(projections.into_boxed_slice()),
- };
- let capture_local_place = Place {
- local: capture_local,
- projection: ctx.result.projection_store.intern(Box::new([])),
+ projection: Projection::new_from_slice(&projections).store(),
};
+ let capture_local_place =
+ Place { local: capture_local, projection: Projection::new_from_slice(&[]).store() };
let capture_local_rvalue =
Rvalue::Use(Operand { kind: OperandKind::Move(capture_param_place), span: None });
- ctx.push_assignment(current, capture_local_place, capture_local_rvalue, MirSpan::Unknown);
+ ctx.push_assignment(
+ current,
+ capture_local_place.as_ref(),
+ capture_local_rvalue,
+ MirSpan::Unknown,
+ );
let local = capture.captured_local();
let local = ctx.binding_local(local)?;
@@ -2230,8 +2241,8 @@ pub fn mir_body_for_closure_query<'db>(
}
let mut err = None;
- ctx.result.walk_places(|mir_place, store| {
- let mir_projections = mir_place.projection.lookup(store);
+ ctx.result.walk_places(|mir_place| {
+ let mir_projections = mir_place.projection.lookup();
if let Some(hir_places) = upvar_map.get(&mir_place.local) {
let projections = hir_places.iter().find_map(|hir_place| {
let iter = mir_projections
@@ -2267,18 +2278,17 @@ pub fn mir_body_for_closure_query<'db>(
match projections {
Some((skip_projections_up_to, (hir_place, upvar_local))) => {
mir_place.local = *upvar_local;
- let mut result_projections = Vec::with_capacity(
- usize::from(hir_place.is_by_ref())
- + (mir_projections.len() - skip_projections_up_to),
- );
- if hir_place.is_by_ref() {
- result_projections.push(ProjectionElem::Deref);
- }
- result_projections
- .extend(mir_projections[skip_projections_up_to..].iter().cloned());
- mir_place.projection = store.intern(result_projections.into());
+ let maybe_deref: &[PlaceElem] =
+ if hir_place.is_by_ref() { &[ProjectionElem::Deref] } else { &[] };
+ mir_place.projection = Projection::new_from_iter(
+ maybe_deref
+ .iter()
+ .copied()
+ .chain(mir_projections[skip_projections_up_to..].iter().copied()),
+ )
+ .store();
}
- None => err = Some(*mir_place),
+ None => err = Some(mir_place.clone()),
}
}
});