mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 20:42:04 +00:00
Intern projections in mir place
This commit is contained in:
parent
e4c469321c
commit
9708a29e57
7 changed files with 253 additions and 157 deletions
|
@ -46,8 +46,8 @@ use crate::{
|
|||
|
||||
use super::{
|
||||
return_slot, AggregateKind, BasicBlockId, BinOp, CastKind, LocalId, MirBody, MirLowerError,
|
||||
MirSpan, Operand, Place, PlaceElem, ProjectionElem, Rvalue, StatementKind, TerminatorKind,
|
||||
UnOp,
|
||||
MirSpan, Operand, Place, PlaceElem, ProjectionElem, ProjectionStore, Rvalue, StatementKind,
|
||||
TerminatorKind, UnOp,
|
||||
};
|
||||
|
||||
mod shim;
|
||||
|
@ -485,17 +485,18 @@ struct DropFlags {
|
|||
}
|
||||
|
||||
impl DropFlags {
|
||||
fn add_place(&mut self, p: Place) {
|
||||
if p.iterate_over_parents().any(|it| self.need_drop.contains(&it)) {
|
||||
fn add_place(&mut self, p: Place, store: &ProjectionStore) {
|
||||
if p.iterate_over_parents(store).any(|it| self.need_drop.contains(&it)) {
|
||||
return;
|
||||
}
|
||||
self.need_drop.retain(|it| !p.is_parent(it));
|
||||
self.need_drop.retain(|it| !p.is_parent(it, store));
|
||||
self.need_drop.insert(p);
|
||||
}
|
||||
|
||||
fn remove_place(&mut self, p: &Place) -> bool {
|
||||
fn remove_place(&mut self, p: &Place, store: &ProjectionStore) -> bool {
|
||||
// FIXME: replace parents with parts
|
||||
if let Some(parent) = p.iterate_over_parents().find(|it| self.need_drop.contains(&it)) {
|
||||
if let Some(parent) = p.iterate_over_parents(store).find(|it| self.need_drop.contains(&it))
|
||||
{
|
||||
self.need_drop.remove(&parent);
|
||||
return true;
|
||||
}
|
||||
|
@ -656,7 +657,7 @@ impl Evaluator<'_> {
|
|||
let mut addr = locals.ptr[p.local].addr;
|
||||
let mut ty: Ty = locals.body.locals[p.local].ty.clone();
|
||||
let mut metadata: Option<IntervalOrOwned> = None; // locals are always sized
|
||||
for proj in &*p.projection {
|
||||
for proj in p.projection.lookup(&locals.body.projection_store) {
|
||||
let prev_ty = ty.clone();
|
||||
ty = self.projected_ty(ty, proj.clone());
|
||||
match proj {
|
||||
|
@ -837,7 +838,9 @@ impl Evaluator<'_> {
|
|||
let addr = self.place_addr(l, &locals)?;
|
||||
let result = self.eval_rvalue(r, &mut locals)?.to_vec(&self)?;
|
||||
self.write_memory(addr, &result)?;
|
||||
locals.drop_flags.add_place(l.clone());
|
||||
locals
|
||||
.drop_flags
|
||||
.add_place(l.clone(), &locals.body.projection_store);
|
||||
}
|
||||
StatementKind::Deinit(_) => not_supported!("de-init statement"),
|
||||
StatementKind::StorageLive(_)
|
||||
|
@ -889,7 +892,9 @@ impl Evaluator<'_> {
|
|||
)?,
|
||||
it => not_supported!("unknown function type {it:?}"),
|
||||
};
|
||||
locals.drop_flags.add_place(destination.clone());
|
||||
locals
|
||||
.drop_flags
|
||||
.add_place(destination.clone(), &locals.body.projection_store);
|
||||
if let Some(stack_frame) = stack_frame {
|
||||
self.code_stack.push(my_stack_frame);
|
||||
current_block_idx = stack_frame.locals.body.start_block;
|
||||
|
@ -970,7 +975,7 @@ impl Evaluator<'_> {
|
|||
) -> Result<()> {
|
||||
let mut remain_args = body.param_locals.len();
|
||||
for ((l, interval), value) in locals.ptr.iter().skip(1).zip(args) {
|
||||
locals.drop_flags.add_place(l.into());
|
||||
locals.drop_flags.add_place(l.into(), &locals.body.projection_store);
|
||||
match value {
|
||||
IntervalOrOwned::Owned(value) => interval.write_from_bytes(self, &value)?,
|
||||
IntervalOrOwned::Borrowed(value) => interval.write_from_interval(self, value)?,
|
||||
|
@ -1646,7 +1651,7 @@ impl Evaluator<'_> {
|
|||
fn eval_operand(&mut self, it: &Operand, locals: &mut Locals) -> Result<Interval> {
|
||||
Ok(match it {
|
||||
Operand::Copy(p) | Operand::Move(p) => {
|
||||
locals.drop_flags.remove_place(p);
|
||||
locals.drop_flags.remove_place(p, &locals.body.projection_store);
|
||||
self.eval_place(p, locals)?
|
||||
}
|
||||
Operand::Static(st) => {
|
||||
|
@ -2468,7 +2473,7 @@ impl Evaluator<'_> {
|
|||
|
||||
fn drop_place(&mut self, place: &Place, locals: &mut Locals, span: MirSpan) -> Result<()> {
|
||||
let (addr, ty, metadata) = self.place_addr_and_ty_and_metadata(place, locals)?;
|
||||
if !locals.drop_flags.remove_place(place) {
|
||||
if !locals.drop_flags.remove_place(place, &locals.body.projection_store) {
|
||||
return Ok(());
|
||||
}
|
||||
let metadata = match metadata {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue