Skip to main content

cairo_lang_parser/
parser.rs

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