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