feat: parse `super let`
diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs
index 5b0085f..34dcf2a 100644
--- a/crates/parser/src/grammar/expressions.rs
+++ b/crates/parser/src/grammar/expressions.rs
@@ -58,7 +58,7 @@
     // }
     attributes::outer_attrs(p);
 
-    if p.at(T![let]) {
+    if p.at(T![let]) || (p.at(T![super]) && p.nth_at(1, T![let])) {
         let_stmt(p, semicolon);
         m.complete(p, LET_STMT);
         return;
@@ -113,8 +113,9 @@
 }
 
 // test let_stmt
-// fn f() { let x: i32 = 92; }
+// fn f() { let x: i32 = 92; super let y; super::foo; }
 pub(super) fn let_stmt(p: &mut Parser<'_>, with_semi: Semicolon) {
+    p.eat(T![super]);
     p.bump(T![let]);
     patterns::pattern(p);
     if p.at(T![:]) {
diff --git a/crates/parser/test_data/parser/inline/ok/let_stmt.rast b/crates/parser/test_data/parser/inline/ok/let_stmt.rast
index de9d0fc..d99dad4 100644
--- a/crates/parser/test_data/parser/inline/ok/let_stmt.rast
+++ b/crates/parser/test_data/parser/inline/ok/let_stmt.rast
@@ -32,5 +32,28 @@
             INT_NUMBER "92"
           SEMICOLON ";"
         WHITESPACE " "
+        LET_STMT
+          SUPER_KW "super"
+          WHITESPACE " "
+          LET_KW "let"
+          WHITESPACE " "
+          IDENT_PAT
+            NAME
+              IDENT "y"
+          SEMICOLON ";"
+        WHITESPACE " "
+        EXPR_STMT
+          PATH_EXPR
+            PATH
+              PATH
+                PATH_SEGMENT
+                  NAME_REF
+                    SUPER_KW "super"
+              COLON2 "::"
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "foo"
+          SEMICOLON ";"
+        WHITESPACE " "
         R_CURLY "}"
   WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/let_stmt.rs b/crates/parser/test_data/parser/inline/ok/let_stmt.rs
index 8003999..d4cc1be 100644
--- a/crates/parser/test_data/parser/inline/ok/let_stmt.rs
+++ b/crates/parser/test_data/parser/inline/ok/let_stmt.rs
@@ -1 +1 @@
-fn f() { let x: i32 = 92; }
+fn f() { let x: i32 = 92; super let y; super::foo; }
diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram
index 673334b..a055ed7 100644
--- a/crates/syntax/rust.ungram
+++ b/crates/syntax/rust.ungram
@@ -348,7 +348,7 @@
 | LetStmt
 
 LetStmt =
-  Attr* 'let' Pat (':' Type)?
+  Attr* 'super'? 'let' Pat (':' Type)?
   '=' initializer:Expr
   LetElse?
   ';'
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index fd23cdc..83ef2d2 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -823,6 +823,8 @@
     pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
     #[inline]
     pub fn let_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![let]) }
+    #[inline]
+    pub fn super_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![super]) }
 }
 pub struct Lifetime {
     pub(crate) syntax: SyntaxNode,