Skip to content

Commit

Permalink
Auto merge of rust-lang#14955 - HKalbasi:mir-fix, r=HKalbasi
Browse files Browse the repository at this point in the history
Remove unnecessary `StorageDead`

I hope this reduces MIR memory usage.
  • Loading branch information
bors committed Jun 3, 2023
2 parents dd0c29c + f44fc27 commit e5c56cd
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 301 deletions.
105 changes: 31 additions & 74 deletions crates/hir-ty/src/infer/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ use chalk_ir::{
};
use hir_def::{
data::adt::VariantData,
hir::{
Array, BinaryOp, BindingAnnotation, BindingId, CaptureBy, Expr, ExprId, Pat, PatId,
Statement, UnaryOp,
},
hir::{Array, BinaryOp, BindingId, CaptureBy, Expr, ExprId, Pat, PatId, Statement, UnaryOp},
lang_item::LangItem,
resolver::{resolver_for_expr, ResolveValueResult, ValueNs},
DefWithBodyId, FieldId, HasModule, VariantId,
Expand All @@ -28,9 +25,9 @@ use crate::{
mir::{BorrowKind, MirSpan, ProjectionElem},
static_lifetime, to_chalk_trait_id,
traits::FnTrait,
utils::{self, generics, pattern_matching_dereference_count, Generics},
Adjust, Adjustment, Binders, ChalkTraitId, ClosureId, ConstValue, DynTy, FnPointer, FnSig,
Interner, Substitution, Ty, TyExt,
utils::{self, generics, Generics},
Adjust, Adjustment, Binders, BindingMode, ChalkTraitId, ClosureId, ConstValue, DynTy,
FnPointer, FnSig, Interner, Substitution, Ty, TyExt,
};

use super::{Expectation, InferenceContext};
Expand Down Expand Up @@ -488,13 +485,7 @@ impl InferenceContext<'_> {
if let Some(initializer) = initializer {
self.walk_expr(*initializer);
if let Some(place) = self.place_of_expr(*initializer) {
let ty = self.expr_ty(*initializer);
self.consume_with_pat(
place,
ty,
BindingAnnotation::Unannotated,
*pat,
);
self.consume_with_pat(place, *pat);
}
}
}
Expand Down Expand Up @@ -799,41 +790,37 @@ impl InferenceContext<'_> {
}
}

fn consume_with_pat(
&mut self,
mut place: HirPlace,
mut ty: Ty,
mut bm: BindingAnnotation,
pat: PatId,
) {
fn consume_with_pat(&mut self, mut place: HirPlace, pat: PatId) {
let cnt = self.result.pat_adjustments.get(&pat).map(|x| x.len()).unwrap_or_default();
place.projections = place
.projections
.iter()
.cloned()
.chain((0..cnt).map(|_| ProjectionElem::Deref))
.collect::<Vec<_>>()
.into();
match &self.body[pat] {
Pat::Missing | Pat::Wild => (),
Pat::Tuple { args, ellipsis } => {
pattern_matching_dereference(&mut ty, &mut bm, &mut place);
let (al, ar) = args.split_at(ellipsis.unwrap_or(args.len()));
let subst = match ty.kind(Interner) {
TyKind::Tuple(_, s) => s,
let field_count = match self.result[pat].kind(Interner) {
TyKind::Tuple(_, s) => s.len(Interner),
_ => return,
};
let fields = subst.iter(Interner).map(|x| x.assert_ty_ref(Interner)).enumerate();
let fields = 0..field_count;
let it = al.iter().zip(fields.clone()).chain(ar.iter().rev().zip(fields.rev()));
for (arg, (i, ty)) in it {
for (arg, i) in it {
let mut p = place.clone();
p.projections.push(ProjectionElem::TupleOrClosureField(i));
self.consume_with_pat(p, ty.clone(), bm, *arg);
self.consume_with_pat(p, *arg);
}
}
Pat::Or(pats) => {
for pat in pats.iter() {
self.consume_with_pat(place.clone(), ty.clone(), bm, *pat);
self.consume_with_pat(place.clone(), *pat);
}
}
Pat::Record { args, .. } => {
pattern_matching_dereference(&mut ty, &mut bm, &mut place);
let subst = match ty.kind(Interner) {
TyKind::Adt(_, s) => s,
_ => return,
};
let Some(variant) = self.result.variant_resolution_for_pat(pat) else {
return;
};
Expand All @@ -843,7 +830,6 @@ impl InferenceContext<'_> {
}
VariantId::StructId(s) => {
let vd = &*self.db.struct_data(s).variant_data;
let field_types = self.db.field_types(variant);
for field_pat in args.iter() {
let arg = field_pat.pat;
let Some(local_id) = vd.field(&field_pat.name) else {
Expand All @@ -854,12 +840,7 @@ impl InferenceContext<'_> {
parent: variant.into(),
local_id,
}));
self.consume_with_pat(
p,
field_types[local_id].clone().substitute(Interner, subst),
bm,
arg,
);
self.consume_with_pat(p, arg);
}
}
}
Expand All @@ -870,26 +851,20 @@ impl InferenceContext<'_> {
| Pat::Path(_)
| Pat::Lit(_) => self.consume_place(place, pat.into()),
Pat::Bind { id, subpat: _ } => {
let mode = self.body.bindings[*id].mode;
if matches!(mode, BindingAnnotation::Ref | BindingAnnotation::RefMut) {
bm = mode;
}
let capture_kind = match bm {
BindingAnnotation::Unannotated | BindingAnnotation::Mutable => {
let mode = self.result.binding_modes[*id];
let capture_kind = match mode {
BindingMode::Move => {
self.consume_place(place, pat.into());
return;
}
BindingAnnotation::Ref => BorrowKind::Shared,
BindingAnnotation::RefMut => BorrowKind::Mut { allow_two_phase_borrow: false },
BindingMode::Ref(Mutability::Not) => BorrowKind::Shared,
BindingMode::Ref(Mutability::Mut) => {
BorrowKind::Mut { allow_two_phase_borrow: false }
}
};
self.add_capture(place, CaptureKind::ByRef(capture_kind), pat.into());
}
Pat::TupleStruct { path: _, args, ellipsis } => {
pattern_matching_dereference(&mut ty, &mut bm, &mut place);
let subst = match ty.kind(Interner) {
TyKind::Adt(_, s) => s,
_ => return,
};
let Some(variant) = self.result.variant_resolution_for_pat(pat) else {
return;
};
Expand All @@ -903,29 +878,20 @@ impl InferenceContext<'_> {
let fields = vd.fields().iter();
let it =
al.iter().zip(fields.clone()).chain(ar.iter().rev().zip(fields.rev()));
let field_types = self.db.field_types(variant);
for (arg, (i, _)) in it {
let mut p = place.clone();
p.projections.push(ProjectionElem::Field(FieldId {
parent: variant.into(),
local_id: i,
}));
self.consume_with_pat(
p,
field_types[i].clone().substitute(Interner, subst),
bm,
*arg,
);
self.consume_with_pat(p, *arg);
}
}
}
}
Pat::Ref { pat, mutability: _ } => {
if let Some((inner, _, _)) = ty.as_reference() {
ty = inner.clone();
place.projections.push(ProjectionElem::Deref);
self.consume_with_pat(place, ty, bm, *pat)
}
place.projections.push(ProjectionElem::Deref);
self.consume_with_pat(place, *pat)
}
Pat::Box { .. } => (), // not supported
}
Expand Down Expand Up @@ -1054,12 +1020,3 @@ fn apply_adjusts_to_place(mut r: HirPlace, adjustments: &[Adjustment]) -> Option
}
Some(r)
}

fn pattern_matching_dereference(
cond_ty: &mut Ty,
binding_mode: &mut BindingAnnotation,
cond_place: &mut HirPlace,
) {
let cnt = pattern_matching_dereference_count(cond_ty, binding_mode);
cond_place.projections.extend((0..cnt).map(|_| ProjectionElem::Deref));
}
27 changes: 3 additions & 24 deletions crates/hir-ty/src/mir/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,9 +478,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
current,
None,
cond_place,
self.expr_ty_after_adjustments(*expr),
*pat,
BindingAnnotation::Unannotated,
)?;
self.write_bytes_to_place(
then_target,
Expand Down Expand Up @@ -598,16 +596,13 @@ impl<'ctx> MirLowerCtx<'ctx> {
else {
return Ok(None);
};
let cond_ty = self.expr_ty_after_adjustments(*expr);
let mut end = None;
for MatchArm { pat, guard, expr } in arms.iter() {
let (then, mut otherwise) = self.pattern_match(
current,
None,
cond_place.clone(),
cond_ty.clone(),
*pat,
BindingAnnotation::Unannotated,
)?;
let then = if let &Some(guard) = guard {
let next = self.new_basic_block();
Expand Down Expand Up @@ -1477,9 +1472,6 @@ impl<'ctx> MirLowerCtx<'ctx> {
span: MirSpan,
) -> Result<()> {
self.drop_scopes.last_mut().unwrap().locals.push(l);
// FIXME: this storage dead is not neccessary, but since drop scope handling is broken, we need
// it to avoid falso positives in mutability errors
self.push_statement(current, StatementKind::StorageDead(l).with_span(span));
self.push_statement(current, StatementKind::StorageLive(l).with_span(span));
Ok(())
}
Expand Down Expand Up @@ -1508,14 +1500,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
return Ok(None);
};
current = c;
(current, else_block) = self.pattern_match(
current,
None,
init_place,
self.expr_ty_after_adjustments(*expr_id),
*pat,
BindingAnnotation::Unannotated,
)?;
(current, else_block) =
self.pattern_match(current, None, init_place, *pat)?;
match (else_block, else_branch) {
(None, _) => (),
(Some(else_block), None) => {
Expand Down Expand Up @@ -1595,14 +1581,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
continue;
}
}
let r = self.pattern_match(
current,
None,
local.into(),
self.result.locals[local].ty.clone(),
param,
BindingAnnotation::Unannotated,
)?;
let r = self.pattern_match(current, None, local.into(), param)?;
if let Some(b) = r.1 {
self.set_terminator(b, TerminatorKind::Unreachable, param.into());
}
Expand Down
Loading

0 comments on commit e5c56cd

Please sign in to comment.