mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-08-19 01:50:32 +00:00
Merge #11598
11598: feat: Parse destructuring assignment r=Veykril a=ChayimFriedman2 Part of #11532. Lowering is not as easy and may not even be feasible right now as it requires generating identifiers: `(a, b) = (b, a)` is desugared into ```rust { let (<gensym_a>, <gensym_b>) = (b, a); a = <gensym_a>; b = <gensym_b>; } ``` rustc uses hygiene to implement that, but we don't support hygiene yet. However, I think parsing was the main problem as lowering will just affect type inference, and while `{unknown}` is not nice it's much better than a syntax error. I'm still looking for the best way to do lowering, though. Fixes #11454. Co-authored-by: Chayim Refael Friedman <chayimfr@gmail.com>
This commit is contained in:
commit
8f504dc873
20 changed files with 582 additions and 221 deletions
|
@ -30,7 +30,7 @@ rayon = "1"
|
|||
expect-test = "1.2.0-pre.1"
|
||||
proc-macro2 = "1.0.8"
|
||||
quote = "1.0.2"
|
||||
ungrammar = "=1.15.0"
|
||||
ungrammar = "=1.16.0"
|
||||
|
||||
test_utils = { path = "../test_utils" }
|
||||
sourcegen = { path = "../sourcegen" }
|
||||
|
|
|
@ -262,6 +262,7 @@ pub struct ExternBlock {
|
|||
impl ast::HasAttrs for ExternBlock {}
|
||||
impl ast::HasDocComments for ExternBlock {}
|
||||
impl ExternBlock {
|
||||
pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
|
||||
pub fn abi(&self) -> Option<Abi> { support::child(&self.syntax) }
|
||||
pub fn extern_item_list(&self) -> Option<ExternItemList> { support::child(&self.syntax) }
|
||||
}
|
||||
|
@ -1062,6 +1063,15 @@ impl LetExpr {
|
|||
pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct UnderscoreExpr {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl ast::HasAttrs for UnderscoreExpr {}
|
||||
impl UnderscoreExpr {
|
||||
pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct StmtList {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
|
@ -1522,6 +1532,7 @@ pub enum Expr {
|
|||
WhileExpr(WhileExpr),
|
||||
YieldExpr(YieldExpr),
|
||||
LetExpr(LetExpr),
|
||||
UnderscoreExpr(UnderscoreExpr),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
@ -2673,6 +2684,17 @@ impl AstNode for LetExpr {
|
|||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for UnderscoreExpr {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == UNDERSCORE_EXPR }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl AstNode for StmtList {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == STMT_LIST }
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
|
@ -3337,6 +3359,9 @@ impl From<YieldExpr> for Expr {
|
|||
impl From<LetExpr> for Expr {
|
||||
fn from(node: LetExpr) -> Expr { Expr::LetExpr(node) }
|
||||
}
|
||||
impl From<UnderscoreExpr> for Expr {
|
||||
fn from(node: UnderscoreExpr) -> Expr { Expr::UnderscoreExpr(node) }
|
||||
}
|
||||
impl AstNode for Expr {
|
||||
fn can_cast(kind: SyntaxKind) -> bool {
|
||||
match kind {
|
||||
|
@ -3345,7 +3370,7 @@ impl AstNode for Expr {
|
|||
| INDEX_EXPR | LITERAL | LOOP_EXPR | MACRO_CALL | MACRO_STMTS | MATCH_EXPR
|
||||
| METHOD_CALL_EXPR | PAREN_EXPR | PATH_EXPR | PREFIX_EXPR | RANGE_EXPR
|
||||
| RECORD_EXPR | REF_EXPR | RETURN_EXPR | TRY_EXPR | TUPLE_EXPR | WHILE_EXPR
|
||||
| YIELD_EXPR | LET_EXPR => true,
|
||||
| YIELD_EXPR | LET_EXPR | UNDERSCORE_EXPR => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -3383,6 +3408,7 @@ impl AstNode for Expr {
|
|||
WHILE_EXPR => Expr::WhileExpr(WhileExpr { syntax }),
|
||||
YIELD_EXPR => Expr::YieldExpr(YieldExpr { syntax }),
|
||||
LET_EXPR => Expr::LetExpr(LetExpr { syntax }),
|
||||
UNDERSCORE_EXPR => Expr::UnderscoreExpr(UnderscoreExpr { syntax }),
|
||||
_ => return None,
|
||||
};
|
||||
Some(res)
|
||||
|
@ -3421,6 +3447,7 @@ impl AstNode for Expr {
|
|||
Expr::WhileExpr(it) => &it.syntax,
|
||||
Expr::YieldExpr(it) => &it.syntax,
|
||||
Expr::LetExpr(it) => &it.syntax,
|
||||
Expr::UnderscoreExpr(it) => &it.syntax,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3887,6 +3914,7 @@ impl AstNode for AnyHasAttrs {
|
|||
| WHILE_EXPR
|
||||
| YIELD_EXPR
|
||||
| LET_EXPR
|
||||
| UNDERSCORE_EXPR
|
||||
| STMT_LIST
|
||||
| RECORD_EXPR_FIELD_LIST
|
||||
| RECORD_EXPR_FIELD
|
||||
|
@ -4546,6 +4574,11 @@ impl std::fmt::Display for LetExpr {
|
|||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for UnderscoreExpr {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for StmtList {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
|
|
|
@ -143,6 +143,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
|
|||
"RETURN_EXPR",
|
||||
"YIELD_EXPR",
|
||||
"LET_EXPR",
|
||||
"UNDERSCORE_EXPR",
|
||||
"MATCH_EXPR",
|
||||
"MATCH_ARM_LIST",
|
||||
"MATCH_ARM",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue