Description
Hm, to me it seems correct to use pat..pat
in the syntax, but expr..expr
in the hir.
Syntactically, they are patterns, as ..
is an infix binary operator. We could add some LR-style re-structuring of the tree, where we don't create a pat until we haven't seen ..
, but that seems complicated. Feels more natural to parse a pat, than notice an ..
, and parse another pat
.
But yeah, in semantics we want to keep those as expressions, so during lowering we need to figure out that, what was a pattern syntactically, actually is an expression semantically.
This feel dual to recently stabilized destructive assignment, where we parse stuff like (a, b) = (b, a)
as expr = expr
, but, during lowering, lower the LHS as a pattern.
Though, seeing the two example side-by-side, maybe we should bite the bullet and just don't distinguish patterns and expressions at the level of syntax? That is, we'd use ast::Expr
for both patterns and expressions. We'd then have an API like
impl ast::Expr {
fn classify(&self) -> IsPattern | IsExpression | Ambiguous
}
impl Semnatics {
fn classify_expr(&self, expr: &ast::Expr) -> IsPattern | IsExpression
}
Originally posted by @matklad in #12158 (comment)