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