Handle destructuring assignments uniformly

Instead of lowering them to `<expr> = <expr>`, then hacking on-demand to resolve them, we lower them to `<pat> = <expr>`, and use the pattern infrastructure to handle them. It turns out, destructuring assignments are surprisingly similar to pattern bindings, and so only minor modifications are needed.

This fixes few bugs that arose because of the non-uniform handling (for example, MIR lowering not handling slice and record patterns, and closure capture calculation not handling destructuring assignments at all), and furthermore, guarantees we won't have such bugs in the future, since the programmer will always have to explicitly handle `Expr::Assignment`.

Tests don't pass yet; that's because the generated patterns do not exist in the source map. The next commit will fix that.
This commit is contained in:
Chayim Refael Friedman 2024-10-06 18:14:07 +03:00
parent 4379153e59
commit 61f162a43d
20 changed files with 886 additions and 707 deletions

View file

@ -546,10 +546,7 @@ pub fn record_literal_missing_fields(
expr: &Expr,
) -> Option<(VariantId, Vec<LocalFieldId>, /*exhaustive*/ bool)> {
let (fields, exhaustive) = match expr {
Expr::RecordLit { fields, spread, ellipsis, is_assignee_expr, .. } => {
let exhaustive = if *is_assignee_expr { !*ellipsis } else { spread.is_none() };
(fields, exhaustive)
}
Expr::RecordLit { fields, spread, .. } => (fields, spread.is_none()),
_ => return None,
};