mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-03 16:58:46 +00:00
Add mir lower support for tuple destructing assignment
This commit is contained in:
parent
9b636e2326
commit
b96e4f2f4a
2 changed files with 65 additions and 0 deletions
|
@ -1203,6 +1203,27 @@ fn destructing_assignment() {
|
||||||
"#,
|
"#,
|
||||||
5,
|
5,
|
||||||
);
|
);
|
||||||
|
check_number(
|
||||||
|
r#"
|
||||||
|
const GOAL: u8 = {
|
||||||
|
let (mut a, mut b) = (2, 5);
|
||||||
|
(a, b) = (b, a);
|
||||||
|
a * 10 + b
|
||||||
|
};
|
||||||
|
"#,
|
||||||
|
52,
|
||||||
|
);
|
||||||
|
check_number(
|
||||||
|
r#"
|
||||||
|
struct Point { x: i32, y: i32 }
|
||||||
|
const GOAL: i32 = {
|
||||||
|
let mut p = Point { x: 5, y: 6 };
|
||||||
|
(p.x, _) = (p.y, p.x);
|
||||||
|
p.x * 10 + p.y
|
||||||
|
};
|
||||||
|
"#,
|
||||||
|
66,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1244,6 +1244,41 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lower_destructing_assignment(
|
||||||
|
&mut self,
|
||||||
|
mut current: BasicBlockId,
|
||||||
|
lhs: ExprId,
|
||||||
|
rhs: Place,
|
||||||
|
span: MirSpan,
|
||||||
|
) -> Result<Option<BasicBlockId>> {
|
||||||
|
match &self.body.exprs[lhs] {
|
||||||
|
Expr::Tuple { exprs, is_assignee_expr: _ } => {
|
||||||
|
for (i, expr) in exprs.iter().enumerate() {
|
||||||
|
let Some(c) = self.lower_destructing_assignment(
|
||||||
|
current,
|
||||||
|
*expr,
|
||||||
|
rhs.project(ProjectionElem::TupleOrClosureField(i)),
|
||||||
|
span,
|
||||||
|
)? else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
current = c;
|
||||||
|
}
|
||||||
|
Ok(Some(current))
|
||||||
|
}
|
||||||
|
Expr::Underscore => Ok(Some(current)),
|
||||||
|
_ => {
|
||||||
|
let Some((lhs_place, current)) =
|
||||||
|
self.lower_expr_as_place(current, lhs, false)?
|
||||||
|
else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
self.push_assignment(current, lhs_place, Operand::Copy(rhs).into(), span);
|
||||||
|
Ok(Some(current))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn lower_assignment(
|
fn lower_assignment(
|
||||||
&mut self,
|
&mut self,
|
||||||
current: BasicBlockId,
|
current: BasicBlockId,
|
||||||
|
@ -1259,6 +1294,15 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
||||||
if matches!(&self.body.exprs[lhs], Expr::Underscore) {
|
if matches!(&self.body.exprs[lhs], Expr::Underscore) {
|
||||||
return Ok(Some(current));
|
return Ok(Some(current));
|
||||||
}
|
}
|
||||||
|
if matches!(
|
||||||
|
&self.body.exprs[lhs],
|
||||||
|
Expr::Tuple { .. } | Expr::RecordLit { .. } | Expr::Call { .. }
|
||||||
|
) {
|
||||||
|
let temp = self.temp(self.expr_ty_after_adjustments(rhs), current, rhs.into())?;
|
||||||
|
let temp = Place::from(temp);
|
||||||
|
self.push_assignment(current, temp.clone(), rhs_op.into(), span);
|
||||||
|
return self.lower_destructing_assignment(current, lhs, temp, span);
|
||||||
|
}
|
||||||
let Some((lhs_place, current)) =
|
let Some((lhs_place, current)) =
|
||||||
self.lower_expr_as_place(current, lhs, false)?
|
self.lower_expr_as_place(current, lhs, false)?
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Reference in a new issue