Skip to content

Commit b96e4f2

Browse files
committed
Add mir lower support for tuple destructing assignment
1 parent 9b636e2 commit b96e4f2

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

crates/hir-ty/src/consteval/tests.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,27 @@ fn destructing_assignment() {
12031203
"#,
12041204
5,
12051205
);
1206+
check_number(
1207+
r#"
1208+
const GOAL: u8 = {
1209+
let (mut a, mut b) = (2, 5);
1210+
(a, b) = (b, a);
1211+
a * 10 + b
1212+
};
1213+
"#,
1214+
52,
1215+
);
1216+
check_number(
1217+
r#"
1218+
struct Point { x: i32, y: i32 }
1219+
const GOAL: i32 = {
1220+
let mut p = Point { x: 5, y: 6 };
1221+
(p.x, _) = (p.y, p.x);
1222+
p.x * 10 + p.y
1223+
};
1224+
"#,
1225+
66,
1226+
);
12061227
}
12071228

12081229
#[test]

crates/hir-ty/src/mir/lower.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,41 @@ impl<'ctx> MirLowerCtx<'ctx> {
12441244
}
12451245
}
12461246

1247+
fn lower_destructing_assignment(
1248+
&mut self,
1249+
mut current: BasicBlockId,
1250+
lhs: ExprId,
1251+
rhs: Place,
1252+
span: MirSpan,
1253+
) -> Result<Option<BasicBlockId>> {
1254+
match &self.body.exprs[lhs] {
1255+
Expr::Tuple { exprs, is_assignee_expr: _ } => {
1256+
for (i, expr) in exprs.iter().enumerate() {
1257+
let Some(c) = self.lower_destructing_assignment(
1258+
current,
1259+
*expr,
1260+
rhs.project(ProjectionElem::TupleOrClosureField(i)),
1261+
span,
1262+
)? else {
1263+
return Ok(None);
1264+
};
1265+
current = c;
1266+
}
1267+
Ok(Some(current))
1268+
}
1269+
Expr::Underscore => Ok(Some(current)),
1270+
_ => {
1271+
let Some((lhs_place, current)) =
1272+
self.lower_expr_as_place(current, lhs, false)?
1273+
else {
1274+
return Ok(None);
1275+
};
1276+
self.push_assignment(current, lhs_place, Operand::Copy(rhs).into(), span);
1277+
Ok(Some(current))
1278+
}
1279+
}
1280+
}
1281+
12471282
fn lower_assignment(
12481283
&mut self,
12491284
current: BasicBlockId,
@@ -1259,6 +1294,15 @@ impl<'ctx> MirLowerCtx<'ctx> {
12591294
if matches!(&self.body.exprs[lhs], Expr::Underscore) {
12601295
return Ok(Some(current));
12611296
}
1297+
if matches!(
1298+
&self.body.exprs[lhs],
1299+
Expr::Tuple { .. } | Expr::RecordLit { .. } | Expr::Call { .. }
1300+
) {
1301+
let temp = self.temp(self.expr_ty_after_adjustments(rhs), current, rhs.into())?;
1302+
let temp = Place::from(temp);
1303+
self.push_assignment(current, temp.clone(), rhs_op.into(), span);
1304+
return self.lower_destructing_assignment(current, lhs, temp, span);
1305+
}
12621306
let Some((lhs_place, current)) =
12631307
self.lower_expr_as_place(current, lhs, false)?
12641308
else {

0 commit comments

Comments
 (0)