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.rs208
1 files changed, 110 insertions, 98 deletions
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index 3852db909e..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;
@@ -276,10 +276,11 @@ impl MirLowerError {
db: &dyn HirDatabase,
p: &Path,
display_target: DisplayTarget,
+ owner: ExpressionStoreOwnerId,
store: &ExpressionStore,
) -> Self {
Self::UnresolvedName(
- hir_display_with_store(p, store).display(db, display_target).to_string(),
+ hir_display_with_store(p, owner, store).display(db, display_target).to_string(),
)
}
}
@@ -302,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,
@@ -313,8 +313,8 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
closures: vec![],
};
let store_owner = owner.expression_store_owner(db);
- let resolver = store_owner.resolver(db);
- let env = db.trait_environment(store_owner);
+ let resolver = owner.resolver(db);
+ let env = db.trait_environment(owner.generic_def(db));
let interner = DbInterner::new_with(db, resolver.krate());
// FIXME(next-solver): Is `non_body_analysis()` correct here? Don't we want to reveal opaque types defined by this body?
let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
@@ -370,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>> {
@@ -395,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))
@@ -421,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(),
@@ -436,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,
@@ -447,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) {
@@ -466,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] {
@@ -517,6 +520,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
self.db,
p,
DisplayTarget::from_crate(self.db, self.krate()),
+ self.owner.expression_store_owner(self.db),
self.store,
)
})?;
@@ -533,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))
@@ -667,7 +671,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
self.lower_block_to_place(statements, current, *tail, place, expr_id.into())
}
}
- Expr::Loop { body, label } => {
+ Expr::Loop { body, label, source: _ } => {
self.lower_loop(current, place, *label, expr_id.into(), |this, begin| {
let scope = this.push_drop_scope();
if let Some((_, mut current)) = this.lower_expr_as_place(begin, *body, true)? {
@@ -829,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;
@@ -884,10 +890,12 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
};
let variant_id =
self.infer.variant_resolution_for_expr(expr_id).ok_or_else(|| {
- MirLowerError::UnresolvedName(
- hir_display_with_store(path, self.store)
- .display(self.db, self.display_target())
- .to_string(),
+ MirLowerError::unresolved_path(
+ self.db,
+ path,
+ self.display_target(),
+ self.owner.expression_store_owner(self.db),
+ self.store,
)
})?;
let subst = match self.expr_ty_without_adjust(expr_id).kind() {
@@ -917,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(),
@@ -944,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)
}
}
@@ -997,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 } => {
@@ -1012,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))
}
@@ -1027,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))
@@ -1120,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());
@@ -1269,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();
@@ -1290,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 })
@@ -1392,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!("")
@@ -1432,6 +1440,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> {
self.db,
c,
DisplayTarget::from_crate(db, owner.krate(db)),
+ self.owner.expression_store_owner(self.db),
self.store,
)
};
@@ -1523,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, ()> {
@@ -1556,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,
@@ -1569,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,
@@ -1591,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,
@@ -1616,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,
@@ -1627,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,
@@ -1667,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
}
}
@@ -1700,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, ()>,
@@ -1709,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 {
@@ -1811,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();
@@ -2063,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,
);
}
@@ -2197,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)?;
@@ -2225,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
@@ -2262,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()),
}
}
});
@@ -2309,10 +2324,7 @@ pub fn mir_body_query<'db>(db: &'db dyn HirDatabase, def: InferBodyId) -> Result
.to_string(),
InferBodyId::DefWithBodyId(DefWithBodyId::VariantId(it)) => {
let loc = it.lookup(db);
- loc.parent.enum_variants(db).variants[loc.index as usize]
- .1
- .display(db, edition)
- .to_string()
+ loc.name.display(db, edition).to_string()
}
InferBodyId::AnonConstId(_) => "{const}".to_owned(),
};