cairo_lang_parser/
parser.rs

1use std::mem;
2
3use cairo_lang_diagnostics::DiagnosticsBuilder;
4use cairo_lang_filesystem::ids::FileId;
5use cairo_lang_filesystem::span::{TextOffset, TextSpan, TextWidth};
6use cairo_lang_primitive_token::{PrimitiveToken, ToPrimitiveTokenStream};
7use cairo_lang_syntax as syntax;
8use cairo_lang_syntax::node::ast::*;
9use cairo_lang_syntax::node::db::SyntaxGroup;
10use cairo_lang_syntax::node::helpers::GetIdentifier;
11use cairo_lang_syntax::node::kind::SyntaxKind;
12use cairo_lang_syntax::node::{SyntaxNode, Token, TypedSyntaxNode};
13use cairo_lang_utils::{LookupIntern, extract_matches, require};
14use syntax::node::green::{GreenNode, GreenNodeDetails};
15use syntax::node::ids::GreenId;
16
17use crate::ParserDiagnostic;
18use crate::diagnostic::ParserDiagnosticKind;
19use crate::lexer::{Lexer, LexerTerminal};
20use crate::operators::{get_post_operator_precedence, get_unary_operator_precedence};
21use crate::recovery::is_of_kind;
22use crate::utils::primitive_token_stream_content_and_offset;
23use crate::validation::{
24    ValidationError, ValidationLocation, validate_literal_number, validate_short_string,
25    validate_string,
26};
27
28#[cfg(test)]
29#[path = "parser_test.rs"]
30mod test;
31
32#[derive(PartialEq)]
33enum MacroParsingContext {
34    /// The code being parsed is a part of a macro rule.
35    MacroRule,
36    /// The code being parsed is a part of a macro expansion.
37    MacroExpansion,
38    /// The code being parsed was generated by a macro expansion.
39    ExpandedMacro,
40    /// None of the above.
41    None,
42}
43
44pub struct Parser<'a> {
45    db: &'a dyn SyntaxGroup,
46    file_id: FileId,
47    lexer: Lexer<'a>,
48    /// The next terminal to handle.
49    next_terminal: LexerTerminal,
50    /// The terminal following [Self::next_terminal], if known.
51    next_next_terminal: Option<LexerTerminal>,
52    /// A vector of pending trivia to be added as leading trivia to the next valid terminal.
53    pending_trivia: Vec<TriviumGreen>,
54    /// The current offset, excluding the current terminal.
55    offset: TextOffset,
56    /// The width of the current terminal being handled (excluding the trivia length of this
57    /// terminal).
58    current_width: TextWidth,
59    /// The length of the trailing trivia following the last read token.
60    last_trivia_length: TextWidth,
61    diagnostics: &'a mut DiagnosticsBuilder<ParserDiagnostic>,
62    /// An accumulating vector of pending skipped tokens diagnostics.
63    pending_skipped_token_diagnostics: Vec<PendingParserDiagnostic>,
64    /// An indicator if we are inside a macro rule expansion.
65    macro_parsing_context: MacroParsingContext,
66}
67
68/// The possible results of a try_parse_* function failing to parse.
69#[derive(PartialEq, Debug)]
70pub enum TryParseFailure {
71    /// The parsing failed, and no token was consumed, the current token is the token which caused
72    /// the failure and thus should be skipped by the caller.
73    SkipToken,
74    /// The parsing failed, some tokens were consumed, and the current token is yet to be
75    /// processed. Should be used when the failure cannot be
76    /// determined by the first token alone, and thus the tokens until the token which
77    /// determines the failure should be consumed.
78    DoNothing,
79}
80/// The result of a try_parse_* functions.
81pub type TryParseResult<GreenElement> = Result<GreenElement, TryParseFailure>;
82
83// ====================================== Naming of items ======================================
84// To avoid confusion, there is a naming convention for the language items.
85// An item is called <item_scope>Item<item_kind>, where item_scope is in {Module, Trait, Impl}, and
86// item_kind is in {Const, Enum, ExternFunction, ExternType, Function, Impl, InlineMacro, Module,
87// Struct, Trait, Type, TypeAlias, Use} (note not all combinations are supported).
88// For example, ModuleItemFunction is a function item in a module, TraitItemConst is a const item in
89// a trait.
90
91// ================================ Naming of parsing functions ================================
92// try_parse_<something>: returns a TryParseElementResult. A `Ok` with green ID with a kind
93// that represents 'something' or a `Err` if 'something' can't be parsed.
94// If the error kind is Failure, the current token is not consumed, otherwise (Success or
95// error of kind FailureAndSkipped) it is (taken or skipped). Used when something may or may not be
96// there and we can act differently according to each case.
97//
98// parse_option_<something>: returns a green ID with a kind that represents 'something'. If
99// 'something' can't be parsed, returns a green ID with the relevant empty kind. Used for an
100// optional child. Always returns some green ID.
101//
102// parse_<something>: returns a green ID with a kind that represents 'something'. If
103// 'something' can't be parsed, returns a green ID with the relevant missing kind. Used when we
104// expect 'something' to be there. Always returns some green ID.
105//
106// expect_<something>: similar to parse_<something>, but assumes the current token is as expected.
107// Therefore, it always returns a GreenId of a node with a kind that represents 'something' and
108// never a missing kind.
109// Should only be called after checking the current token.
110
111const MAX_PRECEDENCE: usize = 1000;
112const MODULE_ITEM_DESCRIPTION: &str = "Const/Enum/ExternFunction/ExternType/Function/Impl/\
113                                       InlineMacro/Module/Struct/Trait/TypeAlias/Use";
114const TRAIT_ITEM_DESCRIPTION: &str = "Const/Function/Impl/Type";
115const IMPL_ITEM_DESCRIPTION: &str = "Const/Function/Impl/Type";
116
117// A macro adding "or an attribute" to the end of a string.
118macro_rules! or_an_attribute {
119    ($string:expr) => {
120        format!("{} or an attribute", $string)
121    };
122}
123
124impl<'a> Parser<'a> {
125    /// Creates a new parser.
126    pub fn new(
127        db: &'a dyn SyntaxGroup,
128        file_id: FileId,
129        text: &'a str,
130        diagnostics: &'a mut DiagnosticsBuilder<ParserDiagnostic>,
131    ) -> Self {
132        let mut lexer = Lexer::from_text(db, text);
133        let next_terminal = lexer.next().unwrap();
134        Parser {
135            db,
136            file_id,
137            lexer,
138            next_terminal,
139            next_next_terminal: None,
140            pending_trivia: Vec::new(),
141            offset: Default::default(),
142            current_width: Default::default(),
143            last_trivia_length: Default::default(),
144            diagnostics,
145            pending_skipped_token_diagnostics: Vec::new(),
146            macro_parsing_context: MacroParsingContext::None,
147        }
148    }
149
150    /// Adds a diagnostic to the parser diagnostics collection.
151    pub fn add_diagnostic(&mut self, kind: ParserDiagnosticKind, span: TextSpan) {
152        self.diagnostics.add(ParserDiagnostic { file_id: self.file_id, kind, span });
153    }
154
155    /// Parses a file.
156    pub fn parse_file(
157        db: &'a dyn SyntaxGroup,
158        diagnostics: &mut DiagnosticsBuilder<ParserDiagnostic>,
159        file_id: FileId,
160        text: &'a str,
161    ) -> SyntaxFile {
162        let parser = Parser::new(db, file_id, text, diagnostics);
163        let green = parser.parse_syntax_file();
164        SyntaxFile::from_syntax_node(db, SyntaxNode::new_root(db, file_id, green.0))
165    }
166
167    /// Parses a file expr.
168    pub fn parse_file_expr(
169        db: &'a dyn SyntaxGroup,
170        diagnostics: &mut DiagnosticsBuilder<ParserDiagnostic>,
171        file_id: FileId,
172        text: &'a str,
173    ) -> Expr {
174        let mut parser = Parser::new(db, file_id, text, diagnostics);
175        parser.macro_parsing_context = MacroParsingContext::ExpandedMacro;
176        let green = parser.parse_expr();
177        if let Err(SkippedError(span)) = parser.skip_until(is_of_kind!()) {
178            parser.add_diagnostic(
179                ParserDiagnosticKind::SkippedElement { element_name: "end of expr".into() },
180                span,
181            );
182        }
183        Expr::from_syntax_node(db, SyntaxNode::new_root(db, file_id, green.0))
184    }
185
186    /// Parses a file as a list of statements.
187    pub fn parse_file_statement_list(
188        db: &'a dyn SyntaxGroup,
189        diagnostics: &'a mut DiagnosticsBuilder<ParserDiagnostic>,
190        file_id: FileId,
191        text: &'a str,
192    ) -> StatementList {
193        let mut parser = Parser::new(db, file_id, text, diagnostics);
194        parser.macro_parsing_context = MacroParsingContext::ExpandedMacro;
195        let statements = StatementList::new_green(
196            db,
197            &parser.parse_list(Self::try_parse_statement, Self::is_eof, "statement"),
198        );
199        StatementList::from_syntax_node(db, SyntaxNode::new_root(db, file_id, statements.0))
200    }
201
202    /// Checks if the given kind is an end of file token.
203    pub fn is_eof(kind: SyntaxKind) -> bool {
204        kind == SyntaxKind::TerminalEndOfFile
205    }
206
207    /// Parses a token stream.
208    pub fn parse_token_stream(
209        db: &'a dyn SyntaxGroup,
210        diagnostics: &mut DiagnosticsBuilder<ParserDiagnostic>,
211        file_id: FileId,
212        token_stream: &'a dyn ToPrimitiveTokenStream<Iter = impl Iterator<Item = PrimitiveToken>>,
213    ) -> SyntaxFile {
214        let (content, offset) = primitive_token_stream_content_and_offset(token_stream);
215        let parser = Parser::new(db, file_id, &content, diagnostics);
216        let green = parser.parse_syntax_file();
217        SyntaxFile::from_syntax_node(
218            db,
219            SyntaxNode::new_root_with_offset(db, file_id, green.0, offset),
220        )
221    }
222
223    /// Parses a token stream expression.
224    pub fn parse_token_stream_expr(
225        db: &'a dyn SyntaxGroup,
226        diagnostics: &mut DiagnosticsBuilder<ParserDiagnostic>,
227        file_id: FileId,
228        content: &str,
229        offset: Option<TextOffset>,
230    ) -> Expr {
231        let mut parser = Parser::new(db, file_id, content, diagnostics);
232        let green = parser.parse_expr();
233        if let Err(SkippedError(span)) = parser.skip_until(is_of_kind!()) {
234            parser.diagnostics.add(ParserDiagnostic {
235                file_id: parser.file_id,
236                kind: ParserDiagnosticKind::SkippedElement { element_name: "end of expr".into() },
237                span,
238            });
239        }
240        Expr::from_syntax_node(db, SyntaxNode::new_root_with_offset(db, file_id, green.0, offset))
241    }
242
243    /// Returns a GreenId of an ExprMissing and adds a diagnostic describing it.
244    fn create_and_report_missing<T: TypedSyntaxNode>(
245        &mut self,
246        missing_kind: ParserDiagnosticKind,
247    ) -> T::Green {
248        let next_offset = self.offset.add_width(self.current_width - self.last_trivia_length);
249        self.add_diagnostic(missing_kind, TextSpan { start: next_offset, end: next_offset });
250        T::missing(self.db)
251    }
252
253    /// Returns the missing terminal and adds the corresponding missing token
254    /// diagnostic report.
255    fn create_and_report_missing_terminal<Terminal: syntax::node::Terminal>(
256        &mut self,
257    ) -> Terminal::Green {
258        self.create_and_report_missing::<Terminal>(ParserDiagnosticKind::MissingToken(
259            Terminal::KIND,
260        ))
261    }
262
263    pub fn parse_syntax_file(mut self) -> SyntaxFileGreen {
264        let mut module_items = vec![];
265        if let Some(doc_item) = self.take_doc() {
266            module_items.push(doc_item.into());
267        }
268        module_items.extend(self.parse_attributed_list(
269            Self::try_parse_module_item,
270            is_of_kind!(),
271            MODULE_ITEM_DESCRIPTION,
272        ));
273        // Create a new vec with the doc item as the children.
274        let items = ModuleItemList::new_green(self.db, &module_items);
275        // This will not panic since the above parsing only stops when reaches EOF.
276        assert_eq!(self.peek().kind, SyntaxKind::TerminalEndOfFile);
277
278        // Fix offset in case there are skipped tokens before EOF. This is usually done in
279        // self.take_raw() but here we don't call self.take_raw as it tries to read the next
280        // token, which doesn't exist.
281        self.offset = self.offset.add_width(self.current_width);
282
283        let eof = self.add_trivia_to_terminal::<TerminalEndOfFile>(self.next_terminal.clone());
284        SyntaxFile::new_green(self.db, items, eof)
285    }
286
287    // ------------------------------- Module items -------------------------------
288
289    /// Returns a GreenId of a node with an Item.* kind (see [syntax::node::ast::ModuleItem]), or
290    /// TryParseFailure if a module item can't be parsed.
291    /// In case of an identifier not followed by a `!`, it is skipped inside the function and thus a
292    /// TryParseFailure::DoNothing is returned.
293    pub fn try_parse_module_item(&mut self) -> TryParseResult<ModuleItemGreen> {
294        let maybe_attributes = self.try_parse_attribute_list(MODULE_ITEM_DESCRIPTION);
295        let (has_attrs, attributes) = match maybe_attributes {
296            Ok(attributes) => (true, attributes),
297            Err(_) => (false, AttributeList::new_green(self.db, &[])),
298        };
299        let post_attributes_offset = self.offset.add_width(self.current_width);
300
301        let visibility_pub = self.try_parse_visibility_pub();
302        let visibility = match visibility_pub {
303            Some(visibility) => visibility.into(),
304            None => VisibilityDefault::new_green(self.db).into(),
305        };
306        let post_visibility_offset = self.offset.add_width(self.current_width);
307
308        match self.peek().kind {
309            SyntaxKind::TerminalConst => {
310                let const_kw = self.take::<TerminalConst>();
311                Ok(if self.peek().kind == SyntaxKind::TerminalFunction {
312                    self.expect_item_function_with_body(attributes, visibility, const_kw.into())
313                        .into()
314                } else {
315                    self.expect_item_const(attributes, visibility, const_kw).into()
316                })
317            }
318            SyntaxKind::TerminalModule => {
319                Ok(self.expect_item_module(attributes, visibility).into())
320            }
321            SyntaxKind::TerminalStruct => {
322                Ok(self.expect_item_struct(attributes, visibility).into())
323            }
324            SyntaxKind::TerminalEnum => Ok(self.expect_item_enum(attributes, visibility).into()),
325            SyntaxKind::TerminalType => {
326                Ok(self.expect_item_type_alias(attributes, visibility).into())
327            }
328            SyntaxKind::TerminalExtern => Ok(self.expect_item_extern(attributes, visibility)),
329            SyntaxKind::TerminalFunction => Ok(self
330                .expect_item_function_with_body(
331                    attributes,
332                    visibility,
333                    OptionTerminalConstEmpty::new_green(self.db).into(),
334                )
335                .into()),
336            SyntaxKind::TerminalUse => Ok(self.expect_item_use(attributes, visibility).into()),
337            SyntaxKind::TerminalTrait => Ok(self.expect_item_trait(attributes, visibility).into()),
338            SyntaxKind::TerminalImpl => Ok(self.expect_module_item_impl(attributes, visibility)),
339            SyntaxKind::TerminalMacro => {
340                Ok(self.expect_item_macro_declaration(attributes, visibility).into())
341            }
342            SyntaxKind::TerminalIdentifier => {
343                // We take the identifier to check if the next token is a `!`. If it is, we assume
344                // that a macro is following and handle it similarly to any other module item. If
345                // not we skip the identifier. 'take_raw' is used here since it is not yet known if
346                // the identifier would be taken as a part of a macro, or skipped.
347                let path = self.parse_path();
348                let post_path_offset = self.offset.add_width(self.current_width);
349                match self.peek().kind {
350                    SyntaxKind::TerminalLParen
351                    | SyntaxKind::TerminalLBrace
352                    | SyntaxKind::TerminalLBrack => {
353                        // This case is treated as an item inline macro with a missing bang ('!').
354                        self.add_diagnostic(
355                            ParserDiagnosticKind::ItemInlineMacroWithoutBang {
356                                identifier: path.identifier(self.db).to_string().into(),
357                                bracket_type: self.peek().kind,
358                            },
359                            TextSpan {
360                                start: self.offset,
361                                end: self.offset.add_width(self.current_width),
362                            },
363                        );
364                        Ok(self
365                            .parse_item_inline_macro_given_bang(
366                                attributes,
367                                path,
368                                TerminalNot::missing(self.db),
369                            )
370                            .into())
371                    }
372                    SyntaxKind::TerminalNot => {
373                        Ok(self.expect_item_inline_macro(attributes, path).into())
374                    }
375                    _ => {
376                        if has_attrs {
377                            self.skip_taken_node_with_offset(
378                                attributes,
379                                ParserDiagnosticKind::SkippedElement {
380                                    element_name: or_an_attribute!(MODULE_ITEM_DESCRIPTION).into(),
381                                },
382                                post_attributes_offset,
383                            );
384                        }
385                        if let Some(visibility_pub) = visibility_pub {
386                            self.skip_taken_node_with_offset(
387                                visibility_pub,
388                                ParserDiagnosticKind::SkippedElement {
389                                    element_name: or_an_attribute!(MODULE_ITEM_DESCRIPTION).into(),
390                                },
391                                post_visibility_offset,
392                            );
393                        }
394                        // TODO(Dean): This produce a slightly worse diagnostic than before.
395                        self.skip_taken_node_with_offset(
396                            path,
397                            ParserDiagnosticKind::SkippedElement {
398                                element_name: or_an_attribute!(MODULE_ITEM_DESCRIPTION).into(),
399                            },
400                            post_path_offset,
401                        );
402                        // The token is already skipped, so it should not be skipped in the caller.
403                        Err(TryParseFailure::DoNothing)
404                    }
405                }
406            }
407            _ => {
408                let mut result = Err(TryParseFailure::SkipToken);
409                if has_attrs {
410                    self.skip_taken_node_with_offset(
411                        attributes,
412                        ParserDiagnosticKind::AttributesWithoutItem,
413                        post_attributes_offset,
414                    );
415                    result = Ok(ModuleItem::missing(self.db));
416                }
417                if let Some(visibility_pub) = visibility_pub {
418                    self.skip_taken_node_with_offset(
419                        visibility_pub,
420                        ParserDiagnosticKind::VisibilityWithoutItem,
421                        post_visibility_offset,
422                    );
423                    result = Ok(ModuleItem::missing(self.db));
424                }
425                result
426            }
427        }
428    }
429
430    /// Assumes the current token is Module.
431    /// Expected pattern: `mod <Identifier> \{<ItemList>\}` or `mod <Identifier>;`.
432    fn expect_item_module(
433        &mut self,
434        attributes: AttributeListGreen,
435        visibility: VisibilityGreen,
436    ) -> ItemModuleGreen {
437        let module_kw = self.take::<TerminalModule>();
438        let name = self.parse_identifier();
439
440        let body = match self.peek().kind {
441            SyntaxKind::TerminalLBrace => {
442                let lbrace = self.take::<TerminalLBrace>();
443                let mut module_items = vec![];
444                if let Some(doc_item) = self.take_doc() {
445                    module_items.push(doc_item.into());
446                }
447                module_items.extend(self.parse_attributed_list(
448                    Self::try_parse_module_item,
449                    is_of_kind!(rbrace),
450                    MODULE_ITEM_DESCRIPTION,
451                ));
452                let items = ModuleItemList::new_green(self.db, &module_items);
453                let rbrace = self.parse_token::<TerminalRBrace>();
454                ModuleBody::new_green(self.db, lbrace, items, rbrace).into()
455            }
456            SyntaxKind::TerminalSemicolon => self.take::<TerminalSemicolon>().into(),
457            _ => self
458                .create_and_report_missing::<TerminalSemicolon>(
459                    ParserDiagnosticKind::ExpectedSemicolonOrBody,
460                )
461                .into(),
462        };
463
464        ItemModule::new_green(self.db, attributes, visibility, module_kw, name, body)
465    }
466
467    /// Assumes the current token is Struct.
468    /// Expected pattern: `struct<Identifier>{<ParamList>}`
469    fn expect_item_struct(
470        &mut self,
471        attributes: AttributeListGreen,
472        visibility: VisibilityGreen,
473    ) -> ItemStructGreen {
474        let struct_kw = self.take::<TerminalStruct>();
475        let name = self.parse_identifier();
476        let generic_params = self.parse_optional_generic_params();
477        let lbrace = self.parse_token::<TerminalLBrace>();
478        let members = self.parse_member_list();
479        let rbrace = self.parse_token::<TerminalRBrace>();
480        ItemStruct::new_green(
481            self.db,
482            attributes,
483            visibility,
484            struct_kw,
485            name,
486            generic_params,
487            lbrace,
488            members,
489            rbrace,
490        )
491    }
492
493    /// Assumes the current token is Enum.
494    /// Expected pattern: `enum<Identifier>{<ParamList>}`
495    fn expect_item_enum(
496        &mut self,
497        attributes: AttributeListGreen,
498        visibility: VisibilityGreen,
499    ) -> ItemEnumGreen {
500        let enum_kw = self.take::<TerminalEnum>();
501        let name = self.parse_identifier();
502        let generic_params = self.parse_optional_generic_params();
503        let lbrace = self.parse_token::<TerminalLBrace>();
504        let variants = self.parse_variant_list();
505        let rbrace = self.parse_token::<TerminalRBrace>();
506        ItemEnum::new_green(
507            self.db,
508            attributes,
509            visibility,
510            enum_kw,
511            name,
512            generic_params,
513            lbrace,
514            variants,
515            rbrace,
516        )
517    }
518
519    /// Assumes the current token is type.
520    /// Expected pattern: `type <Identifier>{<ParamList>} = <TypeExpression>`
521    fn expect_item_type_alias(
522        &mut self,
523        attributes: AttributeListGreen,
524        visibility: VisibilityGreen,
525    ) -> ItemTypeAliasGreen {
526        let type_kw = self.take::<TerminalType>();
527        let name = self.parse_identifier();
528        let generic_params = self.parse_optional_generic_params();
529        let eq = self.parse_token::<TerminalEq>();
530        let ty = self.parse_type_expr();
531        let semicolon = self.parse_token::<TerminalSemicolon>();
532        ItemTypeAlias::new_green(
533            self.db,
534            attributes,
535            visibility,
536            type_kw,
537            name,
538            generic_params,
539            eq,
540            ty,
541            semicolon,
542        )
543    }
544
545    /// Expected pattern: `<ParenthesizedParamList><ReturnTypeClause>`
546    fn expect_function_signature(&mut self) -> FunctionSignatureGreen {
547        let lparen = self.parse_token::<TerminalLParen>();
548        let params = self.parse_param_list();
549        let rparen = self.parse_token::<TerminalRParen>();
550        let return_type_clause = self.parse_option_return_type_clause();
551        let implicits_clause = self.parse_option_implicits_clause();
552        let optional_no_panic = if self.peek().kind == SyntaxKind::TerminalNoPanic {
553            self.take::<TerminalNoPanic>().into()
554        } else {
555            OptionTerminalNoPanicEmpty::new_green(self.db).into()
556        };
557
558        FunctionSignature::new_green(
559            self.db,
560            lparen,
561            params,
562            rparen,
563            return_type_clause,
564            implicits_clause,
565            optional_no_panic,
566        )
567    }
568
569    /// Assumes the current token is [TerminalConst].
570    /// Expected pattern: `const <Identifier> = <Expr>;`
571    fn expect_item_const(
572        &mut self,
573        attributes: AttributeListGreen,
574        visibility: VisibilityGreen,
575        const_kw: TerminalConstGreen,
576    ) -> ItemConstantGreen {
577        let name = self.parse_identifier();
578        let type_clause = self.parse_type_clause(ErrorRecovery {
579            should_stop: is_of_kind!(eq, semicolon, module_item_kw),
580        });
581        let eq = self.parse_token::<TerminalEq>();
582        let expr = self.parse_expr();
583        let semicolon = self.parse_token::<TerminalSemicolon>();
584
585        ItemConstant::new_green(
586            self.db,
587            attributes,
588            visibility,
589            const_kw,
590            name,
591            type_clause,
592            eq,
593            expr,
594            semicolon,
595        )
596    }
597
598    /// Assumes the current token is Extern.
599    /// Expected pattern: `extern(<FunctionDeclaration>|type<Identifier>);`
600    fn expect_item_extern<T: From<ItemExternFunctionGreen> + From<ItemExternTypeGreen>>(
601        &mut self,
602        attributes: AttributeListGreen,
603        visibility: VisibilityGreen,
604    ) -> T {
605        match self.expect_item_extern_inner(attributes, visibility) {
606            ExternItem::Function(x) => x.into(),
607            ExternItem::Type(x) => x.into(),
608        }
609    }
610
611    /// Assumes the current token is Extern.
612    /// Expected pattern: `extern(<FunctionDeclaration>|type<Identifier>);`
613    fn expect_item_extern_inner(
614        &mut self,
615        attributes: AttributeListGreen,
616        visibility: VisibilityGreen,
617    ) -> ExternItem {
618        let extern_kw = self.take::<TerminalExtern>();
619        match self.peek().kind {
620            kind @ (SyntaxKind::TerminalFunction | SyntaxKind::TerminalConst) => {
621                let (optional_const, function_kw) = if kind == SyntaxKind::TerminalConst {
622                    (self.take::<TerminalConst>().into(), self.parse_token::<TerminalFunction>())
623                } else {
624                    (
625                        OptionTerminalConstEmpty::new_green(self.db).into(),
626                        self.take::<TerminalFunction>(),
627                    )
628                };
629                let declaration = self.expect_function_declaration_ex(optional_const, function_kw);
630                let semicolon = self.parse_token::<TerminalSemicolon>();
631                ExternItem::Function(ItemExternFunction::new_green(
632                    self.db,
633                    attributes,
634                    visibility,
635                    extern_kw,
636                    declaration,
637                    semicolon,
638                ))
639            }
640            _ => {
641                // TODO(spapini): Don't return ItemExternType if we don't see a type.
642                let type_kw = self.parse_token::<TerminalType>();
643
644                let name = self.parse_identifier();
645                let generic_params = self.parse_optional_generic_params();
646                let semicolon = self.parse_token::<TerminalSemicolon>();
647                // If the next token is not type, assume it is missing.
648                ExternItem::Type(ItemExternType::new_green(
649                    self.db,
650                    attributes,
651                    visibility,
652                    extern_kw,
653                    type_kw,
654                    name,
655                    generic_params,
656                    semicolon,
657                ))
658            }
659        }
660    }
661
662    /// Assumes the current token is Use.
663    /// Expected pattern: `use<Path>;`
664    fn expect_item_use(
665        &mut self,
666        attributes: AttributeListGreen,
667        visibility: VisibilityGreen,
668    ) -> ItemUseGreen {
669        let use_kw = self.take::<TerminalUse>();
670        let use_path = self.parse_use_path();
671        let semicolon = self.parse_token::<TerminalSemicolon>();
672        ItemUse::new_green(self.db, attributes, visibility, use_kw, use_path, semicolon)
673    }
674
675    /// Assumes the current token is Macro.
676    /// Expected pattern: `macro<Identifier>{<MacroRulesList>}`
677    fn expect_item_macro_declaration(
678        &mut self,
679        attributes: AttributeListGreen,
680        visibility: VisibilityGreen,
681    ) -> ItemMacroDeclarationGreen {
682        let macro_kw = self.take::<TerminalMacro>();
683        let name = self.parse_identifier();
684        let lbrace = self.parse_token::<TerminalLBrace>();
685        let macro_rules = MacroRulesList::new_green(
686            self.db,
687            &self.parse_list(Self::try_parse_macro_rule, is_of_kind!(rbrace), "macro rule"),
688        );
689        let rbrace = self.parse_token::<TerminalRBrace>();
690        ItemMacroDeclaration::new_green(
691            self.db,
692            attributes,
693            visibility,
694            macro_kw,
695            name,
696            lbrace,
697            macro_rules,
698            rbrace,
699        )
700    }
701
702    /// Returns a GreenId of a node with a MacroRule kind or TryParseFailure if a macro rule can't
703    /// be parsed.
704    fn try_parse_macro_rule(&mut self) -> TryParseResult<MacroRuleGreen> {
705        let previous_macro_parsing_context =
706            mem::replace(&mut self.macro_parsing_context, MacroParsingContext::MacroRule);
707        let wrapped_macro = match self.peek().kind {
708            SyntaxKind::TerminalLParen => self
709                .wrap_macro::<TerminalLParen, TerminalRParen, _, _>(ParenthesizedMacro::new_green)
710                .into(),
711            SyntaxKind::TerminalLBrace => self
712                .wrap_macro::<TerminalLBrace, TerminalRBrace, _, _>(BracedMacro::new_green)
713                .into(),
714            SyntaxKind::TerminalLBrack => self
715                .wrap_macro::<TerminalLBrack, TerminalRBrack, _, _>(BracketedMacro::new_green)
716                .into(),
717            _ => return Err(TryParseFailure::SkipToken),
718        };
719        let arrow = self.parse_token::<TerminalMatchArrow>();
720        self.macro_parsing_context = MacroParsingContext::MacroExpansion;
721        let macro_body =
722            self.wrap_macro::<TerminalLBrace, TerminalRBrace, _, _>(BracedMacro::new_green);
723        let semicolon = self.parse_token::<TerminalSemicolon>();
724        self.macro_parsing_context = previous_macro_parsing_context;
725        Ok(MacroRule::new_green(self.db, wrapped_macro, arrow, macro_body, semicolon))
726    }
727    /// Returns a GreenId of a node with a MacroRuleElement kind or TryParseFailure if a macro rule
728    /// element can't be parsed.
729    /// Expected pattern: Either any token or a matcher of the pattern $ident:kind.
730    fn try_parse_macro_element(&mut self) -> TryParseResult<MacroElementGreen> {
731        match self.peek().kind {
732            SyntaxKind::TerminalDollar => {
733                let dollar: TerminalDollarGreen = self.take::<TerminalDollar>();
734                match self.peek().kind {
735                    SyntaxKind::TerminalLParen => {
736                        let lparen = self.take::<TerminalLParen>();
737                        let elements = self.expect_wrapped_macro();
738                        let rparen = self.parse_token::<TerminalRParen>();
739                        let separator: OptionTerminalCommaGreen = match self.peek().kind {
740                            SyntaxKind::TerminalComma => self.take::<TerminalComma>().into(),
741                            _ => OptionTerminalCommaEmpty::new_green(self.db).into(),
742                        };
743                        let operator = match self.peek().kind {
744                            SyntaxKind::TerminalQuestionMark => {
745                                self.take::<TerminalQuestionMark>().into()
746                            }
747                            SyntaxKind::TerminalPlus => self.take::<TerminalPlus>().into(),
748                            SyntaxKind::TerminalMul => self.take::<TerminalMul>().into(),
749                            _ => MacroRepetitionOperator::missing(self.db),
750                        };
751                        Ok(MacroRepetition::new_green(
752                            self.db, dollar, lparen, elements, rparen, separator, operator,
753                        )
754                        .into())
755                    }
756                    _ => {
757                        let ident = self.parse_identifier();
758                        let param_kind: OptionParamKindGreen = if self.peek().kind
759                            == SyntaxKind::TerminalColon
760                        {
761                            let colon = self.parse_token::<TerminalColon>();
762                            let kind = self.parse_macro_rule_param_kind();
763                            let result = ParamKind::new_green(self.db, colon, kind).into();
764                            if let MacroParsingContext::MacroExpansion = self.macro_parsing_context
765                            {
766                                self.add_diagnostic(
767                                    ParserDiagnosticKind::InvalidParamKindInMacroExpansion,
768                                    TextSpan {
769                                        start: self.offset,
770                                        end: self.offset.add_width(self.current_width),
771                                    },
772                                );
773                            }
774                            result
775                        } else {
776                            if let MacroParsingContext::MacroRule = self.macro_parsing_context {
777                                self.add_diagnostic(
778                                    ParserDiagnosticKind::InvalidParamKindInMacroRule,
779                                    TextSpan {
780                                        start: self.offset,
781                                        end: self.offset.add_width(self.current_width),
782                                    },
783                                );
784                            }
785                            OptionParamKindEmpty::new_green(self.db).into()
786                        };
787                        self.macro_parsing_context = MacroParsingContext::None;
788                        Ok(MacroParam::new_green(self.db, dollar, ident, param_kind).into())
789                    }
790                }
791            }
792            SyntaxKind::TerminalLParen
793            | SyntaxKind::TerminalLBrace
794            | SyntaxKind::TerminalLBrack => {
795                let subtree = self.parse_macro_elements();
796                Ok(MacroWrapper::new_green(self.db, subtree).into())
797            }
798            _ => {
799                let token = self.parse_token_tree_leaf();
800                Ok(token.into())
801            }
802        }
803    }
804
805    fn parse_macro_elements(&mut self) -> WrappedMacroGreen {
806        match self.peek().kind {
807            SyntaxKind::TerminalLParen => self
808                .wrap_macro::<TerminalLParen, TerminalRParen, _, _>(ParenthesizedMacro::new_green)
809                .into(),
810            SyntaxKind::TerminalLBrace => self
811                .wrap_macro::<TerminalLBrace, TerminalRBrace, _, _>(BracedMacro::new_green)
812                .into(),
813            SyntaxKind::TerminalLBrack => self
814                .wrap_macro::<TerminalLBrack, TerminalRBrack, _, _>(BracketedMacro::new_green)
815                .into(),
816            _ => unreachable!("parse_macro_elements called on non-delimiter token"),
817        }
818    }
819
820    fn expect_wrapped_macro(&mut self) -> MacroElementsGreen {
821        let mut elements: Vec<MacroElementGreen> = vec![];
822        while !matches!(
823            self.peek().kind,
824            SyntaxKind::TerminalRParen
825                | SyntaxKind::TerminalRBrace
826                | SyntaxKind::TerminalRBrack
827                | SyntaxKind::TerminalEndOfFile
828        ) {
829            let element = self.try_parse_macro_element();
830            match element {
831                Ok(element) => elements.push(element),
832                Err(TryParseFailure::SkipToken) => {
833                    let _ = self.skip_until(is_of_kind!(rparen, rbrace, rbrack));
834                    break;
835                }
836                Err(TryParseFailure::DoNothing) => break,
837            }
838        }
839        MacroElements::new_green(self.db, &elements)
840    }
841
842    fn wrap_macro<
843        LTerminal: syntax::node::Terminal,
844        RTerminal: syntax::node::Terminal,
845        ListGreen,
846        NewGreen: Fn(&dyn SyntaxGroup, LTerminal::Green, MacroElementsGreen, RTerminal::Green) -> ListGreen,
847    >(
848        &mut self,
849        new_green: NewGreen,
850    ) -> ListGreen {
851        let l_term = self.take::<LTerminal>();
852        let elements = self.expect_wrapped_macro();
853        let r_term = self.parse_token::<RTerminal>();
854        new_green(self.db, l_term, elements, r_term)
855    }
856
857    /// Returns a GreenId of a node with a MacroRuleParamKind kind.
858    fn parse_macro_rule_param_kind(&mut self) -> MacroParamKindGreen {
859        let peeked = self.peek();
860        match (peeked.kind, peeked.text.as_str()) {
861            (SyntaxKind::TerminalIdentifier, "ident") => {
862                ParamIdent::new_green(self.db, self.parse_token::<TerminalIdentifier>()).into()
863            }
864            (SyntaxKind::TerminalIdentifier, "expr") => {
865                ParamExpr::new_green(self.db, self.parse_token::<TerminalIdentifier>()).into()
866            }
867            _ => self.create_and_report_missing::<MacroParamKind>(
868                ParserDiagnosticKind::MissingMacroRuleParamKind,
869            ),
870        }
871    }
872
873    /// Returns a GreenId of a node with a UsePath kind or TryParseFailure if can't parse a UsePath.
874    fn try_parse_use_path(&mut self) -> TryParseResult<UsePathGreen> {
875        if !matches!(
876            self.peek().kind,
877            SyntaxKind::TerminalLBrace | SyntaxKind::TerminalIdentifier | SyntaxKind::TerminalMul
878        ) {
879            return Err(TryParseFailure::SkipToken);
880        }
881        Ok(self.parse_use_path())
882    }
883
884    /// Returns a GreenId of a node with a UsePath kind.
885    fn parse_use_path(&mut self) -> UsePathGreen {
886        match self.peek().kind {
887            SyntaxKind::TerminalLBrace => {
888                let lbrace = self.parse_token::<TerminalLBrace>();
889                let items = UsePathList::new_green(self.db,
890                    &self.parse_separated_list::<
891                        UsePath, TerminalComma, UsePathListElementOrSeparatorGreen
892                    >(
893                        Self::try_parse_use_path,
894                        is_of_kind!(rbrace, module_item_kw),
895                        "path segment",
896                    ));
897                let rbrace = self.parse_token::<TerminalRBrace>();
898                UsePathMulti::new_green(self.db, lbrace, items, rbrace).into()
899            }
900            SyntaxKind::TerminalMul => {
901                let star = self.parse_token::<TerminalMul>();
902                UsePathStar::new_green(self.db, star).into()
903            }
904            _ => {
905                if let Ok(ident) = self.try_parse_identifier() {
906                    let ident = PathSegmentSimple::new_green(self.db, ident).into();
907                    match self.peek().kind {
908                        SyntaxKind::TerminalColonColon => {
909                            let colon_colon = self.parse_token::<TerminalColonColon>();
910                            let use_path = self.parse_use_path();
911                            UsePathSingle::new_green(self.db, ident, colon_colon, use_path).into()
912                        }
913                        SyntaxKind::TerminalAs => {
914                            let as_kw = self.take::<TerminalAs>();
915                            let alias = self.parse_identifier();
916                            let alias_clause = AliasClause::new_green(self.db, as_kw, alias).into();
917                            UsePathLeaf::new_green(self.db, ident, alias_clause).into()
918                        }
919                        _ => {
920                            let alias_clause = OptionAliasClauseEmpty::new_green(self.db).into();
921                            UsePathLeaf::new_green(self.db, ident, alias_clause).into()
922                        }
923                    }
924                } else {
925                    let missing = self.create_and_report_missing::<TerminalIdentifier>(
926                        ParserDiagnosticKind::MissingPathSegment,
927                    );
928                    let ident = PathSegmentSimple::new_green(self.db, missing).into();
929                    UsePathLeaf::new_green(
930                        self.db,
931                        ident,
932                        OptionAliasClauseEmpty::new_green(self.db).into(),
933                    )
934                    .into()
935                }
936            }
937        }
938    }
939
940    /// Returns a GreenId of a node with an identifier kind or TryParseFailure if an identifier
941    /// can't be parsed.
942    /// Note that if the terminal is a keyword or an underscore, it is skipped, and
943    /// Some(missing-identifier) is returned.
944    fn try_parse_identifier(&mut self) -> TryParseResult<TerminalIdentifierGreen> {
945        let peeked = self.peek();
946        if peeked.kind.is_keyword_terminal() {
947            // TODO(spapini): don't skip every keyword. Instead, pass a recovery set.
948            Ok(self.skip_token_and_return_missing::<TerminalIdentifier>(
949                ParserDiagnosticKind::ReservedIdentifier { identifier: peeked.text.clone() },
950            ))
951        } else if peeked.kind == SyntaxKind::TerminalUnderscore {
952            Ok(self.skip_token_and_return_missing::<TerminalIdentifier>(
953                ParserDiagnosticKind::UnderscoreNotAllowedAsIdentifier,
954            ))
955        } else {
956            self.try_parse_token::<TerminalIdentifier>()
957        }
958    }
959    /// Returns whether the current token is an identifier, a keyword or an underscore ('_'),
960    /// without consuming it. This should be used mostly, instead of checking whether the current
961    /// token is an identifier, because in many cases we'd want to consume the keyword/underscore as
962    /// the identifier and raise a relevant diagnostic
963    /// (ReservedIdentifier/UnderscoreNotAllowedAsIdentifier).
964    fn is_peek_identifier_like(&self) -> bool {
965        let kind = self.peek().kind;
966        kind.is_keyword_terminal()
967            || matches!(
968                kind,
969                SyntaxKind::TerminalUnderscore
970                    | SyntaxKind::TerminalIdentifier
971                    | SyntaxKind::TerminalDollar
972            )
973    }
974
975    /// Returns a GreenId of a node with an identifier kind.
976    fn parse_identifier(&mut self) -> TerminalIdentifierGreen {
977        match self.try_parse_identifier() {
978            Ok(identifier) => identifier,
979            Err(_) => self.create_and_report_missing_terminal::<TerminalIdentifier>(),
980        }
981    }
982
983    /// Returns a GreenId of node visibility.
984    fn parse_visibility(&mut self) -> VisibilityGreen {
985        match self.try_parse_visibility_pub() {
986            Some(visibility) => visibility.into(),
987            None => VisibilityDefault::new_green(self.db).into(),
988        }
989    }
990
991    /// Returns a GreenId of node with pub visibility or None if not starting with "pub".
992    fn try_parse_visibility_pub(&mut self) -> Option<VisibilityPubGreen> {
993        require(self.peek().kind == SyntaxKind::TerminalPub)?;
994        let pub_kw = self.take::<TerminalPub>();
995        let argument_clause = if self.peek().kind != SyntaxKind::TerminalLParen {
996            OptionVisibilityPubArgumentClauseEmpty::new_green(self.db).into()
997        } else {
998            let lparen = self.parse_token::<TerminalLParen>();
999            let argument = self.parse_token::<TerminalIdentifier>();
1000            let rparen = self.parse_token::<TerminalRParen>();
1001            VisibilityPubArgumentClause::new_green(self.db, lparen, argument, rparen).into()
1002        };
1003        Some(VisibilityPub::new_green(self.db, pub_kw, argument_clause))
1004    }
1005
1006    /// Returns a GreenId of a node with an attribute list kind or TryParseFailure if an attribute
1007    /// list can't be parsed.
1008    /// `expected_elements_str` are the expected elements that these attributes are parsed for.
1009    /// Note: it should not include "attribute".
1010    fn try_parse_attribute_list(
1011        &mut self,
1012        expected_elements_str: &str,
1013    ) -> TryParseResult<AttributeListGreen> {
1014        if self.peek().kind == SyntaxKind::TerminalHash {
1015            Ok(self.parse_attribute_list(expected_elements_str))
1016        } else {
1017            Err(TryParseFailure::SkipToken)
1018        }
1019    }
1020
1021    /// Parses an attribute list.
1022    /// `expected_elements_str` are the expected elements that these attributes are parsed for.
1023    /// Note: it should not include "attribute".
1024    fn parse_attribute_list(&mut self, expected_elements_str: &str) -> AttributeListGreen {
1025        AttributeList::new_green(
1026            self.db,
1027            &self.parse_list(
1028                Self::try_parse_attribute,
1029                |x| x != SyntaxKind::TerminalHash,
1030                &or_an_attribute!(expected_elements_str),
1031            ),
1032        )
1033    }
1034
1035    /// Returns a GreenId of a node with an attribute kind or TryParseFailure if an attribute can't
1036    /// be parsed.
1037    fn try_parse_attribute(&mut self) -> TryParseResult<AttributeGreen> {
1038        match self.peek().kind {
1039            SyntaxKind::TerminalHash => {
1040                let hash = self.take::<TerminalHash>();
1041                let lbrack = self.parse_token::<TerminalLBrack>();
1042                let attr = self.parse_path();
1043                let arguments = self.try_parse_parenthesized_argument_list();
1044                let rbrack = self.parse_token::<TerminalRBrack>();
1045
1046                Ok(Attribute::new_green(self.db, hash, lbrack, attr, arguments, rbrack))
1047            }
1048            _ => Err(TryParseFailure::SkipToken),
1049        }
1050    }
1051
1052    /// Assumes the current token is Function.
1053    /// Expected pattern: `<FunctionDeclaration>`
1054    fn expect_function_declaration(
1055        &mut self,
1056        optional_const: OptionTerminalConstGreen,
1057    ) -> FunctionDeclarationGreen {
1058        let function_kw = self.take::<TerminalFunction>();
1059        self.expect_function_declaration_ex(optional_const, function_kw)
1060    }
1061
1062    /// Assumes the current token is Function.
1063    /// Expected pattern: `<FunctionDeclaration>`
1064    fn expect_function_declaration_ex(
1065        &mut self,
1066        optional_const: OptionTerminalConstGreen,
1067        function_kw: TerminalFunctionGreen,
1068    ) -> FunctionDeclarationGreen {
1069        let name = self.parse_identifier();
1070        let generic_params = self.parse_optional_generic_params();
1071        let signature = self.expect_function_signature();
1072
1073        FunctionDeclaration::new_green(
1074            self.db,
1075            optional_const,
1076            function_kw,
1077            name,
1078            generic_params,
1079            signature,
1080        )
1081    }
1082
1083    /// Assumes the current token is Function.
1084    /// Expected pattern: `<FunctionDeclaration><Block>`
1085    fn expect_item_function_with_body(
1086        &mut self,
1087        attributes: AttributeListGreen,
1088        visibility: VisibilityGreen,
1089        optional_const: OptionTerminalConstGreen,
1090    ) -> FunctionWithBodyGreen {
1091        let declaration = self.expect_function_declaration(optional_const);
1092        let function_body = self.parse_block();
1093        FunctionWithBody::new_green(self.db, attributes, visibility, declaration, function_body)
1094    }
1095
1096    /// Assumes the current token is Trait.
1097    fn expect_item_trait(
1098        &mut self,
1099        attributes: AttributeListGreen,
1100        visibility: VisibilityGreen,
1101    ) -> ItemTraitGreen {
1102        let trait_kw = self.take::<TerminalTrait>();
1103        let name = self.parse_identifier();
1104        let generic_params = self.parse_optional_generic_params();
1105        let body = if self.peek().kind == SyntaxKind::TerminalLBrace {
1106            let lbrace = self.take::<TerminalLBrace>();
1107            let items = TraitItemList::new_green(
1108                self.db,
1109                &self.parse_attributed_list(
1110                    Self::try_parse_trait_item,
1111                    is_of_kind!(rbrace, module_item_kw),
1112                    TRAIT_ITEM_DESCRIPTION,
1113                ),
1114            );
1115            let rbrace = self.parse_token::<TerminalRBrace>();
1116            TraitBody::new_green(self.db, lbrace, items, rbrace).into()
1117        } else {
1118            self.parse_token::<TerminalSemicolon>().into()
1119        };
1120
1121        ItemTrait::new_green(self.db, attributes, visibility, trait_kw, name, generic_params, body)
1122    }
1123
1124    /// Returns a GreenId of a node with a TraitItem.* kind (see
1125    /// [syntax::node::ast::TraitItem]), or TryParseFailure if a trait item can't be parsed.
1126    pub fn try_parse_trait_item(&mut self) -> TryParseResult<TraitItemGreen> {
1127        let maybe_attributes = self.try_parse_attribute_list(TRAIT_ITEM_DESCRIPTION);
1128
1129        let (has_attrs, attributes) = match maybe_attributes {
1130            Ok(attributes) => (true, attributes),
1131            Err(_) => (false, AttributeList::new_green(self.db, &[])),
1132        };
1133
1134        match self.peek().kind {
1135            SyntaxKind::TerminalFunction => Ok(self
1136                .expect_trait_item_function(
1137                    attributes,
1138                    OptionTerminalConstEmpty::new_green(self.db).into(),
1139                )
1140                .into()),
1141            SyntaxKind::TerminalType => Ok(self.expect_trait_item_type(attributes).into()),
1142            SyntaxKind::TerminalConst => {
1143                let const_kw = self.take::<TerminalConst>();
1144                Ok(if self.peek().kind == SyntaxKind::TerminalFunction {
1145                    self.expect_trait_item_function(attributes, const_kw.into()).into()
1146                } else {
1147                    self.expect_trait_item_const(attributes, const_kw).into()
1148                })
1149            }
1150            SyntaxKind::TerminalImpl => Ok(self.expect_trait_item_impl(attributes).into()),
1151            _ => {
1152                if has_attrs {
1153                    Ok(self.skip_taken_node_and_return_missing::<TraitItem>(
1154                        attributes,
1155                        ParserDiagnosticKind::AttributesWithoutTraitItem,
1156                    ))
1157                } else {
1158                    Err(TryParseFailure::SkipToken)
1159                }
1160            }
1161        }
1162    }
1163
1164    /// Assumes the current token is Function.
1165    /// Expected pattern: `<FunctionDeclaration><SemiColon>`
1166    fn expect_trait_item_function(
1167        &mut self,
1168        attributes: AttributeListGreen,
1169        optional_const: OptionTerminalConstGreen,
1170    ) -> TraitItemFunctionGreen {
1171        let declaration = self.expect_function_declaration(optional_const);
1172        let body = if self.peek().kind == SyntaxKind::TerminalLBrace {
1173            self.parse_block().into()
1174        } else {
1175            self.parse_token::<TerminalSemicolon>().into()
1176        };
1177        TraitItemFunction::new_green(self.db, attributes, declaration, body)
1178    }
1179
1180    /// Assumes the current token is Type.
1181    /// Expected pattern: `type <name>;`
1182    fn expect_trait_item_type(&mut self, attributes: AttributeListGreen) -> TraitItemTypeGreen {
1183        let type_kw = self.take::<TerminalType>();
1184        let name = self.parse_identifier();
1185        let generic_params = self.parse_optional_generic_params();
1186        let semicolon = self.parse_token::<TerminalSemicolon>();
1187        TraitItemType::new_green(self.db, attributes, type_kw, name, generic_params, semicolon)
1188    }
1189
1190    /// Assumes the current token is Const.
1191    /// Expected pattern: `const <name>: <type>;`
1192    fn expect_trait_item_const(
1193        &mut self,
1194        attributes: AttributeListGreen,
1195        const_kw: TerminalConstGreen,
1196    ) -> TraitItemConstantGreen {
1197        let name = self.parse_identifier();
1198        let type_clause = self.parse_type_clause(ErrorRecovery {
1199            should_stop: is_of_kind!(eq, semicolon, module_item_kw),
1200        });
1201        let semicolon = self.parse_token::<TerminalSemicolon>();
1202
1203        TraitItemConstant::new_green(self.db, attributes, const_kw, name, type_clause, semicolon)
1204    }
1205
1206    /// Assumes the current token is Impl.
1207    /// Expected pattern: `impl <name>: <trait_path>;`
1208    fn expect_trait_item_impl(&mut self, attributes: AttributeListGreen) -> TraitItemImplGreen {
1209        let impl_kw = self.take::<TerminalImpl>();
1210        let name = self.parse_identifier();
1211        let colon = self.parse_token::<TerminalColon>();
1212        let trait_path = self.parse_type_path();
1213        let semicolon = self.parse_token::<TerminalSemicolon>();
1214        TraitItemImpl::new_green(self.db, attributes, impl_kw, name, colon, trait_path, semicolon)
1215    }
1216
1217    /// Assumes the current token is Impl.
1218    fn expect_module_item_impl(
1219        &mut self,
1220        attributes: AttributeListGreen,
1221        visibility: VisibilityGreen,
1222    ) -> ModuleItemGreen {
1223        match self.expect_item_impl_inner(attributes, visibility, false) {
1224            ImplItemOrAlias::Item(green) => green.into(),
1225            ImplItemOrAlias::Alias(green) => green.into(),
1226        }
1227    }
1228
1229    /// Assumes the current token is Impl.
1230    /// Expects an impl impl-item (impl alias syntax): `impl <name> = <path>;`.
1231    fn expect_impl_item_impl(
1232        &mut self,
1233        attributes: AttributeListGreen,
1234        visibility: VisibilityGreen,
1235    ) -> ItemImplAliasGreen {
1236        extract_matches!(
1237            self.expect_item_impl_inner(attributes, visibility, true),
1238            ImplItemOrAlias::Alias
1239        )
1240    }
1241
1242    /// Assumes the current token is Impl.
1243    /// Expects either an impl item (`impl <name> of <trait_path> {<impl_body>}`) or and impl alias
1244    /// `impl <name> = <path>;`.
1245    /// If `only_allow_alias` is true, always returns a ImplItemOrAlias::Alias.
1246    fn expect_item_impl_inner(
1247        &mut self,
1248        attributes: AttributeListGreen,
1249        visibility: VisibilityGreen,
1250        only_allow_alias: bool,
1251    ) -> ImplItemOrAlias {
1252        let impl_kw = self.take::<TerminalImpl>();
1253        let name = self.parse_identifier();
1254        let generic_params = self.parse_optional_generic_params();
1255
1256        if self.peek().kind == SyntaxKind::TerminalEq || only_allow_alias {
1257            let eq = self.parse_token::<TerminalEq>();
1258            let impl_path = self.parse_type_path();
1259            let semicolon = self.parse_token::<TerminalSemicolon>();
1260
1261            return ImplItemOrAlias::Alias(ItemImplAlias::new_green(
1262                self.db,
1263                attributes,
1264                visibility,
1265                impl_kw,
1266                name,
1267                generic_params,
1268                eq,
1269                impl_path,
1270                semicolon,
1271            ));
1272        }
1273
1274        let of_kw = self.parse_token::<TerminalOf>();
1275        let trait_path = self.parse_type_path();
1276        let body = if self.peek().kind == SyntaxKind::TerminalLBrace {
1277            let lbrace = self.take::<TerminalLBrace>();
1278            let items = ImplItemList::new_green(
1279                self.db,
1280                &self.parse_attributed_list(
1281                    Self::try_parse_impl_item,
1282                    is_of_kind!(rbrace),
1283                    IMPL_ITEM_DESCRIPTION,
1284                ),
1285            );
1286            let rbrace = self.parse_token::<TerminalRBrace>();
1287            ImplBody::new_green(self.db, lbrace, items, rbrace).into()
1288        } else {
1289            self.parse_token::<TerminalSemicolon>().into()
1290        };
1291
1292        ImplItemOrAlias::Item(ItemImpl::new_green(
1293            self.db,
1294            attributes,
1295            visibility,
1296            impl_kw,
1297            name,
1298            generic_params,
1299            of_kw,
1300            trait_path,
1301            body,
1302        ))
1303    }
1304
1305    /// Returns a GreenId of a node with a ImplItem.* kind (see
1306    /// [syntax::node::ast::ImplItem]), or TryParseFailure if an impl item can't be parsed.
1307    pub fn try_parse_impl_item(&mut self) -> TryParseResult<ImplItemGreen> {
1308        let maybe_attributes = self.try_parse_attribute_list(IMPL_ITEM_DESCRIPTION);
1309
1310        let (has_attrs, attributes) = match maybe_attributes {
1311            Ok(attributes) => (true, attributes),
1312            Err(_) => (false, AttributeList::new_green(self.db, &[])),
1313        };
1314
1315        // No visibility in impls, as these just implements the options of a trait, which is always
1316        // pub.
1317        let visibility = VisibilityDefault::new_green(self.db).into();
1318
1319        match self.peek().kind {
1320            SyntaxKind::TerminalFunction => Ok(self
1321                .expect_item_function_with_body(
1322                    attributes,
1323                    visibility,
1324                    OptionTerminalConstEmpty::new_green(self.db).into(),
1325                )
1326                .into()),
1327            SyntaxKind::TerminalType => {
1328                Ok(self.expect_item_type_alias(attributes, visibility).into())
1329            }
1330            SyntaxKind::TerminalConst => {
1331                let const_kw = self.take::<TerminalConst>();
1332                Ok(if self.peek().kind == SyntaxKind::TerminalFunction {
1333                    self.expect_item_function_with_body(attributes, visibility, const_kw.into())
1334                        .into()
1335                } else {
1336                    self.expect_item_const(attributes, visibility, const_kw).into()
1337                })
1338            }
1339            SyntaxKind::TerminalImpl => {
1340                Ok(self.expect_impl_item_impl(attributes, visibility).into())
1341            }
1342            // These are not supported semantically.
1343            SyntaxKind::TerminalModule => {
1344                Ok(self.expect_item_module(attributes, visibility).into())
1345            }
1346            SyntaxKind::TerminalStruct => {
1347                Ok(self.expect_item_struct(attributes, visibility).into())
1348            }
1349            SyntaxKind::TerminalEnum => Ok(self.expect_item_enum(attributes, visibility).into()),
1350            SyntaxKind::TerminalExtern => Ok(self.expect_item_extern(attributes, visibility)),
1351            SyntaxKind::TerminalUse => Ok(self.expect_item_use(attributes, visibility).into()),
1352            SyntaxKind::TerminalTrait => Ok(self.expect_item_trait(attributes, visibility).into()),
1353            _ => {
1354                if has_attrs {
1355                    Ok(self.skip_taken_node_and_return_missing::<ImplItem>(
1356                        attributes,
1357                        ParserDiagnosticKind::AttributesWithoutImplItem,
1358                    ))
1359                } else {
1360                    Err(TryParseFailure::SkipToken)
1361                }
1362            }
1363        }
1364    }
1365
1366    /// Assumes the current token is TerminalNot.
1367    fn expect_item_inline_macro(
1368        &mut self,
1369        attributes: AttributeListGreen,
1370        path: ExprPathGreen,
1371    ) -> ItemInlineMacroGreen {
1372        let bang = self.parse_token::<TerminalNot>();
1373        self.parse_item_inline_macro_given_bang(attributes, path, bang)
1374    }
1375
1376    /// Returns a GreenId of a node with an ItemInlineMacro kind, given the bang ('!') token.
1377    fn parse_item_inline_macro_given_bang(
1378        &mut self,
1379        attributes: AttributeListGreen,
1380        path: ExprPathGreen,
1381        bang: TerminalNotGreen,
1382    ) -> ItemInlineMacroGreen {
1383        let token_tree_node = self.parse_token_tree_node();
1384        let semicolon = self.parse_token::<TerminalSemicolon>();
1385        ItemInlineMacro::new_green(self.db, attributes, path, bang, token_tree_node, semicolon)
1386    }
1387
1388    // ------------------------------- Expressions -------------------------------
1389
1390    /// Returns a GreenId of a node with an Expr.* kind (see [syntax::node::ast::Expr])
1391    /// or TryParseFailure if an expression can't be parsed.
1392    pub fn try_parse_expr(&mut self) -> TryParseResult<ExprGreen> {
1393        self.try_parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Allow, AndLetBehavior::Simple)
1394    }
1395    /// Returns a GreenId of a node with an Expr.* kind (see [syntax::node::ast::Expr])
1396    /// or a node with kind ExprMissing if an expression can't be parsed.
1397    pub fn parse_expr(&mut self) -> ExprGreen {
1398        match self.try_parse_expr() {
1399            Ok(green) => green,
1400            Err(_) => {
1401                self.create_and_report_missing::<Expr>(ParserDiagnosticKind::MissingExpression)
1402            }
1403        }
1404    }
1405
1406    /// Assumes the current token is a binary operator. Otherwise it might panic.
1407    ///
1408    /// Returns a GreenId of the operator.
1409    fn parse_binary_operator(&mut self) -> BinaryOperatorGreen {
1410        // Note that if this code is not reached you might need to add the operator to
1411        // `get_post_operator_precedence`.
1412        match self.peek().kind {
1413            SyntaxKind::TerminalDot => self.take::<TerminalDot>().into(),
1414            SyntaxKind::TerminalMul => self.take::<TerminalMul>().into(),
1415            SyntaxKind::TerminalMulEq => self.take::<TerminalMulEq>().into(),
1416            SyntaxKind::TerminalDiv => self.take::<TerminalDiv>().into(),
1417            SyntaxKind::TerminalDivEq => self.take::<TerminalDivEq>().into(),
1418            SyntaxKind::TerminalMod => self.take::<TerminalMod>().into(),
1419            SyntaxKind::TerminalModEq => self.take::<TerminalModEq>().into(),
1420            SyntaxKind::TerminalPlus => self.take::<TerminalPlus>().into(),
1421            SyntaxKind::TerminalPlusEq => self.take::<TerminalPlusEq>().into(),
1422            SyntaxKind::TerminalMinus => self.take::<TerminalMinus>().into(),
1423            SyntaxKind::TerminalMinusEq => self.take::<TerminalMinusEq>().into(),
1424            SyntaxKind::TerminalEq => self.take::<TerminalEq>().into(),
1425            SyntaxKind::TerminalEqEq => self.take::<TerminalEqEq>().into(),
1426            SyntaxKind::TerminalNeq => self.take::<TerminalNeq>().into(),
1427            SyntaxKind::TerminalLT => self.take::<TerminalLT>().into(),
1428            SyntaxKind::TerminalGT => self.take::<TerminalGT>().into(),
1429            SyntaxKind::TerminalLE => self.take::<TerminalLE>().into(),
1430            SyntaxKind::TerminalGE => self.take::<TerminalGE>().into(),
1431            SyntaxKind::TerminalAnd => self.take::<TerminalAnd>().into(),
1432            SyntaxKind::TerminalAndAnd => self.take::<TerminalAndAnd>().into(),
1433            SyntaxKind::TerminalOrOr => self.take::<TerminalOrOr>().into(),
1434            SyntaxKind::TerminalOr => self.take::<TerminalOr>().into(),
1435            SyntaxKind::TerminalXor => self.take::<TerminalXor>().into(),
1436            SyntaxKind::TerminalDotDot => self.take::<TerminalDotDot>().into(),
1437            SyntaxKind::TerminalDotDotEq => self.take::<TerminalDotDotEq>().into(),
1438            _ => unreachable!(),
1439        }
1440    }
1441
1442    /// Assumes the current token is a unary operator, and returns a GreenId of the operator.
1443    fn expect_unary_operator(&mut self) -> UnaryOperatorGreen {
1444        match self.peek().kind {
1445            SyntaxKind::TerminalAt => self.take::<TerminalAt>().into(),
1446            SyntaxKind::TerminalNot => self.take::<TerminalNot>().into(),
1447            SyntaxKind::TerminalBitNot => self.take::<TerminalBitNot>().into(),
1448            SyntaxKind::TerminalMinus => self.take::<TerminalMinus>().into(),
1449            SyntaxKind::TerminalMul => self.take::<TerminalMul>().into(),
1450            _ => unreachable!(),
1451        }
1452    }
1453
1454    /// Checks if the current token is a relational or equality operator (`<`, `>`, `<=`, `>=`,
1455    /// `==`, or `!=`).
1456    ///
1457    /// This function is used to determine if the given `SyntaxKind` represents a relational or
1458    /// equality operator, which is commonly used in binary expressions.
1459    ///
1460    /// # Parameters:
1461    /// - `kind`: The `SyntaxKind` of the current token.
1462    ///
1463    /// # Returns:
1464    /// `true` if the token is a relational or equality operator, otherwise `false`.
1465    fn is_comparison_operator(&self, kind: SyntaxKind) -> bool {
1466        matches!(
1467            kind,
1468            SyntaxKind::TerminalLT
1469                | SyntaxKind::TerminalGT
1470                | SyntaxKind::TerminalLE
1471                | SyntaxKind::TerminalGE
1472                | SyntaxKind::TerminalEqEq
1473                | SyntaxKind::TerminalNeq
1474        )
1475    }
1476
1477    /// Returns a GreenId of a node with an Expr.* kind (see [syntax::node::ast::Expr])
1478    /// or TryParseFailure if such an expression can't be parsed.
1479    ///
1480    /// Parsing will be limited by:
1481    /// `parent_precedence` - parsing of binary operators limited to this.
1482    /// `lbrace_allowed` - See [LbraceAllowed].
1483    fn try_parse_expr_limited(
1484        &mut self,
1485        parent_precedence: usize,
1486        lbrace_allowed: LbraceAllowed,
1487        and_let_behavior: AndLetBehavior,
1488    ) -> TryParseResult<ExprGreen> {
1489        let mut expr = self.try_parse_atom_or_unary(lbrace_allowed)?;
1490        let mut child_op: Option<SyntaxKind> = None;
1491        loop {
1492            let peeked_kind = self.peek().kind;
1493            let Some(precedence) = get_post_operator_precedence(peeked_kind) else {
1494                return Ok(expr);
1495            };
1496            if precedence >= parent_precedence {
1497                return Ok(expr);
1498            }
1499            expr = match peeked_kind {
1500                // If the next two tokens are `&& let` (part of a let-chain), then they should be
1501                // parsed by the caller. Return immediately.
1502                SyntaxKind::TerminalAndAnd
1503                    if and_let_behavior == AndLetBehavior::Stop
1504                        && self.peek_next_next_kind() == SyntaxKind::TerminalLet =>
1505                {
1506                    return Ok(expr);
1507                }
1508                SyntaxKind::TerminalQuestionMark => ExprErrorPropagate::new_green(
1509                    self.db,
1510                    expr,
1511                    self.take::<TerminalQuestionMark>(),
1512                )
1513                .into(),
1514                SyntaxKind::TerminalLBrack => {
1515                    let lbrack = self.take::<TerminalLBrack>();
1516                    let index_expr = self.parse_expr();
1517                    let rbrack = self.parse_token::<TerminalRBrack>();
1518                    ExprIndexed::new_green(self.db, expr, lbrack, index_expr, rbrack).into()
1519                }
1520                current_op => {
1521                    if let Some(child_op_kind) = child_op {
1522                        if self.is_comparison_operator(child_op_kind)
1523                            && self.is_comparison_operator(current_op)
1524                        {
1525                            let offset = self.offset.add_width(self.current_width);
1526                            self.add_diagnostic(
1527                                ParserDiagnosticKind::ConsecutiveMathOperators {
1528                                    first_op: child_op_kind,
1529                                    second_op: current_op,
1530                                },
1531                                TextSpan { start: offset, end: offset },
1532                            );
1533                        }
1534                    }
1535                    child_op = Some(current_op);
1536                    let op = self.parse_binary_operator();
1537                    let rhs = self.parse_expr_limited(precedence, lbrace_allowed, and_let_behavior);
1538                    ExprBinary::new_green(self.db, expr, op, rhs).into()
1539                }
1540            };
1541        }
1542    }
1543
1544    /// Returns a GreenId of a node with ExprPath, ExprFunctionCall, ExprStructCtorCall,
1545    /// ExprParenthesized, ExprTuple or ExprUnary kind, or TryParseFailure if such an expression
1546    /// can't be parsed.
1547    ///
1548    /// `lbrace_allowed` - See [LbraceAllowed].
1549    fn try_parse_atom_or_unary(
1550        &mut self,
1551        lbrace_allowed: LbraceAllowed,
1552    ) -> TryParseResult<ExprGreen> {
1553        let Some(precedence) = get_unary_operator_precedence(self.peek().kind) else {
1554            return self.try_parse_atom(lbrace_allowed);
1555        };
1556        let op = self.expect_unary_operator();
1557        let expr = self.parse_expr_limited(precedence, lbrace_allowed, AndLetBehavior::Simple);
1558        Ok(ExprUnary::new_green(self.db, op, expr).into())
1559    }
1560
1561    /// Returns a GreenId of a node with an Expr.* kind (see [syntax::node::ast::Expr]),
1562    /// excluding ExprBlock, or ExprMissing if such an expression can't be parsed.
1563    ///
1564    /// `lbrace_allowed` - See [LbraceAllowed].
1565    fn parse_expr_limited(
1566        &mut self,
1567        parent_precedence: usize,
1568        lbrace_allowed: LbraceAllowed,
1569        and_let_behavior: AndLetBehavior,
1570    ) -> ExprGreen {
1571        match self.try_parse_expr_limited(parent_precedence, lbrace_allowed, and_let_behavior) {
1572            Ok(green) => green,
1573            Err(_) => {
1574                self.create_and_report_missing::<Expr>(ParserDiagnosticKind::MissingExpression)
1575            }
1576        }
1577    }
1578
1579    /// Returns a GreenId of a node with an
1580    /// ExprPath|ExprFunctionCall|ExprStructCtorCall|ExprParenthesized|ExprTuple kind, or
1581    /// TryParseFailure if such an expression can't be parsed.
1582    ///
1583    /// `lbrace_allowed` - See [LbraceAllowed].
1584    fn try_parse_atom(&mut self, lbrace_allowed: LbraceAllowed) -> TryParseResult<ExprGreen> {
1585        // TODO(yuval): support paths starting with "::".
1586        match self.peek().kind {
1587            SyntaxKind::TerminalIdentifier | SyntaxKind::TerminalDollar => {
1588                // Call parse_path() and not expect_path(), because it's cheap.
1589                let path = self.parse_path();
1590                match self.peek().kind {
1591                    SyntaxKind::TerminalLParen => Ok(self.expect_function_call(path).into()),
1592                    SyntaxKind::TerminalLBrace if lbrace_allowed == LbraceAllowed::Allow => {
1593                        Ok(self.expect_constructor_call(path).into())
1594                    }
1595                    SyntaxKind::TerminalNot => Ok(self.expect_macro_call(path).into()),
1596                    _ => Ok(path.into()),
1597                }
1598            }
1599            SyntaxKind::TerminalFalse => Ok(self.take::<TerminalFalse>().into()),
1600            SyntaxKind::TerminalTrue => Ok(self.take::<TerminalTrue>().into()),
1601            SyntaxKind::TerminalLiteralNumber => Ok(self.take_terminal_literal_number().into()),
1602            SyntaxKind::TerminalShortString => Ok(self.take_terminal_short_string().into()),
1603            SyntaxKind::TerminalString => Ok(self.take_terminal_string().into()),
1604            SyntaxKind::TerminalLParen => {
1605                // Note that LBrace is allowed inside parenthesis, even if `lbrace_allowed` is
1606                // [LbraceAllowed::Forbid].
1607                Ok(self.expect_parenthesized_expr())
1608            }
1609            SyntaxKind::TerminalLBrack => Ok(self.expect_fixed_size_array_expr().into()),
1610            SyntaxKind::TerminalLBrace if lbrace_allowed == LbraceAllowed::Allow => {
1611                Ok(self.parse_block().into())
1612            }
1613            SyntaxKind::TerminalMatch if lbrace_allowed == LbraceAllowed::Allow => {
1614                Ok(self.expect_match_expr().into())
1615            }
1616            SyntaxKind::TerminalIf if lbrace_allowed == LbraceAllowed::Allow => {
1617                Ok(self.expect_if_expr().into())
1618            }
1619            SyntaxKind::TerminalLoop if lbrace_allowed == LbraceAllowed::Allow => {
1620                Ok(self.expect_loop_expr().into())
1621            }
1622            SyntaxKind::TerminalWhile if lbrace_allowed == LbraceAllowed::Allow => {
1623                Ok(self.expect_while_expr().into())
1624            }
1625            SyntaxKind::TerminalFor if lbrace_allowed == LbraceAllowed::Allow => {
1626                Ok(self.expect_for_expr().into())
1627            }
1628            SyntaxKind::TerminalOr if lbrace_allowed == LbraceAllowed::Allow => {
1629                Ok(self.expect_closure_expr_nary().into())
1630            }
1631            SyntaxKind::TerminalOrOr if lbrace_allowed == LbraceAllowed::Allow => {
1632                Ok(self.expect_closure_expr_nullary().into())
1633            }
1634            _ => {
1635                // TODO(yuval): report to diagnostics.
1636                Err(TryParseFailure::SkipToken)
1637            }
1638        }
1639    }
1640
1641    /// Returns a GreenId of a node with an ExprPath|ExprParenthesized|ExprTuple kind, or
1642    /// TryParseFailure if such an expression can't be parsed.
1643    fn try_parse_type_expr(&mut self) -> TryParseResult<ExprGreen> {
1644        // TODO(yuval): support paths starting with "::".
1645        match self.peek().kind {
1646            SyntaxKind::TerminalAt => {
1647                let op = self.take::<TerminalAt>().into();
1648                let expr = self.parse_type_expr();
1649                Ok(ExprUnary::new_green(self.db, op, expr).into())
1650            }
1651            SyntaxKind::TerminalIdentifier | SyntaxKind::TerminalDollar => {
1652                Ok(self.parse_type_path().into())
1653            }
1654            SyntaxKind::TerminalLParen => Ok(self.expect_type_tuple_expr()),
1655            SyntaxKind::TerminalLBrack => Ok(self.expect_type_fixed_size_array_expr()),
1656            _ => {
1657                // TODO(yuval): report to diagnostics.
1658                Err(TryParseFailure::SkipToken)
1659            }
1660        }
1661    }
1662
1663    /// Returns a GreenId of a node with an ExprPath|ExprParenthesized|ExprTuple kind, or
1664    /// ExprMissing if such an expression can't be parsed.
1665    fn parse_type_expr(&mut self) -> ExprGreen {
1666        match self.try_parse_type_expr() {
1667            Ok(expr) => expr,
1668            Err(_) => {
1669                self.create_and_report_missing::<Expr>(ParserDiagnosticKind::MissingTypeExpression)
1670            }
1671        }
1672    }
1673
1674    /// Assumes the current token is LBrace.
1675    /// Expected pattern: `\{<StructArgList>\}`
1676    fn expect_struct_ctor_argument_list_braced(&mut self) -> StructArgListBracedGreen {
1677        let lbrace = self.take::<TerminalLBrace>();
1678        let arg_list = StructArgList::new_green(
1679            self.db,
1680            &self.parse_separated_list::<StructArg, TerminalComma, StructArgListElementOrSeparatorGreen>(
1681                Self::try_parse_struct_ctor_argument,
1682                is_of_kind!(rparen, block, rbrace, module_item_kw),
1683                "struct constructor argument",
1684            ),
1685        );
1686        let rbrace = self.parse_token::<TerminalRBrace>();
1687
1688        StructArgListBraced::new_green(self.db, lbrace, arg_list, rbrace)
1689    }
1690
1691    /// Assumes the current token is LParen.
1692    /// Expected pattern: `<ArgListParenthesized>`
1693    fn expect_function_call(&mut self, path: ExprPathGreen) -> ExprFunctionCallGreen {
1694        let func_name = path;
1695        let parenthesized_args = self.expect_parenthesized_argument_list();
1696        ExprFunctionCall::new_green(self.db, func_name, parenthesized_args)
1697    }
1698
1699    /// Assumes the current token is TerminalNot.
1700    /// Expected pattern: `!<WrappedArgList>`
1701    fn expect_macro_call(&mut self, path: ExprPathGreen) -> ExprInlineMacroGreen {
1702        let bang = self.take::<TerminalNot>();
1703        let macro_name = path;
1704        let token_tree_node = self.parse_token_tree_node();
1705        ExprInlineMacro::new_green(self.db, macro_name, bang, token_tree_node)
1706    }
1707
1708    /// Either parses a leaf of the tree (i.e. any non-parenthesis token) or an inner node (i.e. a
1709    /// parenthesized stream of tokens).
1710    fn parse_token_tree(&mut self) -> TokenTreeGreen {
1711        match self.peek().kind {
1712            SyntaxKind::TerminalLBrace
1713            | SyntaxKind::TerminalLParen
1714            | SyntaxKind::TerminalLBrack => self.parse_token_tree_node().into(),
1715            SyntaxKind::TerminalDollar => {
1716                let dollar: TerminalDollarGreen = self.take::<TerminalDollar>();
1717                match self.peek().kind {
1718                    SyntaxKind::TerminalLParen => {
1719                        let lparen = self.take::<TerminalLParen>();
1720                        let elements = TokenList::new_green(self.db, &self.parse_token_list());
1721                        let rparen = self.parse_token::<TerminalRParen>();
1722                        let separator: OptionTerminalCommaGreen = match self.peek().kind {
1723                            SyntaxKind::TerminalComma => self.take::<TerminalComma>().into(),
1724                            _ => OptionTerminalCommaEmpty::new_green(self.db).into(),
1725                        };
1726                        let operator = match self.peek().kind {
1727                            SyntaxKind::TerminalQuestionMark => {
1728                                self.take::<TerminalQuestionMark>().into()
1729                            }
1730                            SyntaxKind::TerminalPlus => self.take::<TerminalPlus>().into(),
1731                            SyntaxKind::TerminalMul => self.take::<TerminalMul>().into(),
1732                            _ => unreachable!(),
1733                        };
1734                        TokenTreeRepetition::new_green(
1735                            self.db, dollar, lparen, elements, rparen, separator, operator,
1736                        )
1737                        .into()
1738                    }
1739                    SyntaxKind::TerminalIdentifier => {
1740                        let identifier = self.take::<TerminalIdentifier>();
1741                        TokenTreeParam::new_green(self.db, dollar, identifier).into()
1742                    }
1743                    _ => self.parse_token_tree_leaf().into(),
1744                }
1745            }
1746            _ => self.parse_token_tree_leaf().into(),
1747        }
1748    }
1749
1750    fn parse_token_tree_leaf(&mut self) -> TokenTreeLeafGreen {
1751        let token_node = self.take_token_node();
1752        TokenTreeLeaf::new_green(self.db, token_node)
1753    }
1754
1755    fn parse_token_tree_node(&mut self) -> TokenTreeNodeGreen {
1756        let wrapped_token_tree = match self.peek().kind {
1757            SyntaxKind::TerminalLBrace => self
1758                .expect_wrapped_token_tree::<TerminalLBrace, TerminalRBrace, _, _>(
1759                    BracedTokenTree::new_green,
1760                )
1761                .into(),
1762            SyntaxKind::TerminalLParen => self
1763                .expect_wrapped_token_tree::<TerminalLParen, TerminalRParen, _, _>(
1764                    ParenthesizedTokenTree::new_green,
1765                )
1766                .into(),
1767            SyntaxKind::TerminalLBrack => self
1768                .expect_wrapped_token_tree::<TerminalLBrack, TerminalRBrack, _, _>(
1769                    BracketedTokenTree::new_green,
1770                )
1771                .into(),
1772            _ => {
1773                return self.create_and_report_missing::<TokenTreeNode>(
1774                    ParserDiagnosticKind::MissingWrappedArgList,
1775                );
1776            }
1777        };
1778        TokenTreeNode::new_green(self.db, wrapped_token_tree)
1779    }
1780
1781    /// Assumes the current token is LTerminal.
1782    /// Expected pattern: `[LTerminal](<expr>,)*<expr>?[RTerminal]`
1783    /// Gets `new_green` a green id node builder for the list of the requested type, applies it to
1784    /// the parsed list and returns the result.
1785    fn expect_wrapped_token_tree<
1786        LTerminal: syntax::node::Terminal,
1787        RTerminal: syntax::node::Terminal,
1788        ListGreen,
1789        NewGreen: Fn(&dyn SyntaxGroup, LTerminal::Green, TokenListGreen, RTerminal::Green) -> ListGreen,
1790    >(
1791        &mut self,
1792        new_green: NewGreen,
1793    ) -> ListGreen {
1794        let l_term = self.take::<LTerminal>();
1795        let tokens = self.parse_token_list();
1796        let r_term: <RTerminal as TypedSyntaxNode>::Green = self.parse_token::<RTerminal>();
1797        new_green(self.db, l_term, TokenList::new_green(self.db, &tokens), r_term)
1798    }
1799
1800    fn parse_token_list(&mut self) -> Vec<TokenTreeGreen> {
1801        let mut tokens: Vec<TokenTreeGreen> = vec![];
1802        while !matches!(
1803            self.peek().kind,
1804            SyntaxKind::TerminalRParen
1805                | SyntaxKind::TerminalRBrace
1806                | SyntaxKind::TerminalRBrack
1807                | SyntaxKind::TerminalEndOfFile
1808        ) {
1809            tokens.push(self.parse_token_tree());
1810        }
1811        tokens
1812    }
1813
1814    /// Takes a TokenNode according to the current SyntaxKind.
1815    fn take_token_node(&mut self) -> TokenNodeGreen {
1816        match self.peek().kind {
1817            SyntaxKind::TerminalIdentifier => self.take::<TerminalIdentifier>().into(),
1818            SyntaxKind::TerminalLiteralNumber => self.take::<TerminalLiteralNumber>().into(),
1819            SyntaxKind::TerminalShortString => self.take::<TerminalShortString>().into(),
1820            SyntaxKind::TerminalString => self.take::<TerminalString>().into(),
1821            SyntaxKind::TerminalAs => self.take::<TerminalAs>().into(),
1822            SyntaxKind::TerminalConst => self.take::<TerminalConst>().into(),
1823            SyntaxKind::TerminalElse => self.take::<TerminalElse>().into(),
1824            SyntaxKind::TerminalEnum => self.take::<TerminalEnum>().into(),
1825            SyntaxKind::TerminalExtern => self.take::<TerminalExtern>().into(),
1826            SyntaxKind::TerminalFalse => self.take::<TerminalFalse>().into(),
1827            SyntaxKind::TerminalFunction => self.take::<TerminalFunction>().into(),
1828            SyntaxKind::TerminalIf => self.take::<TerminalIf>().into(),
1829            SyntaxKind::TerminalWhile => self.take::<TerminalWhile>().into(),
1830            SyntaxKind::TerminalFor => self.take::<TerminalFor>().into(),
1831            SyntaxKind::TerminalLoop => self.take::<TerminalLoop>().into(),
1832            SyntaxKind::TerminalImpl => self.take::<TerminalImpl>().into(),
1833            SyntaxKind::TerminalImplicits => self.take::<TerminalImplicits>().into(),
1834            SyntaxKind::TerminalLet => self.take::<TerminalLet>().into(),
1835            SyntaxKind::TerminalMatch => self.take::<TerminalMatch>().into(),
1836            SyntaxKind::TerminalModule => self.take::<TerminalModule>().into(),
1837            SyntaxKind::TerminalMut => self.take::<TerminalMut>().into(),
1838            SyntaxKind::TerminalNoPanic => self.take::<TerminalNoPanic>().into(),
1839            SyntaxKind::TerminalOf => self.take::<TerminalOf>().into(),
1840            SyntaxKind::TerminalRef => self.take::<TerminalRef>().into(),
1841            SyntaxKind::TerminalContinue => self.take::<TerminalContinue>().into(),
1842            SyntaxKind::TerminalReturn => self.take::<TerminalReturn>().into(),
1843            SyntaxKind::TerminalBreak => self.take::<TerminalBreak>().into(),
1844            SyntaxKind::TerminalStruct => self.take::<TerminalStruct>().into(),
1845            SyntaxKind::TerminalTrait => self.take::<TerminalTrait>().into(),
1846            SyntaxKind::TerminalTrue => self.take::<TerminalTrue>().into(),
1847            SyntaxKind::TerminalType => self.take::<TerminalType>().into(),
1848            SyntaxKind::TerminalUse => self.take::<TerminalUse>().into(),
1849            SyntaxKind::TerminalPub => self.take::<TerminalPub>().into(),
1850            SyntaxKind::TerminalAnd => self.take::<TerminalAnd>().into(),
1851            SyntaxKind::TerminalAndAnd => self.take::<TerminalAndAnd>().into(),
1852            SyntaxKind::TerminalArrow => self.take::<TerminalArrow>().into(),
1853            SyntaxKind::TerminalAt => self.take::<TerminalAt>().into(),
1854            SyntaxKind::TerminalBadCharacters => self.take::<TerminalBadCharacters>().into(),
1855            SyntaxKind::TerminalColon => self.take::<TerminalColon>().into(),
1856            SyntaxKind::TerminalColonColon => self.take::<TerminalColonColon>().into(),
1857            SyntaxKind::TerminalComma => self.take::<TerminalComma>().into(),
1858            SyntaxKind::TerminalDiv => self.take::<TerminalDiv>().into(),
1859            SyntaxKind::TerminalDivEq => self.take::<TerminalDivEq>().into(),
1860            SyntaxKind::TerminalDollar => self.take::<TerminalDollar>().into(),
1861            SyntaxKind::TerminalDot => self.take::<TerminalDot>().into(),
1862            SyntaxKind::TerminalDotDot => self.take::<TerminalDotDot>().into(),
1863            SyntaxKind::TerminalDotDotEq => self.take::<TerminalDotDotEq>().into(),
1864            SyntaxKind::TerminalEndOfFile => self.take::<TerminalEndOfFile>().into(),
1865            SyntaxKind::TerminalEq => self.take::<TerminalEq>().into(),
1866            SyntaxKind::TerminalEqEq => self.take::<TerminalEqEq>().into(),
1867            SyntaxKind::TerminalGE => self.take::<TerminalGE>().into(),
1868            SyntaxKind::TerminalGT => self.take::<TerminalGT>().into(),
1869            SyntaxKind::TerminalHash => self.take::<TerminalHash>().into(),
1870            SyntaxKind::TerminalLBrace => self.take::<TerminalLBrace>().into(),
1871            SyntaxKind::TerminalLBrack => self.take::<TerminalLBrack>().into(),
1872            SyntaxKind::TerminalLE => self.take::<TerminalLE>().into(),
1873            SyntaxKind::TerminalLParen => self.take::<TerminalLParen>().into(),
1874            SyntaxKind::TerminalLT => self.take::<TerminalLT>().into(),
1875            SyntaxKind::TerminalMatchArrow => self.take::<TerminalMatchArrow>().into(),
1876            SyntaxKind::TerminalMinus => self.take::<TerminalMinus>().into(),
1877            SyntaxKind::TerminalMinusEq => self.take::<TerminalMinusEq>().into(),
1878            SyntaxKind::TerminalMod => self.take::<TerminalMod>().into(),
1879            SyntaxKind::TerminalModEq => self.take::<TerminalModEq>().into(),
1880            SyntaxKind::TerminalMul => self.take::<TerminalMul>().into(),
1881            SyntaxKind::TerminalMulEq => self.take::<TerminalMulEq>().into(),
1882            SyntaxKind::TerminalNeq => self.take::<TerminalNeq>().into(),
1883            SyntaxKind::TerminalNot => self.take::<TerminalNot>().into(),
1884            SyntaxKind::TerminalBitNot => self.take::<TerminalBitNot>().into(),
1885            SyntaxKind::TerminalOr => self.take::<TerminalOr>().into(),
1886            SyntaxKind::TerminalOrOr => self.take::<TerminalOrOr>().into(),
1887            SyntaxKind::TerminalPlus => self.take::<TerminalPlus>().into(),
1888            SyntaxKind::TerminalPlusEq => self.take::<TerminalPlusEq>().into(),
1889            SyntaxKind::TerminalQuestionMark => self.take::<TerminalQuestionMark>().into(),
1890            SyntaxKind::TerminalRBrace => self.take::<TerminalRBrace>().into(),
1891            SyntaxKind::TerminalRBrack => self.take::<TerminalRBrack>().into(),
1892            SyntaxKind::TerminalRParen => self.take::<TerminalRParen>().into(),
1893            SyntaxKind::TerminalSemicolon => self.take::<TerminalSemicolon>().into(),
1894            SyntaxKind::TerminalUnderscore => self.take::<TerminalUnderscore>().into(),
1895            SyntaxKind::TerminalXor => self.take::<TerminalXor>().into(),
1896            other => unreachable!("Unexpected token kind: {other:?}"),
1897        }
1898    }
1899    /// Returns a GreenId of a node with an ArgListParenthesized|ArgListBracketed|ArgListBraced kind
1900    /// or TryParseFailure if such an argument list can't be parsed.
1901    pub(crate) fn parse_wrapped_arg_list(&mut self) -> WrappedArgListGreen {
1902        match self.peek().kind {
1903            SyntaxKind::TerminalLParen => self
1904                .expect_wrapped_argument_list::<TerminalLParen, TerminalRParen, _, _>(
1905                    ArgListParenthesized::new_green,
1906                )
1907                .into(),
1908            SyntaxKind::TerminalLBrack => self
1909                .expect_wrapped_argument_list::<TerminalLBrack, TerminalRBrack, _, _>(
1910                    ArgListBracketed::new_green,
1911                )
1912                .into(),
1913            SyntaxKind::TerminalLBrace => self
1914                .expect_wrapped_argument_list::<TerminalLBrace, TerminalRBrace, _, _>(
1915                    ArgListBraced::new_green,
1916                )
1917                .into(),
1918            _ => self.create_and_report_missing::<WrappedArgList>(
1919                ParserDiagnosticKind::MissingWrappedArgList,
1920            ),
1921        }
1922    }
1923
1924    /// Assumes the current token is LTerminal.
1925    /// Expected pattern: `[LTerminal](<expr>,)*<expr>?[RTerminal]`
1926    /// Gets `new_green` a green id node builder for the list of the requested type, applies it to
1927    /// the parsed list and returns the result.
1928    fn expect_wrapped_argument_list<
1929        LTerminal: syntax::node::Terminal,
1930        RTerminal: syntax::node::Terminal,
1931        ListGreen,
1932        NewGreen: Fn(&dyn SyntaxGroup, LTerminal::Green, ArgListGreen, RTerminal::Green) -> ListGreen,
1933    >(
1934        &mut self,
1935        new_green: NewGreen,
1936    ) -> ListGreen {
1937        let l_term = self.take::<LTerminal>();
1938        let exprs: Vec<ArgListElementOrSeparatorGreen> = self
1939            .parse_separated_list::<Arg, TerminalComma, ArgListElementOrSeparatorGreen>(
1940                Self::try_parse_function_argument,
1941                is_of_kind!(rparen, rbrace, rbrack, block, module_item_kw),
1942                "argument",
1943            );
1944        let r_term: <RTerminal as TypedSyntaxNode>::Green = self.parse_token::<RTerminal>();
1945        new_green(self.db, l_term, ArgList::new_green(self.db, &exprs), r_term)
1946    }
1947
1948    /// Assumes the current token is LParen.
1949    /// Expected pattern: `\(<ArgList>\)`
1950    fn expect_parenthesized_argument_list(&mut self) -> ArgListParenthesizedGreen {
1951        self.expect_wrapped_argument_list::<TerminalLParen, TerminalRParen, _, _>(
1952            ArgListParenthesized::new_green,
1953        )
1954    }
1955
1956    /// Tries to parse parenthesized argument list.
1957    /// Expected pattern: `\(<ArgList>\)`
1958    fn try_parse_parenthesized_argument_list(&mut self) -> OptionArgListParenthesizedGreen {
1959        if self.peek().kind == SyntaxKind::TerminalLParen {
1960            self.expect_parenthesized_argument_list().into()
1961        } else {
1962            OptionArgListParenthesizedEmpty::new_green(self.db).into()
1963        }
1964    }
1965
1966    /// Parses a function call's argument, which contains possibly modifiers, and a argument clause.
1967    fn try_parse_function_argument(&mut self) -> TryParseResult<ArgGreen> {
1968        let modifiers_list = self.parse_modifier_list();
1969        let arg_clause = self.try_parse_argument_clause();
1970        match arg_clause {
1971            Ok(arg_clause) => {
1972                let modifiers = ModifierList::new_green(self.db, &modifiers_list);
1973                Ok(Arg::new_green(self.db, modifiers, arg_clause))
1974            }
1975            Err(_) if !modifiers_list.is_empty() => {
1976                let modifiers = ModifierList::new_green(self.db, &modifiers_list);
1977                let arg_clause = ArgClauseUnnamed::new_green(self.db, self.parse_expr()).into();
1978                Ok(Arg::new_green(self.db, modifiers, arg_clause))
1979            }
1980            Err(err) => Err(err),
1981        }
1982    }
1983
1984    /// Parses a function call's argument, which is an expression with or without the name
1985    /// of the argument.
1986    ///
1987    /// Possible patterns:
1988    /// * `<Expr>` (unnamed).
1989    /// * `<Identifier>: <Expr>` (named).
1990    /// * `:<Identifier>` (Field init shorthand - syntactic sugar for `a: a`).
1991    fn try_parse_argument_clause(&mut self) -> TryParseResult<ArgClauseGreen> {
1992        if self.peek().kind == SyntaxKind::TerminalColon {
1993            let colon = self.take::<TerminalColon>();
1994            let name = self.parse_identifier();
1995            return Ok(ArgClauseFieldInitShorthand::new_green(
1996                self.db,
1997                colon,
1998                ExprFieldInitShorthand::new_green(self.db, name),
1999            )
2000            .into());
2001        }
2002
2003        // Read an expression.
2004        let value = self.try_parse_expr()?;
2005        // If the next token is `:` and the expression is an identifier, this is the argument's
2006        // name.
2007        if self.peek().kind == SyntaxKind::TerminalColon {
2008            if let Some(argname) = self.try_extract_identifier(value) {
2009                let colon = self.take::<TerminalColon>();
2010                let expr = self.parse_expr();
2011                return Ok(ArgClauseNamed::new_green(self.db, argname, colon, expr).into());
2012            }
2013        }
2014
2015        Ok(ArgClauseUnnamed::new_green(self.db, value).into())
2016    }
2017
2018    /// If the given `expr` is a simple identifier, returns the corresponding green node.
2019    /// Otherwise, returns `TryParseFailure`.
2020    fn try_extract_identifier(&self, expr: ExprGreen) -> Option<TerminalIdentifierGreen> {
2021        // Check that `expr` is `ExprPath`.
2022        let GreenNode {
2023            kind: SyntaxKind::ExprPath,
2024            details: GreenNodeDetails::Node { children: children0, .. },
2025        } = &*expr.0.lookup_intern(self.db)
2026        else {
2027            return None;
2028        };
2029
2030        // Extract ExprPathInner
2031        let [_dollar, path_inner] = children0[..] else {
2032            return None;
2033        };
2034
2035        let GreenNode {
2036            kind: SyntaxKind::ExprPathInner,
2037            details: GreenNodeDetails::Node { children: children1, .. },
2038        } = &*path_inner.lookup_intern(self.db)
2039        else {
2040            return None;
2041        };
2042
2043        // Check that it has one child.
2044        let [path_segment] = children1[..] else {
2045            return None;
2046        };
2047
2048        // Check that `path_segment` is `PathSegmentSimple`.
2049        let GreenNode {
2050            kind: SyntaxKind::PathSegmentSimple,
2051            details: GreenNodeDetails::Node { children: children2, .. },
2052        } = &*path_segment.lookup_intern(self.db)
2053        else {
2054            return None;
2055        };
2056
2057        // Check that it has one child.
2058        let [ident] = children2[..] else {
2059            return None;
2060        };
2061
2062        // Check that it is indeed `TerminalIdentifier`.
2063        let GreenNode { kind: SyntaxKind::TerminalIdentifier, .. } =
2064            ident.lookup_intern(self.db).as_ref()
2065        else {
2066            return None;
2067        };
2068
2069        Some(TerminalIdentifierGreen(ident))
2070    }
2071
2072    /// Assumes the current token is LBrace.
2073    /// Expected pattern: `<StructArgListBraced>`
2074    fn expect_constructor_call(&mut self, path: ExprPathGreen) -> ExprStructCtorCallGreen {
2075        let ctor_name = path;
2076        let args = self.expect_struct_ctor_argument_list_braced();
2077        ExprStructCtorCall::new_green(self.db, ctor_name, args)
2078    }
2079
2080    /// Assumes the current token is LParen.
2081    /// Expected pattern: `\((<expr>,)*<expr>?\)`
2082    /// Returns a GreenId of a node with kind ExprParenthesized|ExprTuple.
2083    fn expect_parenthesized_expr(&mut self) -> ExprGreen {
2084        let lparen = self.take::<TerminalLParen>();
2085        let exprs: Vec<ExprListElementOrSeparatorGreen> = self
2086            .parse_separated_list::<Expr, TerminalComma, ExprListElementOrSeparatorGreen>(
2087                Self::try_parse_expr,
2088                is_of_kind!(rparen, block, rbrace, module_item_kw),
2089                "expression",
2090            );
2091        let rparen = self.parse_token::<TerminalRParen>();
2092
2093        if let [ExprListElementOrSeparatorGreen::Element(expr)] = &exprs[..] {
2094            // We have exactly one item and no separator --> This is not a tuple.
2095            ExprParenthesized::new_green(self.db, lparen, *expr, rparen).into()
2096        } else {
2097            ExprListParenthesized::new_green(
2098                self.db,
2099                lparen,
2100                ExprList::new_green(self.db, &exprs),
2101                rparen,
2102            )
2103            .into()
2104        }
2105    }
2106
2107    /// Assumes the current token is LParen.
2108    /// Expected pattern: `\((<type_expr>,)*<type_expr>?\)`
2109    /// Returns a GreenId of a node with kind ExprTuple.
2110    fn expect_type_tuple_expr(&mut self) -> ExprGreen {
2111        let lparen = self.take::<TerminalLParen>();
2112        let exprs: Vec<ExprListElementOrSeparatorGreen> = self
2113            .parse_separated_list::<Expr, TerminalComma, ExprListElementOrSeparatorGreen>(
2114                Self::try_parse_type_expr,
2115                is_of_kind!(rparen, block, rbrace, module_item_kw),
2116                "type expression",
2117            );
2118        let rparen = self.parse_token::<TerminalRParen>();
2119        if let [ExprListElementOrSeparatorGreen::Element(_)] = &exprs[..] {
2120            self.add_diagnostic(
2121                ParserDiagnosticKind::MissingToken(SyntaxKind::TokenComma),
2122                TextSpan { start: self.offset, end: self.offset },
2123            );
2124        }
2125        ExprListParenthesized::new_green(
2126            self.db,
2127            lparen,
2128            ExprList::new_green(self.db, &exprs),
2129            rparen,
2130        )
2131        .into()
2132    }
2133
2134    /// Assumes the current token is LBrack.
2135    /// Expected pattern: `\[<type_expr>; <expr>\]`.
2136    /// Returns a GreenId of a node with kind ExprFixedSizeArray.
2137    fn expect_type_fixed_size_array_expr(&mut self) -> ExprGreen {
2138        let lbrack = self.take::<TerminalLBrack>();
2139        let exprs: Vec<ExprListElementOrSeparatorGreen> = self
2140            .parse_separated_list::<Expr, TerminalComma, ExprListElementOrSeparatorGreen>(
2141                Self::try_parse_type_expr,
2142                is_of_kind!(rbrack, semicolon),
2143                "type expression",
2144            );
2145        let semicolon = self.parse_token::<TerminalSemicolon>();
2146        let size_expr = self.parse_expr();
2147        let fixed_size_array_size =
2148            FixedSizeArraySize::new_green(self.db, semicolon, size_expr).into();
2149        let rbrack = self.parse_token::<TerminalRBrack>();
2150        ExprFixedSizeArray::new_green(
2151            self.db,
2152            lbrack,
2153            ExprList::new_green(self.db, &exprs),
2154            fixed_size_array_size,
2155            rbrack,
2156        )
2157        .into()
2158    }
2159
2160    /// Assumes the current token is DotDot.
2161    /// Expected pattern: `\.\.<Expr>`
2162    fn expect_struct_argument_tail(&mut self) -> StructArgTailGreen {
2163        let dotdot = self.take::<TerminalDotDot>(); // ..
2164        // TODO(yuval): consider changing this to SimpleExpr once it exists.
2165        let expr = self.parse_expr();
2166        StructArgTail::new_green(self.db, dotdot, expr)
2167    }
2168
2169    // For the similar syntax in Rust, see
2170    // https://doc.rust-lang.org/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax.
2171    /// Like parse_argument, but also allows a struct-arg-tail, e.g. 'let s2 = S{"s2", ..s1};'
2172    /// Returns a GreenId of a node with kind StructArgSingle|StructArgTail.
2173    fn try_parse_struct_ctor_argument(&mut self) -> TryParseResult<StructArgGreen> {
2174        match self.peek().kind {
2175            SyntaxKind::TerminalDotDot => Ok(self.expect_struct_argument_tail().into()),
2176            _ => self.try_parse_argument_single().map(|arg| arg.into()),
2177        }
2178    }
2179
2180    /// Returns a GreenId of a node with kind StructArgExpr or OptionStructArgExprEmpty if an
2181    /// argument expression `(":<value>")` can't be parsed.
2182    fn parse_option_struct_arg_expression(&mut self) -> OptionStructArgExprGreen {
2183        if self.peek().kind == SyntaxKind::TerminalColon {
2184            let colon = self.take::<TerminalColon>();
2185            let value = self.parse_expr();
2186            StructArgExpr::new_green(self.db, colon, value).into()
2187        } else {
2188            OptionStructArgExprEmpty::new_green(self.db).into()
2189        }
2190    }
2191
2192    /// Returns a GreenId of a node with kind OptionExprClause or OptionExprClauseEmpty if an
2193    /// argument expression `("Expr")` can't be parsed.
2194    fn parse_option_expression_clause(&mut self) -> OptionExprClauseGreen {
2195        if self.peek().kind == SyntaxKind::TerminalSemicolon {
2196            OptionExprClauseEmpty::new_green(self.db).into()
2197        } else {
2198            let value = self.parse_expr();
2199            ExprClause::new_green(self.db, value).into()
2200        }
2201    }
2202
2203    /// Returns a GreenId of a node with kind StructArgSingle.
2204    fn try_parse_argument_single(&mut self) -> TryParseResult<StructArgSingleGreen> {
2205        let identifier = self.try_parse_identifier()?;
2206        let struct_arg_expr = self.parse_option_struct_arg_expression(); // :<expr>
2207        Ok(StructArgSingle::new_green(self.db, identifier, struct_arg_expr))
2208    }
2209
2210    /// Returns a GreenId of a node with kind ExprBlock.
2211    fn parse_block(&mut self) -> ExprBlockGreen {
2212        let skipped_tokens = self.skip_until(is_of_kind!(rbrace, lbrace, module_item_kw, block));
2213
2214        if let Err(SkippedError(span)) = skipped_tokens {
2215            self.add_diagnostic(
2216                ParserDiagnosticKind::SkippedElement { element_name: "'{'".into() },
2217                span,
2218            );
2219        }
2220
2221        let is_rbrace_or_top_level = is_of_kind!(rbrace, module_item_kw);
2222        if is_rbrace_or_top_level(self.peek().kind) {
2223            return ExprBlock::new_green(
2224                self.db,
2225                self.create_and_report_missing_terminal::<TerminalLBrace>(),
2226                StatementList::new_green(self.db, &[]),
2227                TerminalRBrace::missing(self.db),
2228            );
2229        }
2230        // Don't report diagnostic if one has already been reported.
2231        let lbrace = self.parse_token_ex::<TerminalLBrace>(skipped_tokens.is_ok());
2232        let statements = StatementList::new_green(
2233            self.db,
2234            &self.parse_list(
2235                Self::try_parse_statement,
2236                is_of_kind!(rbrace, module_item_kw),
2237                "statement",
2238            ),
2239        );
2240        let rbrace = self.parse_token::<TerminalRBrace>();
2241        ExprBlock::new_green(self.db, lbrace, statements, rbrace)
2242    }
2243
2244    /// Assumes the current token is `Match`.
2245    /// Expected pattern: `match <expr> \{<MatchArm>*\}`
2246    fn expect_match_expr(&mut self) -> ExprMatchGreen {
2247        let match_kw = self.take::<TerminalMatch>();
2248        let expr =
2249            self.parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Forbid, AndLetBehavior::Simple);
2250        let lbrace = self.parse_token::<TerminalLBrace>();
2251        let arms = MatchArms::new_green(
2252            self.db,
2253            &self
2254                .parse_separated_list::<MatchArm, TerminalComma, MatchArmsElementOrSeparatorGreen>(
2255                    Self::try_parse_match_arm,
2256                    is_of_kind!(block, rbrace, module_item_kw),
2257                    "match arm",
2258                ),
2259        );
2260        let rbrace = self.parse_token::<TerminalRBrace>();
2261        ExprMatch::new_green(self.db, match_kw, expr, lbrace, arms, rbrace)
2262    }
2263
2264    /// Assumes the current token is `If`.
2265    fn expect_if_expr(&mut self) -> ExprIfGreen {
2266        let if_kw = self.take::<TerminalIf>();
2267
2268        let conditions = self.parse_condition_list();
2269        let if_block = self.parse_block();
2270        let else_clause = if self.peek().kind == SyntaxKind::TerminalElse {
2271            let else_kw = self.take::<TerminalElse>();
2272            let else_block_or_if = if self.peek().kind == SyntaxKind::TerminalIf {
2273                self.expect_if_expr().into()
2274            } else {
2275                self.parse_block().into()
2276            };
2277            ElseClause::new_green(self.db, else_kw, else_block_or_if).into()
2278        } else {
2279            OptionElseClauseEmpty::new_green(self.db).into()
2280        };
2281        ExprIf::new_green(self.db, if_kw, conditions, if_block, else_clause)
2282    }
2283
2284    /// If `condition` is a [ConditionExpr] of the form `<expr> <op> <expr>`, returns the operator's
2285    /// kind.
2286    /// Otherwise, returns `None`.
2287    fn get_binary_operator(&self, condition: ConditionGreen) -> Option<SyntaxKind> {
2288        let condition_expr_green = self.db.lookup_intern_green(condition.0);
2289        require(condition_expr_green.kind == SyntaxKind::ConditionExpr)?;
2290
2291        let expr_binary_green = self.db.lookup_intern_green(condition_expr_green.children()[0]);
2292        require(expr_binary_green.kind == SyntaxKind::ExprBinary)?;
2293
2294        Some(self.db.lookup_intern_green(expr_binary_green.children()[1]).kind)
2295    }
2296
2297    /// Parses a conjunction of conditions of the form `<condition> && <condition> && ...`,
2298    /// where each condition is either `<expr>` or `let <pattern> = <expr>`.
2299    ///
2300    /// Assumes the next expected token (after the condition list) is `{`. This assumption is used
2301    /// in case of an error.
2302    fn parse_condition_list(&mut self) -> ConditionListAndGreen {
2303        let and_and_precedence = get_post_operator_precedence(SyntaxKind::TerminalAndAnd).unwrap();
2304
2305        let start_offset = self.offset.add_width(self.current_width);
2306        let condition = self.parse_condition_expr(false);
2307        let mut conditions: Vec<ConditionListAndElementOrSeparatorGreen> = vec![condition.into()];
2308
2309        // If there is more than one condition, check that the first condition does not have a
2310        // precedence lower than `&&`.
2311        if self.peek().kind == SyntaxKind::TerminalAndAnd {
2312            if let Some(op) = self.get_binary_operator(condition) {
2313                if let Some(precedence) = get_post_operator_precedence(op) {
2314                    if precedence > and_and_precedence {
2315                        let offset =
2316                            self.offset.add_width(self.current_width - self.last_trivia_length);
2317                        self.add_diagnostic(
2318                            ParserDiagnosticKind::LowPrecedenceOperatorInIfLet { op },
2319                            TextSpan { start: start_offset, end: offset },
2320                        );
2321                    }
2322                }
2323            }
2324        }
2325
2326        while self.peek().kind == SyntaxKind::TerminalAndAnd {
2327            let and_and = self.take::<TerminalAndAnd>();
2328            conditions.push(and_and.into());
2329
2330            let condition = self.parse_condition_expr(true);
2331            conditions.push(condition.into());
2332        }
2333
2334        let peek_item = self.peek();
2335        if let Some(op_precedence) = get_post_operator_precedence(peek_item.kind) {
2336            if op_precedence > and_and_precedence {
2337                let offset = self.offset.add_width(self.current_width);
2338                self.add_diagnostic(
2339                    ParserDiagnosticKind::LowPrecedenceOperatorInIfLet { op: peek_item.kind },
2340                    TextSpan { start: offset, end: offset },
2341                );
2342                // Skip the rest of the tokens until `{`. Don't report additional diagnostics.
2343                let _ = self.skip_until(is_of_kind!(rbrace, lbrace, module_item_kw, block));
2344            }
2345        }
2346
2347        ConditionListAnd::new_green(self.db, &conditions)
2348    }
2349
2350    /// Parses condition exprs of the form `<expr>` or `let <pattern> = <expr>`.
2351    ///
2352    /// In the case of `let <pattern> = <expr>`, the parser will stop at the first `&&` token
2353    /// (which is not inside parenthesis).
2354    /// If `stop_at_and` is true, this will also be the case for `<expr>`.
2355    fn parse_condition_expr(&mut self, stop_at_and: bool) -> ConditionGreen {
2356        let and_and_precedence = get_post_operator_precedence(SyntaxKind::TerminalAndAnd).unwrap();
2357        if self.peek().kind == SyntaxKind::TerminalLet {
2358            let let_kw = self.take::<TerminalLet>();
2359            let pattern_list = self
2360            .parse_separated_list_inner::<Pattern, TerminalOr, PatternListOrElementOrSeparatorGreen>(
2361                Self::try_parse_pattern,
2362                is_of_kind!(eq),
2363                "pattern",
2364                Some(ParserDiagnosticKind::DisallowedTrailingSeparatorOr),
2365            );
2366
2367            let pattern_list_green = if pattern_list.is_empty() {
2368                self.create_and_report_missing::<PatternListOr>(
2369                    ParserDiagnosticKind::MissingPattern,
2370                )
2371            } else {
2372                PatternListOr::new_green(self.db, &pattern_list)
2373            };
2374            let eq = self.parse_token::<TerminalEq>();
2375            let expr: ExprGreen = self.parse_expr_limited(
2376                and_and_precedence,
2377                LbraceAllowed::Forbid,
2378                AndLetBehavior::Stop,
2379            );
2380            ConditionLet::new_green(self.db, let_kw, pattern_list_green, eq, expr).into()
2381        } else {
2382            let condition = self.parse_expr_limited(
2383                if stop_at_and { and_and_precedence } else { MAX_PRECEDENCE },
2384                LbraceAllowed::Forbid,
2385                AndLetBehavior::Stop,
2386            );
2387            ConditionExpr::new_green(self.db, condition).into()
2388        }
2389    }
2390
2391    /// Assumes the current token is `Loop`.
2392    /// Expected pattern: `loop <block>`.
2393    fn expect_loop_expr(&mut self) -> ExprLoopGreen {
2394        let loop_kw = self.take::<TerminalLoop>();
2395        let body = self.parse_block();
2396
2397        ExprLoop::new_green(self.db, loop_kw, body)
2398    }
2399
2400    /// Assumes the current token is `While`.
2401    /// Expected pattern: `while <condition> <block>`.
2402    fn expect_while_expr(&mut self) -> ExprWhileGreen {
2403        let while_kw = self.take::<TerminalWhile>();
2404        let conditions = self.parse_condition_list();
2405        let body = self.parse_block();
2406
2407        ExprWhile::new_green(self.db, while_kw, conditions, body)
2408    }
2409
2410    /// Assumes the current token is `For`.
2411    /// Expected pattern: `for <pattern> <identifier> <expression> <block>`.
2412    /// Identifier will be checked to be 'in' in semantics.
2413    fn expect_for_expr(&mut self) -> ExprForGreen {
2414        let for_kw = self.take::<TerminalFor>();
2415        let pattern = self.parse_pattern();
2416        let ident = self.take_raw();
2417        let in_identifier: TerminalIdentifierGreen = match ident.text.as_str() {
2418            "in" => self.add_trivia_to_terminal::<TerminalIdentifier>(ident),
2419            _ => {
2420                self.append_skipped_token_to_pending_trivia(
2421                    ident,
2422                    ParserDiagnosticKind::SkippedElement { element_name: "'in'".into() },
2423                );
2424                TerminalIdentifier::missing(self.db)
2425            }
2426        };
2427        let expression =
2428            self.parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Forbid, AndLetBehavior::Simple);
2429        let body = self.parse_block();
2430        ExprFor::new_green(self.db, for_kw, pattern, in_identifier, expression, body)
2431    }
2432
2433    /// Assumes the current token is `|`.
2434    /// Expected pattern: `| <params> | <ReturnTypeClause> <expression>`.
2435    fn expect_closure_expr_nary(&mut self) -> ExprClosureGreen {
2436        let leftor = self.take::<TerminalOr>();
2437        let params = self.parse_closure_param_list();
2438        let rightor = self.parse_token::<TerminalOr>();
2439
2440        self.parse_closure_expr_body(
2441            ClosureParamWrapperNAry::new_green(self.db, leftor, params, rightor).into(),
2442        )
2443    }
2444    /// Assumes the current token is `||`.
2445    /// Expected pattern: `|| <ReturnTypeClause> <expression> `.
2446    fn expect_closure_expr_nullary(&mut self) -> ExprClosureGreen {
2447        let wrapper = self.take::<TerminalOrOr>().into();
2448        self.parse_closure_expr_body(wrapper)
2449    }
2450    fn parse_closure_expr_body(&mut self, wrapper: ClosureParamWrapperGreen) -> ExprClosureGreen {
2451        let mut block_required = self.peek().kind == SyntaxKind::TerminalArrow;
2452
2453        let return_type_clause = self.parse_option_return_type_clause();
2454        let optional_no_panic = if self.peek().kind == SyntaxKind::TerminalNoPanic {
2455            block_required = true;
2456            self.take::<TerminalNoPanic>().into()
2457        } else {
2458            OptionTerminalNoPanicEmpty::new_green(self.db).into()
2459        };
2460        let expr = if block_required { self.parse_block().into() } else { self.parse_expr() };
2461
2462        ExprClosure::new_green(self.db, wrapper, return_type_clause, optional_no_panic, expr)
2463    }
2464
2465    /// Assumes the current token is LBrack.
2466    /// Expected pattern: `\[<expr>; <expr>\]`.
2467    fn expect_fixed_size_array_expr(&mut self) -> ExprFixedSizeArrayGreen {
2468        let lbrack = self.take::<TerminalLBrack>();
2469        let exprs: Vec<ExprListElementOrSeparatorGreen> = self
2470            .parse_separated_list::<Expr, TerminalComma, ExprListElementOrSeparatorGreen>(
2471                Self::try_parse_expr,
2472                is_of_kind!(rbrack, semicolon),
2473                "expression",
2474            );
2475        let size_green = if self.peek().kind == SyntaxKind::TerminalSemicolon {
2476            let semicolon = self.take::<TerminalSemicolon>();
2477            let size = self.parse_expr();
2478            FixedSizeArraySize::new_green(self.db, semicolon, size).into()
2479        } else {
2480            OptionFixedSizeArraySizeEmpty::new_green(self.db).into()
2481        };
2482        let rbrack = self.parse_token::<TerminalRBrack>();
2483        ExprFixedSizeArray::new_green(
2484            self.db,
2485            lbrack,
2486            ExprList::new_green(self.db, &exprs),
2487            size_green,
2488            rbrack,
2489        )
2490    }
2491
2492    /// Returns a GreenId of a node with a MatchArm kind or TryParseFailure if a match arm can't be
2493    /// parsed.
2494    pub fn try_parse_match_arm(&mut self) -> TryParseResult<MatchArmGreen> {
2495        let pattern_list = self
2496            .parse_separated_list_inner::<Pattern, TerminalOr, PatternListOrElementOrSeparatorGreen>(
2497                Self::try_parse_pattern,
2498                is_of_kind!(match_arrow, rparen, block, rbrace, module_item_kw),
2499                "pattern",
2500                Some(ParserDiagnosticKind::DisallowedTrailingSeparatorOr),
2501            );
2502        if pattern_list.is_empty() {
2503            return Err(TryParseFailure::SkipToken);
2504        }
2505
2506        let pattern_list_green = PatternListOr::new_green(self.db, &pattern_list);
2507
2508        let arrow = self.parse_token::<TerminalMatchArrow>();
2509        let expr = self.parse_expr();
2510        Ok(MatchArm::new_green(self.db, pattern_list_green, arrow, expr))
2511    }
2512
2513    /// Returns a GreenId of a node with some Pattern kind (see
2514    /// [syntax::node::ast::Pattern]) or TryParseFailure if a pattern can't be parsed.
2515    fn try_parse_pattern(&mut self) -> TryParseResult<PatternGreen> {
2516        let modifier_list = self.parse_modifier_list();
2517        if !modifier_list.is_empty() {
2518            let modifiers = ModifierList::new_green(self.db, &modifier_list);
2519            let name = self.parse_identifier();
2520            return Ok(PatternIdentifier::new_green(self.db, modifiers, name).into());
2521        };
2522
2523        // TODO(yuval): Support "Or" patterns.
2524        Ok(match self.peek().kind {
2525            SyntaxKind::TerminalLiteralNumber => self.take_terminal_literal_number().into(),
2526            SyntaxKind::TerminalShortString => self.take_terminal_short_string().into(),
2527            SyntaxKind::TerminalTrue => self.take::<TerminalTrue>().into(),
2528            SyntaxKind::TerminalFalse => self.take::<TerminalFalse>().into(),
2529            SyntaxKind::TerminalUnderscore => self.take::<TerminalUnderscore>().into(),
2530            SyntaxKind::TerminalIdentifier => {
2531                // TODO(ilya): Consider parsing a single identifier as PatternIdentifier rather
2532                // then ExprPath.
2533                let path = self.parse_path();
2534                match self.peek().kind {
2535                    SyntaxKind::TerminalLBrace => {
2536                        let lbrace = self.take::<TerminalLBrace>();
2537                        let params = PatternStructParamList::new_green(
2538                            self.db,
2539                            &self.parse_separated_list::<
2540                                PatternStructParam,
2541                                TerminalComma,
2542                                PatternStructParamListElementOrSeparatorGreen>
2543                            (
2544                                Self::try_parse_pattern_struct_param,
2545                                is_of_kind!(rparen, block, rbrace, module_item_kw),
2546                                "struct pattern parameter",
2547                            ),
2548                        );
2549                        let rbrace = self.parse_token::<TerminalRBrace>();
2550                        PatternStruct::new_green(self.db, path, lbrace, params, rbrace).into()
2551                    }
2552                    SyntaxKind::TerminalLParen => {
2553                        // Enum pattern.
2554                        let lparen = self.take::<TerminalLParen>();
2555                        let pattern = self.parse_pattern();
2556                        let rparen = self.parse_token::<TerminalRParen>();
2557                        let inner_pattern =
2558                            PatternEnumInnerPattern::new_green(self.db, lparen, pattern, rparen);
2559                        PatternEnum::new_green(self.db, path, inner_pattern.into()).into()
2560                    }
2561                    _ => {
2562                        // Check that `expr` is `ExprPath`.
2563                        let GreenNode {
2564                            kind: SyntaxKind::ExprPath,
2565                            details: GreenNodeDetails::Node { children: path_children, .. },
2566                        } = &*path.0.lookup_intern(self.db)
2567                        else {
2568                            return Err(TryParseFailure::SkipToken);
2569                        };
2570
2571                        // Extract ExprPathInner
2572                        let [_dollar, path_inner] = path_children[..] else {
2573                            return Err(TryParseFailure::SkipToken);
2574                        };
2575
2576                        let GreenNode {
2577                            kind: SyntaxKind::ExprPathInner,
2578                            details: GreenNodeDetails::Node { children: inner_path_children, .. },
2579                        } = &*path_inner.lookup_intern(self.db)
2580                        else {
2581                            return Err(TryParseFailure::SkipToken);
2582                        };
2583
2584                        // If the path has more than 1 element assume it's a simplified Enum variant
2585                        // Eg. MyEnum::A(()) ~ MyEnum::A
2586                        // Multi-element path identifiers aren't allowed, for now this mechanism is
2587                        // sufficient.
2588                        match inner_path_children.len() {
2589                            // 0 => return None, - unreachable
2590                            1 => path.into(),
2591                            _ => PatternEnum::new_green(
2592                                self.db,
2593                                path,
2594                                OptionPatternEnumInnerPatternEmpty::new_green(self.db).into(),
2595                            )
2596                            .into(),
2597                        }
2598                    }
2599                }
2600            }
2601            SyntaxKind::TerminalLParen => {
2602                let lparen = self.take::<TerminalLParen>();
2603                let patterns = PatternList::new_green(self.db,  &self.parse_separated_list::<
2604                    Pattern,
2605                    TerminalComma,
2606                    PatternListElementOrSeparatorGreen>
2607                (
2608                    Self::try_parse_pattern,
2609                    is_of_kind!(rparen, block, rbrace, module_item_kw),
2610                    "pattern",
2611                ));
2612                let rparen = self.parse_token::<TerminalRParen>();
2613                PatternTuple::new_green(self.db, lparen, patterns, rparen).into()
2614            }
2615            SyntaxKind::TerminalLBrack => {
2616                let lbrack = self.take::<TerminalLBrack>();
2617                let patterns = PatternList::new_green(self.db,  &self.parse_separated_list::<
2618                    Pattern,
2619                    TerminalComma,
2620                    PatternListElementOrSeparatorGreen>
2621                (
2622                    Self::try_parse_pattern,
2623                    is_of_kind!(rbrack, block, rbrace, module_item_kw),
2624                    "pattern",
2625                ));
2626                let rbrack = self.parse_token::<TerminalRBrack>();
2627                PatternFixedSizeArray::new_green(self.db, lbrack, patterns, rbrack).into()
2628            }
2629            _ => return Err(TryParseFailure::SkipToken),
2630        })
2631    }
2632    /// Returns a GreenId of a node with some Pattern kind (see
2633    /// [syntax::node::ast::Pattern]).
2634    fn parse_pattern(&mut self) -> PatternGreen {
2635        // If not found, return a missing underscore pattern.
2636        match self.try_parse_pattern() {
2637            Ok(pattern) => pattern,
2638            Err(_) => self.create_and_report_missing_terminal::<TerminalUnderscore>().into(),
2639        }
2640    }
2641
2642    /// Returns a GreenId of a syntax inside a struct pattern. Example:
2643    /// `MyStruct { param0, param1: _, .. }`.
2644    fn try_parse_pattern_struct_param(&mut self) -> TryParseResult<PatternStructParamGreen> {
2645        Ok(match self.peek().kind {
2646            SyntaxKind::TerminalDotDot => self.take::<TerminalDotDot>().into(),
2647            _ => {
2648                let modifier_list = self.parse_modifier_list();
2649                let name = if modifier_list.is_empty() {
2650                    self.try_parse_identifier()?
2651                } else {
2652                    self.parse_identifier()
2653                };
2654                let modifiers = ModifierList::new_green(self.db, &modifier_list);
2655                if self.peek().kind == SyntaxKind::TerminalColon {
2656                    let colon = self.take::<TerminalColon>();
2657                    let pattern = self.parse_pattern();
2658                    PatternStructParamWithExpr::new_green(self.db, modifiers, name, colon, pattern)
2659                        .into()
2660                } else {
2661                    PatternIdentifier::new_green(self.db, modifiers, name).into()
2662                }
2663            }
2664        })
2665    }
2666
2667    // ------------------------------- Statements -------------------------------
2668
2669    /// Returns a GreenId of a node with a Statement.* kind (see
2670    /// [syntax::node::ast::Statement]) or TryParseFailure if a statement can't be parsed.
2671    pub fn try_parse_statement(&mut self) -> TryParseResult<StatementGreen> {
2672        let maybe_attributes = self.try_parse_attribute_list("Statement");
2673        let (has_attrs, attributes) = match maybe_attributes {
2674            Ok(attributes) => (true, attributes),
2675            Err(_) => (false, AttributeList::new_green(self.db, &[])),
2676        };
2677        match self.peek().kind {
2678            SyntaxKind::TerminalLet => {
2679                let let_kw = self.take::<TerminalLet>();
2680                let pattern = self.parse_pattern();
2681                let type_clause = self.parse_option_type_clause();
2682                let eq = self.parse_token::<TerminalEq>();
2683                let rhs = self.parse_expr();
2684
2685                // Check if this is a let-else statement.
2686                let let_else_clause: OptionLetElseClauseGreen =
2687                    if self.peek().kind == SyntaxKind::TerminalElse {
2688                        let else_kw = self.take::<TerminalElse>();
2689                        let else_block = self.parse_block();
2690                        LetElseClause::new_green(self.db, else_kw, else_block).into()
2691                    } else {
2692                        OptionLetElseClauseEmpty::new_green(self.db).into()
2693                    };
2694
2695                let semicolon = self.parse_token::<TerminalSemicolon>();
2696                Ok(StatementLet::new_green(
2697                    self.db,
2698                    attributes,
2699                    let_kw,
2700                    pattern,
2701                    type_clause,
2702                    eq,
2703                    rhs,
2704                    let_else_clause,
2705                    semicolon,
2706                )
2707                .into())
2708            }
2709            SyntaxKind::TerminalContinue => {
2710                let continue_kw = self.take::<TerminalContinue>();
2711                let semicolon = self.parse_token::<TerminalSemicolon>();
2712                Ok(StatementContinue::new_green(self.db, attributes, continue_kw, semicolon).into())
2713            }
2714            SyntaxKind::TerminalReturn => {
2715                let return_kw = self.take::<TerminalReturn>();
2716                let expr = self.parse_option_expression_clause();
2717                let semicolon = self.parse_token::<TerminalSemicolon>();
2718                Ok(StatementReturn::new_green(self.db, attributes, return_kw, expr, semicolon)
2719                    .into())
2720            }
2721            SyntaxKind::TerminalBreak => {
2722                let break_kw = self.take::<TerminalBreak>();
2723                let expr = self.parse_option_expression_clause();
2724                let semicolon = self.parse_token::<TerminalSemicolon>();
2725                Ok(StatementBreak::new_green(self.db, attributes, break_kw, expr, semicolon).into())
2726            }
2727            SyntaxKind::TerminalConst => {
2728                let const_kw = self.take::<TerminalConst>();
2729                Ok(StatementItem::new_green(
2730                    self.db,
2731                    self.expect_item_const(
2732                        attributes,
2733                        VisibilityDefault::new_green(self.db).into(),
2734                        const_kw,
2735                    )
2736                    .into(),
2737                )
2738                .into())
2739            }
2740            SyntaxKind::TerminalUse => Ok(StatementItem::new_green(
2741                self.db,
2742                self.expect_item_use(attributes, VisibilityDefault::new_green(self.db).into())
2743                    .into(),
2744            )
2745            .into()),
2746            SyntaxKind::TerminalType => Ok(StatementItem::new_green(
2747                self.db,
2748                self.expect_item_type_alias(
2749                    attributes,
2750                    VisibilityDefault::new_green(self.db).into(),
2751                )
2752                .into(),
2753            )
2754            .into()),
2755            _ => match self.try_parse_expr() {
2756                Ok(expr) => {
2757                    let optional_semicolon = if self.peek().kind == SyntaxKind::TerminalSemicolon {
2758                        self.take::<TerminalSemicolon>().into()
2759                    } else {
2760                        OptionTerminalSemicolonEmpty::new_green(self.db).into()
2761                    };
2762                    Ok(StatementExpr::new_green(self.db, attributes, expr, optional_semicolon)
2763                        .into())
2764                }
2765                Err(_) if has_attrs => Ok(self.skip_taken_node_and_return_missing::<Statement>(
2766                    attributes,
2767                    ParserDiagnosticKind::AttributesWithoutStatement,
2768                )),
2769                Err(err) => Err(err),
2770            },
2771        }
2772    }
2773
2774    /// Returns a GreenId of a node with kind TypeClause or OptionTypeClauseEmpty if a type clause
2775    /// can't be parsed.
2776    fn parse_option_type_clause(&mut self) -> OptionTypeClauseGreen {
2777        match self.try_parse_type_clause() {
2778            Some(green) => green.into(),
2779            None => OptionTypeClauseEmpty::new_green(self.db).into(),
2780        }
2781    }
2782
2783    /// Parses a type clause of the form: `: <type>`.
2784    fn parse_type_clause(&mut self, error_recovery: ErrorRecovery) -> TypeClauseGreen {
2785        match self.try_parse_type_clause() {
2786            Some(green) => green,
2787            None => {
2788                let res = self.create_and_report_missing::<TypeClause>(
2789                    ParserDiagnosticKind::MissingTypeClause,
2790                );
2791                self.skip_until(error_recovery.should_stop).ok();
2792                res
2793            }
2794        }
2795    }
2796    fn try_parse_type_clause(&mut self) -> Option<TypeClauseGreen> {
2797        if self.peek().kind == SyntaxKind::TerminalColon {
2798            let colon = self.take::<TerminalColon>();
2799            let ty = self.parse_type_expr();
2800            Some(TypeClause::new_green(self.db, colon, ty))
2801        } else {
2802            None
2803        }
2804    }
2805
2806    /// Returns a GreenId of a node with kind ReturnTypeClause or OptionReturnTypeClauseEmpty if a
2807    /// return type clause can't be parsed.
2808    fn parse_option_return_type_clause(&mut self) -> OptionReturnTypeClauseGreen {
2809        if self.peek().kind == SyntaxKind::TerminalArrow {
2810            let arrow = self.take::<TerminalArrow>();
2811            let return_type = self.parse_type_expr();
2812            ReturnTypeClause::new_green(self.db, arrow, return_type).into()
2813        } else {
2814            OptionReturnTypeClauseEmpty::new_green(self.db).into()
2815        }
2816    }
2817
2818    /// Returns a GreenId of a node with kind ImplicitsClause or OptionImplicitsClauseEmpty if a
2819    /// implicits-clause can't be parsed.
2820    fn parse_option_implicits_clause(&mut self) -> OptionImplicitsClauseGreen {
2821        if self.peek().kind == SyntaxKind::TerminalImplicits {
2822            let implicits_kw = self.take::<TerminalImplicits>();
2823            let lparen = self.parse_token::<TerminalLParen>();
2824            let implicits = ImplicitsList::new_green(
2825                self.db,
2826                &self.parse_separated_list::<ExprPath, TerminalComma, ImplicitsListElementOrSeparatorGreen>(
2827                    Self::try_parse_path,
2828                    // Don't stop at keywords as try_parse_path handles keywords inside it. Otherwise the diagnostic is less accurate.
2829                    is_of_kind!(rparen, lbrace, rbrace),
2830                    "implicit type",
2831                ),
2832            );
2833            let rparen = self.parse_token::<TerminalRParen>();
2834            ImplicitsClause::new_green(self.db, implicits_kw, lparen, implicits, rparen).into()
2835        } else {
2836            OptionImplicitsClauseEmpty::new_green(self.db).into()
2837        }
2838    }
2839
2840    /// Returns a GreenId of a node with kind ParamList.
2841    fn parse_param_list(&mut self) -> ParamListGreen {
2842        ParamList::new_green(
2843            self.db,
2844            &self.parse_separated_list::<Param, TerminalComma, ParamListElementOrSeparatorGreen>(
2845                Self::try_parse_param,
2846                is_of_kind!(rparen, block, lbrace, rbrace, module_item_kw),
2847                "parameter",
2848            ),
2849        )
2850    }
2851
2852    /// Returns a GreenId of a node with kind ClosureParamList.
2853    fn parse_closure_param_list(&mut self) -> ParamListGreen {
2854        ParamList::new_green(
2855            self.db,
2856            &self.parse_separated_list::<Param, TerminalComma, ParamListElementOrSeparatorGreen>(
2857                Self::try_parse_closure_param,
2858                is_of_kind!(or, block, lbrace, rbrace, module_item_kw),
2859                "parameter",
2860            ),
2861        )
2862    }
2863
2864    /// Returns a GreenId of a node with kind Modifier or TryParseFailure if a modifier can't be
2865    /// parsed.
2866    fn try_parse_modifier(&mut self) -> Option<ModifierGreen> {
2867        match self.peek().kind {
2868            SyntaxKind::TerminalRef => Some(self.take::<TerminalRef>().into()),
2869            SyntaxKind::TerminalMut => Some(self.take::<TerminalMut>().into()),
2870            _ => None,
2871        }
2872    }
2873
2874    /// Returns a vector of GreenIds with kind Modifier.
2875    fn parse_modifier_list(&mut self) -> Vec<ModifierGreen> {
2876        let mut modifier_list = vec![];
2877
2878        while let Some(modifier) = self.try_parse_modifier() {
2879            modifier_list.push(modifier);
2880        }
2881        modifier_list
2882    }
2883
2884    /// Returns a GreenId of a node with kind Param or TryParseFailure if a parameter can't be
2885    /// parsed.
2886    fn try_parse_param(&mut self) -> TryParseResult<ParamGreen> {
2887        let modifier_list = self.parse_modifier_list();
2888        let name = if modifier_list.is_empty() {
2889            self.try_parse_identifier()?
2890        } else {
2891            // If we had modifiers then the identifier is not optional and can't be '_'.
2892            self.parse_identifier()
2893        };
2894
2895        let type_clause = self
2896            .parse_type_clause(ErrorRecovery {
2897                should_stop: is_of_kind!(comma, rparen, module_item_kw),
2898            })
2899            .into();
2900        Ok(Param::new_green(
2901            self.db,
2902            ModifierList::new_green(self.db, &modifier_list),
2903            name,
2904            type_clause,
2905        ))
2906    }
2907
2908    /// Returns a GreenId of a node with kind Param or TryParseFailure if a parameter can't
2909    /// be parsed.
2910    fn try_parse_closure_param(&mut self) -> TryParseResult<ParamGreen> {
2911        let modifier_list = self.parse_modifier_list();
2912        let name = if modifier_list.is_empty() {
2913            self.try_parse_identifier()?
2914        } else {
2915            // If we had modifiers then the identifier is not optional and can't be '_'.
2916            self.parse_identifier()
2917        };
2918
2919        let type_clause = self.parse_option_type_clause();
2920        Ok(Param::new_green(
2921            self.db,
2922            ModifierList::new_green(self.db, &modifier_list),
2923            name,
2924            type_clause,
2925        ))
2926    }
2927
2928    /// Returns a GreenId of a node with kind MemberList.
2929    fn parse_member_list(&mut self) -> MemberListGreen {
2930        MemberList::new_green(
2931            self.db,
2932            &self.parse_separated_list::<Member, TerminalComma, MemberListElementOrSeparatorGreen>(
2933                Self::try_parse_member,
2934                is_of_kind!(rparen, block, lbrace, rbrace, module_item_kw),
2935                "member or variant",
2936            ),
2937        )
2938    }
2939
2940    /// Returns a GreenId of a node with kind Member or TryParseFailure if a struct member can't be
2941    /// parsed.
2942    fn try_parse_member(&mut self) -> TryParseResult<MemberGreen> {
2943        let attributes = self.try_parse_attribute_list("Struct member");
2944        let visibility = self.parse_visibility();
2945        let (name, attributes) = match attributes {
2946            Ok(attributes) => (self.parse_identifier(), attributes),
2947            Err(_) => (self.try_parse_identifier()?, AttributeList::new_green(self.db, &[])),
2948        };
2949        let type_clause = self.parse_type_clause(ErrorRecovery {
2950            should_stop: is_of_kind!(comma, rbrace, module_item_kw),
2951        });
2952        Ok(Member::new_green(self.db, attributes, visibility, name, type_clause))
2953    }
2954
2955    /// Returns a GreenId of a node with kind VariantList.
2956    fn parse_variant_list(&mut self) -> VariantListGreen {
2957        VariantList::new_green(
2958            self.db,
2959            &self
2960                .parse_separated_list::<Variant, TerminalComma, VariantListElementOrSeparatorGreen>(
2961                    Self::try_parse_variant,
2962                    is_of_kind!(rparen, block, lbrace, rbrace, module_item_kw),
2963                    "variant",
2964                ),
2965        )
2966    }
2967
2968    /// Returns a GreenId of a node with kind Variant or TryParseFailure if an enum variant can't be
2969    /// parsed.
2970    fn try_parse_variant(&mut self) -> TryParseResult<VariantGreen> {
2971        let attributes = self.try_parse_attribute_list("Enum variant");
2972        let (name, attributes) = match attributes {
2973            Ok(attributes) => (self.parse_identifier(), attributes),
2974            Err(_) => (self.try_parse_identifier()?, AttributeList::new_green(self.db, &[])),
2975        };
2976
2977        let type_clause = self.parse_option_type_clause();
2978        Ok(Variant::new_green(self.db, attributes, name, type_clause))
2979    }
2980
2981    /// Expected pattern: `<PathSegment>(::<PathSegment>)*`
2982    /// Returns a GreenId of a node with kind ExprPath.
2983    fn parse_path(&mut self) -> ExprPathGreen {
2984        let dollar = match self.peek().kind {
2985            SyntaxKind::TerminalDollar => self.take::<TerminalDollar>().into(),
2986            _ => OptionTerminalDollarEmpty::new_green(self.db).into(),
2987        };
2988
2989        let mut children: Vec<ExprPathInnerElementOrSeparatorGreen> = vec![];
2990        loop {
2991            let (segment, optional_separator) = self.parse_path_segment();
2992            children.push(segment.into());
2993
2994            if let Some(separator) = optional_separator {
2995                children.push(separator.into());
2996                continue;
2997            }
2998            break;
2999        }
3000
3001        ExprPath::new_green(self.db, dollar, ExprPathInner::new_green(self.db, &children))
3002    }
3003    /// Returns a GreenId of a node with kind ExprPath or TryParseFailure if a path can't be parsed.
3004    fn try_parse_path(&mut self) -> TryParseResult<ExprPathGreen> {
3005        if self.is_peek_identifier_like() {
3006            Ok(self.parse_path())
3007        } else {
3008            Err(TryParseFailure::SkipToken)
3009        }
3010    }
3011
3012    /// Expected pattern: `(<PathSegment>::)*<PathSegment>(::){0,1}<GenericArgs>`.
3013    ///
3014    /// Returns a GreenId of a node with kind ExprPath.
3015    fn parse_type_path(&mut self) -> ExprPathGreen {
3016        let dollar = match self.peek().kind {
3017            SyntaxKind::TerminalDollar => self.take::<TerminalDollar>().into(),
3018            _ => OptionTerminalDollarEmpty::new_green(self.db).into(),
3019        };
3020
3021        let mut children: Vec<ExprPathInnerElementOrSeparatorGreen> = vec![];
3022        loop {
3023            let (segment, optional_separator) = self.parse_type_path_segment();
3024            children.push(segment.into());
3025
3026            if let Some(separator) = optional_separator {
3027                children.push(separator.into());
3028                continue;
3029            }
3030            break;
3031        }
3032
3033        ExprPath::new_green(self.db, dollar, ExprPathInner::new_green(self.db, &children))
3034    }
3035
3036    /// Returns a PathSegment and an optional separator.
3037    fn parse_path_segment(&mut self) -> (PathSegmentGreen, Option<TerminalColonColonGreen>) {
3038        let identifier = match self.try_parse_identifier() {
3039            Ok(identifier) => identifier,
3040            Err(_) => {
3041                return (
3042                    self.create_and_report_missing::<PathSegment>(
3043                        ParserDiagnosticKind::MissingPathSegment,
3044                    ),
3045                    // TODO(ilya, 10/10/2022): Should we continue parsing the path here?
3046                    None,
3047                );
3048            }
3049        };
3050        match self.try_parse_token::<TerminalColonColon>() {
3051            Ok(separator) if self.peek().kind == SyntaxKind::TerminalLT => (
3052                PathSegmentWithGenericArgs::new_green(
3053                    self.db,
3054                    identifier,
3055                    separator.into(),
3056                    self.expect_generic_args(),
3057                )
3058                .into(),
3059                self.try_parse_token::<TerminalColonColon>().ok(),
3060            ),
3061            optional_separator => {
3062                (PathSegmentSimple::new_green(self.db, identifier).into(), optional_separator.ok())
3063            }
3064        }
3065    }
3066
3067    /// Returns a Typed PathSegment or a normal PathSegment.
3068    /// Additionally returns an optional separators.
3069    fn parse_type_path_segment(&mut self) -> (PathSegmentGreen, Option<TerminalColonColonGreen>) {
3070        let identifier = match self.try_parse_identifier() {
3071            Ok(identifier) => identifier,
3072            Err(_) => {
3073                return (
3074                    self.create_and_report_missing::<PathSegment>(
3075                        ParserDiagnosticKind::MissingPathSegment,
3076                    ),
3077                    // TODO(ilya, 10/10/2022): Should we continue parsing the path here?
3078                    None,
3079                );
3080            }
3081        };
3082        match self.try_parse_token::<TerminalColonColon>() {
3083            Err(_) if self.peek().kind == SyntaxKind::TerminalLT => (
3084                PathSegmentWithGenericArgs::new_green(
3085                    self.db,
3086                    identifier,
3087                    OptionTerminalColonColonEmpty::new_green(self.db).into(),
3088                    self.expect_generic_args(),
3089                )
3090                .into(),
3091                None,
3092            ),
3093            // This is here to preserve backwards compatibility.
3094            // This allows Option::<T> to still work after this change.
3095            Ok(separator) if self.peek().kind == SyntaxKind::TerminalLT => (
3096                PathSegmentWithGenericArgs::new_green(
3097                    self.db,
3098                    identifier,
3099                    separator.into(),
3100                    self.expect_generic_args(),
3101                )
3102                .into(),
3103                self.try_parse_token::<TerminalColonColon>().ok(),
3104            ),
3105            optional_separator => {
3106                (PathSegmentSimple::new_green(self.db, identifier).into(), optional_separator.ok())
3107            }
3108        }
3109    }
3110
3111    /// Takes and validates a TerminalLiteralNumber token.
3112    fn take_terminal_literal_number(&mut self) -> TerminalLiteralNumberGreen {
3113        let diag = validate_literal_number(&self.peek().text);
3114        let green = self.take::<TerminalLiteralNumber>();
3115        self.add_optional_diagnostic(diag);
3116        green
3117    }
3118
3119    /// Takes and validates a TerminalShortString token.
3120    fn take_terminal_short_string(&mut self) -> TerminalShortStringGreen {
3121        let diag = validate_short_string(&self.peek().text);
3122        let green = self.take::<TerminalShortString>();
3123        self.add_optional_diagnostic(diag);
3124        green
3125    }
3126
3127    /// Takes and validates a TerminalString token.
3128    fn take_terminal_string(&mut self) -> TerminalStringGreen {
3129        let diag = validate_string(&self.peek().text);
3130        let green = self.take::<TerminalString>();
3131        self.add_optional_diagnostic(diag);
3132        green
3133    }
3134
3135    /// Adds a diagnostic of kind `kind` if provided, at the current offset.
3136    fn add_optional_diagnostic(&mut self, err: Option<ValidationError>) {
3137        if let Some(err) = err {
3138            let span_end = self.offset.add_width(self.current_width);
3139            let span = match err.location {
3140                ValidationLocation::Full => TextSpan { start: self.offset, end: span_end },
3141                ValidationLocation::After => TextSpan { start: span_end, end: span_end },
3142            };
3143            self.add_diagnostic(err.kind, span);
3144        }
3145    }
3146
3147    /// Returns a GreenId of a node with an
3148    /// ExprLiteral|ExprPath|ExprParenthesized|ExprTuple|ExprUnderscore kind, or TryParseFailure if
3149    /// such an expression can't be parsed.
3150    fn try_parse_generic_arg(&mut self) -> TryParseResult<GenericArgGreen> {
3151        let expr = match self.peek().kind {
3152            SyntaxKind::TerminalUnderscore => {
3153                let underscore = self.take::<TerminalUnderscore>().into();
3154                return Ok(GenericArgUnnamed::new_green(self.db, underscore).into());
3155            }
3156            SyntaxKind::TerminalLiteralNumber => self.take_terminal_literal_number().into(),
3157            SyntaxKind::TerminalMinus => {
3158                let op = self.take::<TerminalMinus>().into();
3159                let expr = self.parse_token::<TerminalLiteralNumber>().into();
3160                ExprUnary::new_green(self.db, op, expr).into()
3161            }
3162            SyntaxKind::TerminalShortString => self.take_terminal_short_string().into(),
3163            SyntaxKind::TerminalTrue => self.take::<TerminalTrue>().into(),
3164            SyntaxKind::TerminalFalse => self.take::<TerminalFalse>().into(),
3165            SyntaxKind::TerminalLBrace => self.parse_block().into(),
3166            _ => self.try_parse_type_expr()?,
3167        };
3168
3169        // If the next token is `:` and the expression is an identifier, this is the argument's
3170        // name.
3171        if self.peek().kind == SyntaxKind::TerminalColon {
3172            if let Some(argname) = self.try_extract_identifier(expr) {
3173                let colon = self.take::<TerminalColon>();
3174                let expr = if self.peek().kind == SyntaxKind::TerminalUnderscore {
3175                    self.take::<TerminalUnderscore>().into()
3176                } else {
3177                    let expr = self.parse_type_expr();
3178                    GenericArgValueExpr::new_green(self.db, expr).into()
3179                };
3180                return Ok(GenericArgNamed::new_green(self.db, argname, colon, expr).into());
3181            }
3182        }
3183        Ok(GenericArgUnnamed::new_green(
3184            self.db,
3185            GenericArgValueExpr::new_green(self.db, expr).into(),
3186        )
3187        .into())
3188    }
3189
3190    /// Assumes the current token is LT.
3191    /// Expected pattern: `\< <GenericArgList> \>`
3192    fn expect_generic_args(&mut self) -> GenericArgsGreen {
3193        let langle = self.take::<TerminalLT>();
3194        let generic_args = GenericArgList::new_green(
3195            self.db,
3196            &self.parse_separated_list::<GenericArg, TerminalComma, GenericArgListElementOrSeparatorGreen>(
3197                Self::try_parse_generic_arg,
3198                is_of_kind!(rangle, rparen, block, lbrace, rbrace, module_item_kw),
3199                "generic arg",
3200            ),
3201        );
3202        let rangle = self.parse_token::<TerminalGT>();
3203        GenericArgs::new_green(self.db, langle, generic_args, rangle)
3204    }
3205
3206    /// Assumes the current token is LT.
3207    /// Expected pattern: `\< <GenericParamList> \>`
3208    fn expect_generic_params(&mut self) -> WrappedGenericParamListGreen {
3209        let langle = self.take::<TerminalLT>();
3210        let generic_params = GenericParamList::new_green(
3211            self.db,
3212            &self.parse_separated_list::<GenericParam, TerminalComma, GenericParamListElementOrSeparatorGreen>(
3213                Self::try_parse_generic_param,
3214                is_of_kind!(rangle, rparen, block, lbrace, rbrace, module_item_kw),
3215                "generic param",
3216            ),
3217        );
3218        let rangle = self.parse_token::<TerminalGT>();
3219        WrappedGenericParamList::new_green(self.db, langle, generic_params, rangle)
3220    }
3221
3222    fn parse_optional_generic_params(&mut self) -> OptionWrappedGenericParamListGreen {
3223        if self.peek().kind != SyntaxKind::TerminalLT {
3224            return OptionWrappedGenericParamListEmpty::new_green(self.db).into();
3225        }
3226        self.expect_generic_params().into()
3227    }
3228
3229    fn try_parse_generic_param(&mut self) -> TryParseResult<GenericParamGreen> {
3230        match self.peek().kind {
3231            SyntaxKind::TerminalConst => {
3232                let const_kw = self.take::<TerminalConst>();
3233                let name = self.parse_identifier();
3234                let colon = self.parse_token::<TerminalColon>();
3235                let ty = self.parse_type_expr();
3236                Ok(GenericParamConst::new_green(self.db, const_kw, name, colon, ty).into())
3237            }
3238            SyntaxKind::TerminalImpl => {
3239                let impl_kw = self.take::<TerminalImpl>();
3240                let name = self.parse_identifier();
3241                let colon = self.parse_token::<TerminalColon>();
3242                let trait_path = self.parse_type_path();
3243                let associated_item_constraints = self.parse_optional_associated_item_constraints();
3244                Ok(GenericParamImplNamed::new_green(
3245                    self.db,
3246                    impl_kw,
3247                    name,
3248                    colon,
3249                    trait_path,
3250                    associated_item_constraints,
3251                )
3252                .into())
3253            }
3254            SyntaxKind::TerminalPlus => {
3255                let plus = self.take::<TerminalPlus>();
3256                let trait_path = self.parse_type_path();
3257                let associated_item_constraints = self.parse_optional_associated_item_constraints();
3258                Ok(GenericParamImplAnonymous::new_green(
3259                    self.db,
3260                    plus,
3261                    trait_path,
3262                    associated_item_constraints,
3263                )
3264                .into())
3265            }
3266            SyntaxKind::TerminalMinus => {
3267                let minus = self.take::<TerminalMinus>();
3268                let trait_path = self.parse_type_path();
3269                Ok(GenericParamNegativeImpl::new_green(self.db, minus, trait_path).into())
3270            }
3271            _ => Ok(GenericParamType::new_green(self.db, self.try_parse_identifier()?).into()),
3272        }
3273    }
3274
3275    /// Assumes the current token is LBrack.
3276    /// Expected pattern: `[ <associated_item_constraints_list> ]>`
3277    fn expect_associated_item_constraints(&mut self) -> AssociatedItemConstraintsGreen {
3278        let lbrack = self.take::<TerminalLBrack>();
3279        let associated_item_constraints_list = AssociatedItemConstraintList::new_green(
3280            self.db,
3281            &self.parse_separated_list::<AssociatedItemConstraint, TerminalComma, AssociatedItemConstraintListElementOrSeparatorGreen>(
3282                Self::try_parse_associated_item_constraint,
3283                is_of_kind!(rbrack,rangle, rparen, block, lbrace, rbrace, module_item_kw),
3284                "associated type argument",
3285            ),
3286        );
3287        let rangle = self.parse_token::<TerminalRBrack>();
3288        AssociatedItemConstraints::new_green(
3289            self.db,
3290            lbrack,
3291            associated_item_constraints_list,
3292            rangle,
3293        )
3294    }
3295
3296    fn parse_optional_associated_item_constraints(
3297        &mut self,
3298    ) -> OptionAssociatedItemConstraintsGreen {
3299        if self.peek().kind != SyntaxKind::TerminalLBrack {
3300            return OptionAssociatedItemConstraintsEmpty::new_green(self.db).into();
3301        }
3302        self.expect_associated_item_constraints().into()
3303    }
3304
3305    /// Returns a GreenId of a node with kind AssociatedTypeArg or TryParseFailure if an associated
3306    /// type argument can't be parsed.
3307    fn try_parse_associated_item_constraint(
3308        &mut self,
3309    ) -> TryParseResult<AssociatedItemConstraintGreen> {
3310        let ident = self.try_parse_identifier()?;
3311        let colon = self.parse_token::<TerminalColon>();
3312        let ty = self.parse_type_expr();
3313        Ok(AssociatedItemConstraint::new_green(self.db, ident, colon, ty))
3314    }
3315
3316    // ------------------------------- Helpers -------------------------------
3317
3318    /// Parses a list of elements (without separators), where the elements are parsed using
3319    /// `try_parse_list_element`.
3320    /// Returns the list of green ids of the elements.
3321    ///
3322    /// `should_stop` is a predicate to decide how to proceed in case an element can't be parsed,
3323    /// according to the current token. If it returns true, the parsing of the list stops. If it
3324    /// returns false, the current token is skipped and we try to parse an element again.
3325    ///
3326    /// `expected_element` is a description of the expected element.
3327    fn parse_list<ElementGreen>(
3328        &mut self,
3329        try_parse_list_element: fn(&mut Self) -> TryParseResult<ElementGreen>,
3330        should_stop: fn(SyntaxKind) -> bool,
3331        expected_element: &str,
3332    ) -> Vec<ElementGreen> {
3333        let mut children: Vec<ElementGreen> = Vec::new();
3334        loop {
3335            let parse_result = try_parse_list_element(self);
3336            match parse_result {
3337                Ok(element_green) => {
3338                    children.push(element_green);
3339                }
3340                Err(err) => {
3341                    if should_stop(self.peek().kind) {
3342                        break;
3343                    }
3344                    if err == TryParseFailure::SkipToken {
3345                        self.skip_token(ParserDiagnosticKind::SkippedElement {
3346                            element_name: expected_element.into(),
3347                        });
3348                    }
3349                }
3350            }
3351        }
3352        children
3353    }
3354
3355    /// Parses a list of elements (without separators) that can be prefixed with attributes
3356    /// (#[...]), where the elements are parsed using `try_parse_list_element`.
3357    /// Returns the list of green ids of the elements.
3358    ///
3359    /// `should_stop` is a predicate to decide how to proceed in case an element can't be parsed,
3360    /// according to the current token. If it returns true, the parsing of the list stops. If it
3361    /// returns false, the current token is skipped and we try to parse an element again.
3362    ///
3363    /// `expected_element` is a description of the expected element. Note: it should not include
3364    /// "attribute".
3365    fn parse_attributed_list<ElementGreen>(
3366        &mut self,
3367        try_parse_list_element: fn(&mut Self) -> TryParseResult<ElementGreen>,
3368        should_stop: fn(SyntaxKind) -> bool,
3369        expected_element: &str,
3370    ) -> Vec<ElementGreen> {
3371        self.parse_list::<ElementGreen>(
3372            try_parse_list_element,
3373            should_stop,
3374            &or_an_attribute!(expected_element),
3375        )
3376    }
3377
3378    /// Parses a list of elements with `separator`s, where the elements are parsed using
3379    /// `try_parse_list_element`. Depending on the value of
3380    /// `forbid_trailing_separator` the separator may or may not appear in
3381    /// the end of the list. Returns the list of elements and separators. This list contains
3382    /// alternating children: [element, separator, element, separator, ...]. Separators may be
3383    /// missing. The length of the list is either 2 * #elements - 1 or 2 * #elements (a
3384    /// separator for each element or for each element but the last one).
3385    ///
3386    /// `should_stop` is a predicate to decide how to proceed in case an element or a separator
3387    /// can't be parsed, according to the current token.
3388    /// When parsing an element:
3389    /// If it returns true, the parsing of the list stops. If it returns false, the current token
3390    /// is skipped and we try to parse an element again.
3391    /// When parsing a separator:
3392    /// If it returns true, the parsing of the list stops. If it returns false, a missing separator
3393    /// is added and we continue to try to parse another element (with the same token).
3394    fn parse_separated_list_inner<
3395        Element: TypedSyntaxNode,
3396        Separator: syntax::node::Terminal,
3397        ElementOrSeparatorGreen,
3398    >(
3399        &mut self,
3400        try_parse_list_element: fn(&mut Self) -> TryParseResult<Element::Green>,
3401        should_stop: fn(SyntaxKind) -> bool,
3402        expected_element: &'static str,
3403        forbid_trailing_separator: Option<ParserDiagnosticKind>,
3404    ) -> Vec<ElementOrSeparatorGreen>
3405    where
3406        ElementOrSeparatorGreen: From<Separator::Green> + From<Element::Green>,
3407    {
3408        let mut children: Vec<ElementOrSeparatorGreen> = Vec::new();
3409        loop {
3410            match try_parse_list_element(self) {
3411                Err(_) if should_stop(self.peek().kind) => {
3412                    if let (Some(diagnostic_kind), true) =
3413                        (forbid_trailing_separator, !children.is_empty())
3414                    {
3415                        self.add_diagnostic(
3416                            diagnostic_kind,
3417                            TextSpan { start: self.offset, end: self.offset },
3418                        );
3419                    }
3420                    break;
3421                }
3422                Err(_) => {
3423                    self.skip_token(ParserDiagnosticKind::SkippedElement {
3424                        element_name: expected_element.into(),
3425                    });
3426                    continue;
3427                }
3428                Ok(element) => {
3429                    children.push(element.into());
3430                }
3431            };
3432
3433            let separator = match self.try_parse_token::<Separator>() {
3434                Err(_) if should_stop(self.peek().kind) => {
3435                    break;
3436                }
3437                Err(_) => self.create_and_report_missing::<Separator>(
3438                    ParserDiagnosticKind::MissingToken(Separator::KIND),
3439                ),
3440                Ok(separator) => separator,
3441            };
3442            children.push(separator.into());
3443        }
3444        children
3445    }
3446    /// Calls parse_separated_list_inner with trailing separator enabled.
3447    fn parse_separated_list<
3448        Element: TypedSyntaxNode,
3449        Separator: syntax::node::Terminal,
3450        ElementOrSeparatorGreen,
3451    >(
3452        &mut self,
3453        try_parse_list_element: fn(&mut Self) -> TryParseResult<Element::Green>,
3454        should_stop: fn(SyntaxKind) -> bool,
3455        expected_element: &'static str,
3456    ) -> Vec<ElementOrSeparatorGreen>
3457    where
3458        ElementOrSeparatorGreen: From<Separator::Green> + From<Element::Green>,
3459    {
3460        self.parse_separated_list_inner::<Element, Separator, ElementOrSeparatorGreen>(
3461            try_parse_list_element,
3462            should_stop,
3463            expected_element,
3464            None,
3465        )
3466    }
3467
3468    /// Peeks at the next terminal from the Lexer without taking it.
3469    pub fn peek(&self) -> &LexerTerminal {
3470        &self.next_terminal
3471    }
3472
3473    /// Peeks at the token following the next one.
3474    /// Assumption: the next token is not EOF.
3475    pub fn peek_next_next_kind(&mut self) -> SyntaxKind {
3476        self.next_next_terminal.get_or_insert_with(|| self.lexer.next().unwrap()).kind
3477    }
3478
3479    /// Takes a terminal from the Lexer and places it in self.next_terminal.
3480    fn take_raw(&mut self) -> LexerTerminal {
3481        self.offset = self.offset.add_width(self.current_width);
3482        self.current_width = self.next_terminal.width(self.db);
3483        self.last_trivia_length = trivia_total_width(self.db, &self.next_terminal.trailing_trivia);
3484
3485        let next_terminal =
3486            self.next_next_terminal.take().unwrap_or_else(|| self.lexer.next().unwrap());
3487        std::mem::replace(&mut self.next_terminal, next_terminal)
3488    }
3489
3490    /// Skips the next, non-taken, token. A skipped token is a token which is not expected where it
3491    /// is found. Skipping this token means reporting an error, appending the token to the
3492    /// current trivia as skipped, and continuing the compilation as if it wasn't there.
3493    fn skip_token(&mut self, diagnostic_kind: ParserDiagnosticKind) {
3494        if self.peek().kind == SyntaxKind::TerminalEndOfFile {
3495            self.add_diagnostic(diagnostic_kind, TextSpan { start: self.offset, end: self.offset });
3496            return;
3497        }
3498        let terminal = self.take_raw();
3499        self.append_skipped_token_to_pending_trivia(terminal, diagnostic_kind);
3500    }
3501
3502    /// Appends the given terminal to the pending trivia and reports a diagnostic. Used for skipping
3503    /// a taken ('take_raw') token.
3504    fn append_skipped_token_to_pending_trivia(
3505        &mut self,
3506        terminal: LexerTerminal,
3507        diagnostic_kind: ParserDiagnosticKind,
3508    ) {
3509        let orig_offset = self.offset;
3510        let diag_start =
3511            self.offset.add_width(trivia_total_width(self.db, &terminal.leading_trivia));
3512        let diag_end = diag_start.add_width(TextWidth::from_str(&terminal.text));
3513
3514        // Add to pending trivia.
3515        self.pending_trivia.extend(terminal.leading_trivia);
3516        self.pending_trivia.push(TokenSkipped::new_green(self.db, terminal.text).into());
3517        let trailing_trivia_width = trivia_total_width(self.db, &terminal.trailing_trivia);
3518        self.pending_trivia.extend(terminal.trailing_trivia);
3519        self.pending_skipped_token_diagnostics.push(PendingParserDiagnostic {
3520            kind: diagnostic_kind,
3521            span: TextSpan { start: diag_start, end: diag_end },
3522            leading_trivia_start: orig_offset,
3523            trailing_trivia_end: diag_end.add_width(trailing_trivia_width),
3524        });
3525    }
3526
3527    /// A wrapper for `skip_taken_node_with_offset` to report the skipped node diagnostic relative
3528    /// to the current offset. Use this when the skipped node is the last node taken.
3529    fn skip_taken_node_from_current_offset(
3530        &mut self,
3531        node_to_skip: impl Into<SkippedNodeGreen>,
3532        diagnostic_kind: ParserDiagnosticKind,
3533    ) {
3534        self.skip_taken_node_with_offset(
3535            node_to_skip,
3536            diagnostic_kind,
3537            self.offset.add_width(self.current_width),
3538        )
3539    }
3540
3541    /// Skips the given node which is a variant of `SkippedNode` and is already taken. A skipped
3542    /// node is a node which is not expected where it is found. Skipping this node means
3543    /// reporting the given error (pointing to right after the node), appending the node to the
3544    /// current trivia as skipped, and continuing the compilation as if it wasn't there.
3545    /// `end_of_node_offset` is the offset of the end of the skipped node.
3546    fn skip_taken_node_with_offset(
3547        &mut self,
3548        node_to_skip: impl Into<SkippedNodeGreen>,
3549        diagnostic_kind: ParserDiagnosticKind,
3550        end_of_node_offset: TextOffset,
3551    ) {
3552        let trivium_green = TriviumSkippedNode::new_green(self.db, node_to_skip.into()).into();
3553
3554        // Add to pending trivia.
3555        self.pending_trivia.push(trivium_green);
3556
3557        let start_of_node_offset = end_of_node_offset.sub_width(trivium_green.0.width(self.db));
3558        let diag_pos = end_of_node_offset
3559            .sub_width(trailing_trivia_width(self.db, trivium_green.0).unwrap_or_default());
3560
3561        self.pending_skipped_token_diagnostics.push(PendingParserDiagnostic {
3562            kind: diagnostic_kind,
3563            span: TextSpan { start: diag_pos, end: diag_pos },
3564            leading_trivia_start: start_of_node_offset,
3565            trailing_trivia_end: end_of_node_offset,
3566        });
3567    }
3568
3569    /// Skips the current token, reports the given diagnostic and returns missing kind of the
3570    /// expected terminal.
3571    fn skip_token_and_return_missing<ExpectedTerminal: syntax::node::Terminal>(
3572        &mut self,
3573        diagnostic: ParserDiagnosticKind,
3574    ) -> ExpectedTerminal::Green {
3575        self.skip_token(diagnostic);
3576        ExpectedTerminal::missing(self.db)
3577    }
3578
3579    /// Skips a given SkippedNode, reports the given diagnostic (pointing to right after the node)
3580    /// and returns missing kind of the expected node.
3581    fn skip_taken_node_and_return_missing<ExpectedNode: TypedSyntaxNode>(
3582        &mut self,
3583        node_to_skip: impl Into<SkippedNodeGreen>,
3584        diagnostic_kind: ParserDiagnosticKind,
3585    ) -> ExpectedNode::Green {
3586        self.skip_taken_node_from_current_offset(node_to_skip, diagnostic_kind);
3587        ExpectedNode::missing(self.db)
3588    }
3589
3590    /// Skips terminals until `should_stop` returns `true`.
3591    ///
3592    /// Returns the span of the skipped terminals, if any.
3593    pub(crate) fn skip_until(
3594        &mut self,
3595        should_stop: fn(SyntaxKind) -> bool,
3596    ) -> Result<(), SkippedError> {
3597        let mut diag_start = None;
3598        let mut diag_end = None;
3599        while !should_stop(self.peek().kind) {
3600            let terminal = self.take_raw();
3601            diag_start.get_or_insert(self.offset);
3602            diag_end = Some(self.offset.add_width(TextWidth::from_str(&terminal.text)));
3603
3604            self.pending_trivia.extend(terminal.leading_trivia);
3605            self.pending_trivia.push(TokenSkipped::new_green(self.db, terminal.text).into());
3606            self.pending_trivia.extend(terminal.trailing_trivia);
3607        }
3608        if let (Some(diag_start), Some(diag_end)) = (diag_start, diag_end) {
3609            Err(SkippedError(TextSpan { start: diag_start, end: diag_end }))
3610        } else {
3611            Ok(())
3612        }
3613    }
3614
3615    /// Builds a new terminal to replace the given terminal by gluing the recently skipped terminals
3616    /// to the given terminal as extra leading trivia.
3617    fn add_trivia_to_terminal<Terminal: syntax::node::Terminal>(
3618        &mut self,
3619        lexer_terminal: LexerTerminal,
3620    ) -> Terminal::Green {
3621        let LexerTerminal { text, kind: _, leading_trivia, trailing_trivia } = lexer_terminal;
3622        let token = Terminal::TokenType::new_green(self.db, text);
3623        let mut new_leading_trivia = mem::take(&mut self.pending_trivia);
3624
3625        self.consume_pending_skipped_diagnostics();
3626
3627        new_leading_trivia.extend(leading_trivia);
3628        Terminal::new_green(
3629            self.db,
3630            Trivia::new_green(self.db, &new_leading_trivia),
3631            token,
3632            Trivia::new_green(self.db, &trailing_trivia),
3633        )
3634    }
3635
3636    /// Adds the pending skipped-tokens diagnostics, merging consecutive similar ones, and reset
3637    /// self.pending_skipped_token_diagnostics.
3638    fn consume_pending_skipped_diagnostics(&mut self) {
3639        let mut pending_skipped = self.pending_skipped_token_diagnostics.drain(..);
3640        let Some(first) = pending_skipped.next() else {
3641            return;
3642        };
3643
3644        let mut current_diag = first;
3645
3646        for diag in pending_skipped {
3647            if diag.kind == current_diag.kind
3648                && current_diag.trailing_trivia_end == diag.leading_trivia_start
3649            {
3650                // Aggregate this diagnostic with the previous ones.
3651                current_diag = PendingParserDiagnostic {
3652                    span: TextSpan { start: current_diag.span.start, end: diag.span.end },
3653                    kind: diag.kind,
3654                    leading_trivia_start: current_diag.leading_trivia_start,
3655                    trailing_trivia_end: diag.trailing_trivia_end,
3656                };
3657            } else {
3658                // Produce a diagnostic from the aggregated ones, and start aggregating a new
3659                // diagnostic.
3660                self.diagnostics.add(ParserDiagnostic {
3661                    file_id: self.file_id,
3662                    span: current_diag.span,
3663                    kind: current_diag.kind,
3664                });
3665                current_diag = diag;
3666            }
3667        }
3668        // Produce a diagnostic from the aggregated ones at the end.
3669        self.add_diagnostic(current_diag.kind, current_diag.span);
3670    }
3671
3672    /// Takes a token from the Lexer and place it in self.current. If tokens were skipped, glue them
3673    /// to this token as leading trivia.
3674    pub fn take<Terminal: syntax::node::Terminal>(&mut self) -> Terminal::Green {
3675        let token = self.take_raw();
3676        assert_eq!(token.kind, Terminal::KIND);
3677        self.add_trivia_to_terminal::<Terminal>(token)
3678    }
3679
3680    /// If the current leading trivia start with non-doc comments, creates a new `ItemHeaderDoc` and
3681    /// appends the trivia to it. The purpose of this item is to prevent non-doc comments moving
3682    /// from the top of the file formatter.
3683    fn take_doc(&mut self) -> Option<ItemHeaderDocGreen> {
3684        // Take all the trivia from `self.next_terminal`, until a doc-comment is found. If the
3685        // result does not contain a non-doc comment (i.e. regular comment or inner
3686        // comment), return None and do not change the next terminal leading trivia.
3687        let mut has_header_doc = false;
3688        let mut split_index = 0;
3689        for trivium in &self.next_terminal.leading_trivia {
3690            match trivium.0.lookup_intern(self.db).kind {
3691                SyntaxKind::TokenSingleLineComment | SyntaxKind::TokenSingleLineInnerComment => {
3692                    has_header_doc = true;
3693                }
3694                SyntaxKind::TokenSingleLineDocComment => {
3695                    break;
3696                }
3697                _ => {}
3698            }
3699            split_index += 1;
3700        }
3701        if !has_header_doc {
3702            return None;
3703        }
3704        // Split the trivia into header doc and the rest.
3705        let leading_trivia = self.next_terminal.leading_trivia.split_off(split_index);
3706        let header_doc = std::mem::replace(&mut self.next_terminal.leading_trivia, leading_trivia);
3707        let empty_lexer_terminal = LexerTerminal {
3708            text: "".into(),
3709            kind: SyntaxKind::TerminalEmpty,
3710            leading_trivia: header_doc,
3711            trailing_trivia: vec![],
3712        };
3713        self.offset = self.offset.add_width(empty_lexer_terminal.width(self.db));
3714
3715        let empty_terminal = self.add_trivia_to_terminal::<TerminalEmpty>(empty_lexer_terminal);
3716        Some(ItemHeaderDoc::new_green(self.db, empty_terminal))
3717    }
3718
3719    /// If the current terminal is of kind `Terminal`, returns its Green wrapper. Otherwise, returns
3720    /// TryParseFailure.
3721    /// Note that this function should not be called for 'TerminalIdentifier' -
3722    /// try_parse_identifier() should be used instead.
3723    fn try_parse_token<Terminal: syntax::node::Terminal>(
3724        &mut self,
3725    ) -> TryParseResult<Terminal::Green> {
3726        if Terminal::KIND == self.peek().kind {
3727            Ok(self.take::<Terminal>())
3728        } else {
3729            Err(TryParseFailure::SkipToken)
3730        }
3731    }
3732
3733    /// If the current token is of kind `token_kind`, returns a GreenId of a node with this kind.
3734    /// Otherwise, returns Token::Missing.
3735    ///
3736    /// Note that this function should not be called for 'TerminalIdentifier' - parse_identifier()
3737    /// should be used instead.
3738    fn parse_token<Terminal: syntax::node::Terminal>(&mut self) -> Terminal::Green {
3739        self.parse_token_ex::<Terminal>(true)
3740    }
3741
3742    /// Same as [Self::parse_token], except that the diagnostic may be omitted.
3743    fn parse_token_ex<Terminal: syntax::node::Terminal>(
3744        &mut self,
3745        report_diagnostic: bool,
3746    ) -> Terminal::Green {
3747        match self.try_parse_token::<Terminal>() {
3748            Ok(green) => green,
3749            Err(_) => {
3750                if report_diagnostic {
3751                    self.create_and_report_missing_terminal::<Terminal>()
3752                } else {
3753                    Terminal::missing(self.db)
3754                }
3755            }
3756        }
3757    }
3758}
3759
3760/// Controls whether Lbrace (`{`) is allowed in the expression.
3761///
3762/// Lbrace is always allowed in sub-expressions (e.g. in parenthesized expression). For example,
3763/// while `1 + MyStruct { ... }` may not be valid, `1 + (MyStruct { ... })` is always ok.
3764///
3765/// This can be used to parse the argument of a `match` statement,
3766/// so that the `{` that opens the `match` body is not confused with other potential uses of
3767/// `{`.
3768#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3769enum LbraceAllowed {
3770    Forbid,
3771    Allow,
3772}
3773
3774/// Controls the behavior of the parser when encountering `&& let` tokens.
3775#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3776enum AndLetBehavior {
3777    /// Parse without special handling of `&& let`.
3778    Simple,
3779    /// Stop parsing an expression at `&& let` and return the expression so far.
3780    Stop,
3781}
3782
3783/// Indicates that [Parser::skip_until] skipped some terminals.
3784pub(crate) struct SkippedError(pub(crate) TextSpan);
3785
3786/// Defines the parser behavior in the case of a parsing error.
3787struct ErrorRecovery {
3788    /// In the case of a parsing error, tokens will be skipped until `should_stop`
3789    /// returns `true`. For example, one can stop at tokens such as `,` and `}`.
3790    should_stop: fn(SyntaxKind) -> bool,
3791}
3792
3793enum ExternItem {
3794    Function(ItemExternFunctionGreen),
3795    Type(ItemExternTypeGreen),
3796}
3797
3798#[derive(Debug)]
3799enum ImplItemOrAlias {
3800    Item(ItemImplGreen),
3801    Alias(ItemImplAliasGreen),
3802}
3803
3804/// A parser diagnostic that is not yet reported as it is accumulated with similar consecutive
3805/// diagnostics.
3806pub struct PendingParserDiagnostic {
3807    pub span: TextSpan,
3808    pub kind: ParserDiagnosticKind,
3809    pub leading_trivia_start: TextOffset,
3810    pub trailing_trivia_end: TextOffset,
3811}
3812
3813/// Returns the total width of the given trivia list.
3814fn trivia_total_width(db: &dyn SyntaxGroup, trivia: &[TriviumGreen]) -> TextWidth {
3815    trivia.iter().map(|trivium| trivium.0.width(db)).sum::<TextWidth>()
3816}
3817
3818/// The width of the trailing trivia, traversing the tree to the bottom right node.
3819fn trailing_trivia_width(db: &dyn SyntaxGroup, green_id: GreenId) -> Option<TextWidth> {
3820    let node = green_id.lookup_intern(db);
3821    if node.kind == SyntaxKind::Trivia {
3822        return Some(node.width());
3823    }
3824    match &node.details {
3825        GreenNodeDetails::Token(_) => Some(TextWidth::default()),
3826        GreenNodeDetails::Node { children, .. } => {
3827            for child in children.iter().rev() {
3828                if let Some(width) = trailing_trivia_width(db, *child) {
3829                    return Some(width);
3830                }
3831            }
3832            None
3833        }
3834    }
3835}