mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 17:53:56 +00:00
Auto merge of #14847 - HKalbasi:layout, r=HKalbasi
Reduce MIR memory usage
This commit is contained in:
commit
bb78059be4
@ -205,7 +205,7 @@ type PlaceElem = ProjectionElem<LocalId, Ty>;
|
|||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Place {
|
pub struct Place {
|
||||||
pub local: LocalId,
|
pub local: LocalId,
|
||||||
pub projection: Vec<PlaceElem>,
|
pub projection: Box<[PlaceElem]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Place {
|
impl Place {
|
||||||
@ -216,13 +216,20 @@ impl Place {
|
|||||||
fn iterate_over_parents(&self) -> impl Iterator<Item = Place> + '_ {
|
fn iterate_over_parents(&self) -> impl Iterator<Item = Place> + '_ {
|
||||||
(0..self.projection.len())
|
(0..self.projection.len())
|
||||||
.map(|x| &self.projection[0..x])
|
.map(|x| &self.projection[0..x])
|
||||||
.map(|x| Place { local: self.local, projection: x.to_vec() })
|
.map(|x| Place { local: self.local, projection: x.to_vec().into() })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn project(&self, projection: PlaceElem) -> Place {
|
||||||
|
Place {
|
||||||
|
local: self.local,
|
||||||
|
projection: self.projection.iter().cloned().chain([projection]).collect(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<LocalId> for Place {
|
impl From<LocalId> for Place {
|
||||||
fn from(local: LocalId) -> Self {
|
fn from(local: LocalId) -> Self {
|
||||||
Self { local, projection: vec![] }
|
Self { local, projection: vec![].into() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,7 +444,7 @@ pub enum TerminatorKind {
|
|||||||
/// These are owned by the callee, which is free to modify them.
|
/// These are owned by the callee, which is free to modify them.
|
||||||
/// This allows the memory occupied by "by-value" arguments to be
|
/// This allows the memory occupied by "by-value" arguments to be
|
||||||
/// reused across function calls without duplicating the contents.
|
/// reused across function calls without duplicating the contents.
|
||||||
args: Vec<Operand>,
|
args: Box<[Operand]>,
|
||||||
/// Where the returned value will be written
|
/// Where the returned value will be written
|
||||||
destination: Place,
|
destination: Place,
|
||||||
/// Where to go after this call returns. If none, the call necessarily diverges.
|
/// Where to go after this call returns. If none, the call necessarily diverges.
|
||||||
@ -894,7 +901,7 @@ pub enum Rvalue {
|
|||||||
///
|
///
|
||||||
/// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After
|
/// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After
|
||||||
/// generator lowering, `Generator` aggregate kinds are disallowed too.
|
/// generator lowering, `Generator` aggregate kinds are disallowed too.
|
||||||
Aggregate(AggregateKind, Vec<Operand>),
|
Aggregate(AggregateKind, Box<[Operand]>),
|
||||||
|
|
||||||
/// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
|
/// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
|
||||||
///
|
///
|
||||||
@ -1011,7 +1018,7 @@ impl MirBody {
|
|||||||
for_operand(o2, &mut f);
|
for_operand(o2, &mut f);
|
||||||
}
|
}
|
||||||
Rvalue::Aggregate(_, ops) => {
|
Rvalue::Aggregate(_, ops) => {
|
||||||
for op in ops {
|
for op in ops.iter_mut() {
|
||||||
for_operand(op, &mut f);
|
for_operand(op, &mut f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1058,6 +1065,27 @@ impl MirBody {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn shrink_to_fit(&mut self) {
|
||||||
|
let MirBody {
|
||||||
|
basic_blocks,
|
||||||
|
locals,
|
||||||
|
start_block: _,
|
||||||
|
owner: _,
|
||||||
|
binding_locals,
|
||||||
|
param_locals,
|
||||||
|
closures,
|
||||||
|
} = self;
|
||||||
|
basic_blocks.shrink_to_fit();
|
||||||
|
locals.shrink_to_fit();
|
||||||
|
binding_locals.shrink_to_fit();
|
||||||
|
param_locals.shrink_to_fit();
|
||||||
|
closures.shrink_to_fit();
|
||||||
|
for (_, b) in basic_blocks.iter_mut() {
|
||||||
|
let BasicBlock { statements, terminator: _, is_cleanup: _ } = b;
|
||||||
|
statements.shrink_to_fit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
|
@ -93,7 +93,7 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef>
|
|||||||
Operand::Copy(p) | Operand::Move(p) => {
|
Operand::Copy(p) | Operand::Move(p) => {
|
||||||
let mut ty: Ty = body.locals[p.local].ty.clone();
|
let mut ty: Ty = body.locals[p.local].ty.clone();
|
||||||
let mut is_dereference_of_ref = false;
|
let mut is_dereference_of_ref = false;
|
||||||
for proj in &p.projection {
|
for proj in &*p.projection {
|
||||||
if *proj == ProjectionElem::Deref && ty.as_reference().is_some() {
|
if *proj == ProjectionElem::Deref && ty.as_reference().is_some() {
|
||||||
is_dereference_of_ref = true;
|
is_dereference_of_ref = true;
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef>
|
|||||||
for_operand(o2, statement.span);
|
for_operand(o2, statement.span);
|
||||||
}
|
}
|
||||||
Rvalue::Aggregate(_, ops) => {
|
Rvalue::Aggregate(_, ops) => {
|
||||||
for op in ops {
|
for op in ops.iter() {
|
||||||
for_operand(op, statement.span);
|
for_operand(op, statement.span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -562,7 +562,7 @@ impl Evaluator<'_> {
|
|||||||
let mut ty: Ty =
|
let mut ty: Ty =
|
||||||
self.ty_filler(&locals.body.locals[p.local].ty, locals.subst, locals.body.owner)?;
|
self.ty_filler(&locals.body.locals[p.local].ty, locals.subst, locals.body.owner)?;
|
||||||
let mut metadata: Option<IntervalOrOwned> = None; // locals are always sized
|
let mut metadata: Option<IntervalOrOwned> = None; // locals are always sized
|
||||||
for proj in &p.projection {
|
for proj in &*p.projection {
|
||||||
let prev_ty = ty.clone();
|
let prev_ty = ty.clone();
|
||||||
ty = proj.projected_ty(
|
ty = proj.projected_ty(
|
||||||
ty,
|
ty,
|
||||||
|
@ -387,7 +387,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||||||
current,
|
current,
|
||||||
place,
|
place,
|
||||||
ty,
|
ty,
|
||||||
vec![],
|
Box::new([]),
|
||||||
expr_id.into(),
|
expr_id.into(),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
@ -561,7 +561,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||||||
};
|
};
|
||||||
self.push_assignment(current, ref_mut_iterator_place.clone(), Rvalue::Ref(BorrowKind::Mut { allow_two_phase_borrow: false }, iterator_place), expr_id.into());
|
self.push_assignment(current, ref_mut_iterator_place.clone(), Rvalue::Ref(BorrowKind::Mut { allow_two_phase_borrow: false }, iterator_place), expr_id.into());
|
||||||
self.lower_loop(current, place, label, expr_id.into(), |this, begin| {
|
self.lower_loop(current, place, label, expr_id.into(), |this, begin| {
|
||||||
let Some(current) = this.lower_call(iter_next_fn_op, vec![Operand::Copy(ref_mut_iterator_place)], option_item_place.clone(), begin, false, expr_id.into())?
|
let Some(current) = this.lower_call(iter_next_fn_op, Box::new([Operand::Copy(ref_mut_iterator_place)]), option_item_place.clone(), begin, false, expr_id.into())?
|
||||||
else {
|
else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
@ -758,8 +758,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||||||
match x {
|
match x {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None => {
|
None => {
|
||||||
let mut p = sp.clone();
|
let p = sp.project(ProjectionElem::Field(FieldId {
|
||||||
p.projection.push(ProjectionElem::Field(FieldId {
|
|
||||||
parent: variant_id,
|
parent: variant_id,
|
||||||
local_id: LocalFieldId::from_raw(RawIdx::from(i as u32)),
|
local_id: LocalFieldId::from_raw(RawIdx::from(i as u32)),
|
||||||
}));
|
}));
|
||||||
@ -782,10 +781,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||||||
};
|
};
|
||||||
let local_id =
|
let local_id =
|
||||||
variant_data.field(name).ok_or(MirLowerError::UnresolvedField)?;
|
variant_data.field(name).ok_or(MirLowerError::UnresolvedField)?;
|
||||||
let mut place = place;
|
let place = place.project(PlaceElem::Field(FieldId { parent: union_id.into(), local_id }));
|
||||||
place
|
|
||||||
.projection
|
|
||||||
.push(PlaceElem::Field(FieldId { parent: union_id.into(), local_id }));
|
|
||||||
self.lower_expr_to_place(*expr, place, current)
|
self.lower_expr_to_place(*expr, place, current)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -826,8 +822,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||||||
let Some((operand, current)) = self.lower_expr_to_some_operand(*expr, current)? else {
|
let Some((operand, current)) = self.lower_expr_to_some_operand(*expr, current)? else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
let mut p = place;
|
let p = place.project(ProjectionElem::Deref);
|
||||||
p.projection.push(ProjectionElem::Deref);
|
|
||||||
self.push_assignment(current, p, operand.into(), expr_id.into());
|
self.push_assignment(current, p, operand.into(), expr_id.into());
|
||||||
Ok(Some(current))
|
Ok(Some(current))
|
||||||
},
|
},
|
||||||
@ -1031,7 +1026,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||||||
self.push_assignment(
|
self.push_assignment(
|
||||||
current,
|
current,
|
||||||
place,
|
place,
|
||||||
Rvalue::Aggregate(AggregateKind::Closure(ty), operands),
|
Rvalue::Aggregate(AggregateKind::Closure(ty), operands.into()),
|
||||||
expr_id.into(),
|
expr_id.into(),
|
||||||
);
|
);
|
||||||
Ok(Some(current))
|
Ok(Some(current))
|
||||||
@ -1128,11 +1123,11 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||||||
let index = name
|
let index = name
|
||||||
.as_tuple_index()
|
.as_tuple_index()
|
||||||
.ok_or(MirLowerError::TypeError("named field on tuple"))?;
|
.ok_or(MirLowerError::TypeError("named field on tuple"))?;
|
||||||
place.projection.push(ProjectionElem::TupleOrClosureField(index))
|
*place = place.project(ProjectionElem::TupleOrClosureField(index))
|
||||||
} else {
|
} else {
|
||||||
let field =
|
let field =
|
||||||
self.infer.field_resolution(expr_id).ok_or(MirLowerError::UnresolvedField)?;
|
self.infer.field_resolution(expr_id).ok_or(MirLowerError::UnresolvedField)?;
|
||||||
place.projection.push(ProjectionElem::Field(field));
|
*place = place.project(ProjectionElem::Field(field));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
not_supported!("")
|
not_supported!("")
|
||||||
@ -1242,7 +1237,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||||||
prev_block: BasicBlockId,
|
prev_block: BasicBlockId,
|
||||||
place: Place,
|
place: Place,
|
||||||
ty: Ty,
|
ty: Ty,
|
||||||
fields: Vec<Operand>,
|
fields: Box<[Operand]>,
|
||||||
span: MirSpan,
|
span: MirSpan,
|
||||||
) -> Result<BasicBlockId> {
|
) -> Result<BasicBlockId> {
|
||||||
let subst = match ty.kind(Interner) {
|
let subst = match ty.kind(Interner) {
|
||||||
@ -1280,13 +1275,13 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||||||
else {
|
else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
self.lower_call(func, args, place, current, is_uninhabited, span)
|
self.lower_call(func, args.into(), place, current, is_uninhabited, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_call(
|
fn lower_call(
|
||||||
&mut self,
|
&mut self,
|
||||||
func: Operand,
|
func: Operand,
|
||||||
args: Vec<Operand>,
|
args: Box<[Operand]>,
|
||||||
place: Place,
|
place: Place,
|
||||||
current: BasicBlockId,
|
current: BasicBlockId,
|
||||||
is_uninhabited: bool,
|
is_uninhabited: bool,
|
||||||
@ -1744,12 +1739,13 @@ pub fn mir_body_for_closure_query(
|
|||||||
match r {
|
match r {
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
p.local = closure_local;
|
p.local = closure_local;
|
||||||
let prev_projs =
|
let mut next_projs = vec![PlaceElem::TupleOrClosureField(x.1)];
|
||||||
mem::replace(&mut p.projection, vec![PlaceElem::TupleOrClosureField(x.1)]);
|
let prev_projs = mem::take(&mut p.projection);
|
||||||
if x.0.kind != CaptureKind::ByValue {
|
if x.0.kind != CaptureKind::ByValue {
|
||||||
p.projection.push(ProjectionElem::Deref);
|
next_projs.push(ProjectionElem::Deref);
|
||||||
}
|
}
|
||||||
p.projection.extend(prev_projs.into_iter().skip(x.0.place.projections.len()));
|
next_projs.extend(prev_projs.iter().cloned().skip(x.0.place.projections.len()));
|
||||||
|
p.projection = next_projs.into();
|
||||||
}
|
}
|
||||||
None => err = Some(p.clone()),
|
None => err = Some(p.clone()),
|
||||||
}
|
}
|
||||||
@ -1764,6 +1760,7 @@ pub fn mir_body_for_closure_query(
|
|||||||
if let Some(err) = err {
|
if let Some(err) = err {
|
||||||
return Err(MirLowerError::UnresolvedUpvar(err));
|
return Err(MirLowerError::UnresolvedUpvar(err));
|
||||||
}
|
}
|
||||||
|
ctx.result.shrink_to_fit();
|
||||||
Ok(Arc::new(ctx.result))
|
Ok(Arc::new(ctx.result))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1780,7 +1777,8 @@ pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result<Arc<Mi
|
|||||||
});
|
});
|
||||||
let body = db.body(def);
|
let body = db.body(def);
|
||||||
let infer = db.infer(def);
|
let infer = db.infer(def);
|
||||||
let result = lower_to_mir(db, def, &body, &infer, body.body_expr)?;
|
let mut result = lower_to_mir(db, def, &body, &infer, body.body_expr)?;
|
||||||
|
result.shrink_to_fit();
|
||||||
Ok(Arc::new(result))
|
Ok(Arc::new(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ impl MirLowerCtx<'_> {
|
|||||||
)? else {
|
)? else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
x.0.projection.push(ProjectionElem::Deref);
|
x.0 = x.0.project(ProjectionElem::Deref);
|
||||||
Ok(Some(x))
|
Ok(Some(x))
|
||||||
}
|
}
|
||||||
Adjust::Deref(Some(od)) => {
|
Adjust::Deref(Some(od)) => {
|
||||||
@ -139,15 +139,14 @@ impl MirLowerCtx<'_> {
|
|||||||
let ty = self.expr_ty_without_adjust(expr_id);
|
let ty = self.expr_ty_without_adjust(expr_id);
|
||||||
let ref_ty =
|
let ref_ty =
|
||||||
TyKind::Ref(Mutability::Not, static_lifetime(), ty).intern(Interner);
|
TyKind::Ref(Mutability::Not, static_lifetime(), ty).intern(Interner);
|
||||||
let mut temp: Place = self.temp(ref_ty, current, expr_id.into())?.into();
|
let temp: Place = self.temp(ref_ty, current, expr_id.into())?.into();
|
||||||
self.push_assignment(
|
self.push_assignment(
|
||||||
current,
|
current,
|
||||||
temp.clone(),
|
temp.clone(),
|
||||||
Operand::Static(s).into(),
|
Operand::Static(s).into(),
|
||||||
expr_id.into(),
|
expr_id.into(),
|
||||||
);
|
);
|
||||||
temp.projection.push(ProjectionElem::Deref);
|
Ok(Some((temp.project(ProjectionElem::Deref), current)))
|
||||||
Ok(Some((temp, current)))
|
|
||||||
}
|
}
|
||||||
_ => try_rvalue(self),
|
_ => try_rvalue(self),
|
||||||
}
|
}
|
||||||
@ -196,7 +195,7 @@ impl MirLowerCtx<'_> {
|
|||||||
let Some((mut r, current)) = self.lower_expr_as_place(current, *expr, true)? else {
|
let Some((mut r, current)) = self.lower_expr_as_place(current, *expr, true)? else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
r.projection.push(ProjectionElem::Deref);
|
r = r.project(ProjectionElem::Deref);
|
||||||
Ok(Some((r, current)))
|
Ok(Some((r, current)))
|
||||||
}
|
}
|
||||||
_ => try_rvalue(self),
|
_ => try_rvalue(self),
|
||||||
@ -253,7 +252,7 @@ impl MirLowerCtx<'_> {
|
|||||||
let Some(current) = self.lower_expr_to_place(*index, l_index.into(), current)? else {
|
let Some(current) = self.lower_expr_to_place(*index, l_index.into(), current)? else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
p_base.projection.push(ProjectionElem::Index(l_index));
|
p_base = p_base.project(ProjectionElem::Index(l_index));
|
||||||
Ok(Some((p_base, current)))
|
Ok(Some((p_base, current)))
|
||||||
}
|
}
|
||||||
_ => try_rvalue(self),
|
_ => try_rvalue(self),
|
||||||
@ -283,10 +282,10 @@ impl MirLowerCtx<'_> {
|
|||||||
)
|
)
|
||||||
.intern(Interner),
|
.intern(Interner),
|
||||||
);
|
);
|
||||||
let Some(current) = self.lower_call(index_fn_op, vec![Operand::Copy(place), index_operand], result.clone(), current, false, span)? else {
|
let Some(current) = self.lower_call(index_fn_op, Box::new([Operand::Copy(place), index_operand]), result.clone(), current, false, span)? else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
result.projection.push(ProjectionElem::Deref);
|
result = result.project(ProjectionElem::Deref);
|
||||||
Ok(Some((result, current)))
|
Ok(Some((result, current)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,10 +329,10 @@ impl MirLowerCtx<'_> {
|
|||||||
.intern(Interner),
|
.intern(Interner),
|
||||||
);
|
);
|
||||||
let mut result: Place = self.temp(target_ty_ref, current, span)?.into();
|
let mut result: Place = self.temp(target_ty_ref, current, span)?.into();
|
||||||
let Some(current) = self.lower_call(deref_fn_op, vec![Operand::Copy(ref_place)], result.clone(), current, false, span)? else {
|
let Some(current) = self.lower_call(deref_fn_op, Box::new([Operand::Copy(ref_place)]), result.clone(), current, false, span)? else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
result.projection.push(ProjectionElem::Deref);
|
result = result.project(ProjectionElem::Deref);
|
||||||
Ok(Some((result, current)))
|
Ok(Some((result, current)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,10 +110,10 @@ impl MirLowerCtx<'_> {
|
|||||||
Pat::Slice { prefix, slice, suffix } => {
|
Pat::Slice { prefix, slice, suffix } => {
|
||||||
pattern_matching_dereference(&mut cond_ty, &mut binding_mode, &mut cond_place);
|
pattern_matching_dereference(&mut cond_ty, &mut binding_mode, &mut cond_place);
|
||||||
for (i, &pat) in prefix.iter().enumerate() {
|
for (i, &pat) in prefix.iter().enumerate() {
|
||||||
let mut next_place = cond_place.clone();
|
let next_place = cond_place.project(ProjectionElem::ConstantIndex {
|
||||||
next_place
|
offset: i as u64,
|
||||||
.projection
|
from_end: false,
|
||||||
.push(ProjectionElem::ConstantIndex { offset: i as u64, from_end: false });
|
});
|
||||||
let cond_ty = self.infer[pat].clone();
|
let cond_ty = self.infer[pat].clone();
|
||||||
(current, current_else) = self.pattern_match(
|
(current, current_else) = self.pattern_match(
|
||||||
current,
|
current,
|
||||||
@ -126,8 +126,7 @@ impl MirLowerCtx<'_> {
|
|||||||
}
|
}
|
||||||
if let Some(slice) = slice {
|
if let Some(slice) = slice {
|
||||||
if let Pat::Bind { id, subpat: _ } = self.body[*slice] {
|
if let Pat::Bind { id, subpat: _ } = self.body[*slice] {
|
||||||
let mut next_place = cond_place.clone();
|
let next_place = cond_place.project(ProjectionElem::Subslice {
|
||||||
next_place.projection.push(ProjectionElem::Subslice {
|
|
||||||
from: prefix.len() as u64,
|
from: prefix.len() as u64,
|
||||||
to: suffix.len() as u64,
|
to: suffix.len() as u64,
|
||||||
});
|
});
|
||||||
@ -142,10 +141,10 @@ impl MirLowerCtx<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i, &pat) in suffix.iter().enumerate() {
|
for (i, &pat) in suffix.iter().enumerate() {
|
||||||
let mut next_place = cond_place.clone();
|
let next_place = cond_place.project(ProjectionElem::ConstantIndex {
|
||||||
next_place
|
offset: i as u64,
|
||||||
.projection
|
from_end: true,
|
||||||
.push(ProjectionElem::ConstantIndex { offset: i as u64, from_end: true });
|
});
|
||||||
let cond_ty = self.infer[pat].clone();
|
let cond_ty = self.infer[pat].clone();
|
||||||
(current, current_else) = self.pattern_match(
|
(current, current_else) = self.pattern_match(
|
||||||
current,
|
current,
|
||||||
@ -269,11 +268,10 @@ impl MirLowerCtx<'_> {
|
|||||||
Pat::Ref { pat, mutability: _ } => {
|
Pat::Ref { pat, mutability: _ } => {
|
||||||
if let Some((ty, _, _)) = cond_ty.as_reference() {
|
if let Some((ty, _, _)) = cond_ty.as_reference() {
|
||||||
cond_ty = ty.clone();
|
cond_ty = ty.clone();
|
||||||
cond_place.projection.push(ProjectionElem::Deref);
|
|
||||||
self.pattern_match(
|
self.pattern_match(
|
||||||
current,
|
current,
|
||||||
current_else,
|
current_else,
|
||||||
cond_place,
|
cond_place.project(ProjectionElem::Deref),
|
||||||
cond_ty,
|
cond_ty,
|
||||||
*pat,
|
*pat,
|
||||||
binding_mode,
|
binding_mode,
|
||||||
@ -479,8 +477,7 @@ impl MirLowerCtx<'_> {
|
|||||||
binding_mode: BindingAnnotation,
|
binding_mode: BindingAnnotation,
|
||||||
) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
|
) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
|
||||||
for (proj, arg, ty) in args {
|
for (proj, arg, ty) in args {
|
||||||
let mut cond_place = cond_place.clone();
|
let cond_place = cond_place.project(proj);
|
||||||
cond_place.projection.push(proj);
|
|
||||||
(current, current_else) =
|
(current, current_else) =
|
||||||
self.pattern_match(current, current_else, cond_place, ty, arg, binding_mode)?;
|
self.pattern_match(current, current_else, cond_place, ty, arg, binding_mode)?;
|
||||||
}
|
}
|
||||||
@ -513,5 +510,11 @@ fn pattern_matching_dereference(
|
|||||||
cond_place: &mut Place,
|
cond_place: &mut Place,
|
||||||
) {
|
) {
|
||||||
let cnt = pattern_matching_dereference_count(cond_ty, binding_mode);
|
let cnt = pattern_matching_dereference_count(cond_ty, binding_mode);
|
||||||
cond_place.projection.extend((0..cnt).map(|_| ProjectionElem::Deref));
|
cond_place.projection = cond_place
|
||||||
|
.projection
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.chain((0..cnt).map(|_| ProjectionElem::Deref))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user