1use std::mem;
2use std::sync::Arc;
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::deque::Deque;
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::{LexerTerminal, tokenize_all};
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 MacroRule,
39 MacroExpansion,
41 ExpandedMacro,
43 None,
45}
46
47pub struct Parser<'a, 'mt> {
48 db: &'a dyn Database,
49 file_id: FileId<'a>,
50 terminals: Deque<LexerTerminal<'a>>,
52 pending_trivia: Vec<TriviumGreen<'a>>,
54 offset: TextOffset,
56 current_width: TextWidth,
59 last_trivia_length: TextWidth,
61 diagnostics: &'mt mut DiagnosticsBuilder<'a, ParserDiagnostic<'a>>,
62 pending_skipped_token_diagnostics: Vec<PendingParserDiagnostic>,
64 macro_parsing_context: MacroParsingContext,
66}
67
68impl<'a> Parser<'a, '_> {
69 fn next_terminal(&self) -> &LexerTerminal<'a> {
70 &self.terminals[0]
71 }
72
73 fn next_next_terminal(&self) -> &LexerTerminal<'a> {
74 &self.terminals[1]
75 }
76
77 fn advance(&mut self) -> LexerTerminal<'a> {
78 self.terminals.pop_front().unwrap()
79 }
80
81 fn next_terminal_mut(&mut self) -> &mut LexerTerminal<'a> {
82 &mut self.terminals[0]
83 }
84}
85
86#[derive(PartialEq, Debug)]
88pub enum TryParseFailure {
89 SkipToken,
92 DoNothing,
97}
98pub type TryParseResult<GreenElement> = Result<GreenElement, TryParseFailure>;
100
101const MAX_PRECEDENCE: usize = 1000;
130const MODULE_ITEM_DESCRIPTION: &str = "Const/Enum/ExternFunction/ExternType/Function/Impl/\
131 InlineMacro/Module/Struct/Trait/TypeAlias/Use";
132const TRAIT_ITEM_DESCRIPTION: &str = "Const/Function/Impl/Type";
133const IMPL_ITEM_DESCRIPTION: &str = "Const/Function/Impl/Type";
134
135macro_rules! or_an_attribute {
137 ($string:expr) => {
138 format!("{} or an attribute", $string)
139 };
140}
141
142impl<'a, 'mt> Parser<'a, 'mt> {
143 pub fn new(
145 db: &'a dyn Database,
146 file_id: FileId<'a>,
147 text: &'a str,
148 diagnostics: &'mt mut DiagnosticsBuilder<'a, ParserDiagnostic<'a>>,
149 ) -> Self {
150 let tokens: Deque<LexerTerminal<'a>> = tokenize_all(db, (), Arc::from(text));
151 Parser {
152 db,
153 file_id,
154 terminals: tokens,
155 pending_trivia: Vec::new(),
156 offset: Default::default(),
157 current_width: Default::default(),
158 last_trivia_length: Default::default(),
159 diagnostics,
160 pending_skipped_token_diagnostics: Vec::new(),
161 macro_parsing_context: MacroParsingContext::None,
162 }
163 }
164
165 pub fn add_diagnostic(&mut self, kind: ParserDiagnosticKind, span: TextSpan) {
167 self.diagnostics.add(ParserDiagnostic { file_id: self.file_id, kind, span });
168 }
169
170 pub fn parse_file(
172 db: &'a dyn Database,
173 diagnostics: &'mt mut DiagnosticsBuilder<'a, ParserDiagnostic<'a>>,
174 file_id: FileId<'a>,
175 text: &'a str,
176 ) -> SyntaxFile<'a> {
177 let parser = Parser::new(db, file_id, text, diagnostics);
178 let green = parser.parse_syntax_file();
179 SyntaxFile::from_syntax_node(db, SyntaxNode::new_root(db, file_id, green.0))
180 }
181
182 pub fn parse_file_expr(
184 db: &'a dyn Database,
185 diagnostics: &'mt mut DiagnosticsBuilder<'a, ParserDiagnostic<'a>>,
186 file_id: FileId<'a>,
187 text: &'a str,
188 ) -> Expr<'a> {
189 let mut parser = Parser::new(db, file_id, text, diagnostics);
190 parser.macro_parsing_context = MacroParsingContext::ExpandedMacro;
191 let green = parser.parse_expr();
192 if let Err(SkippedError(span)) = parser.skip_until(is_of_kind!()) {
193 parser.add_diagnostic(
194 ParserDiagnosticKind::SkippedElement { element_name: "end of expr".into() },
195 span,
196 );
197 }
198 Expr::from_syntax_node(db, SyntaxNode::new_root(db, file_id, green.0))
199 }
200
201 pub fn parse_file_statement_list(
203 db: &'a dyn Database,
204 diagnostics: &'mt mut DiagnosticsBuilder<'a, ParserDiagnostic<'a>>,
205 file_id: FileId<'a>,
206 text: &'a str,
207 ) -> StatementList<'a> {
208 let mut parser = Parser::new(db, file_id, text, diagnostics);
209 parser.macro_parsing_context = MacroParsingContext::ExpandedMacro;
210 let statements = StatementList::new_green(
211 db,
212 &parser.parse_list(Self::try_parse_statement, Self::is_eof, "statement"),
213 );
214 StatementList::from_syntax_node(db, SyntaxNode::new_root(db, file_id, statements.0))
215 }
216
217 pub fn is_eof(kind: SyntaxKind) -> bool {
219 kind == SyntaxKind::TerminalEndOfFile
220 }
221
222 pub fn parse_token_stream(
224 db: &'a dyn Database,
225 diagnostics: &'mt mut DiagnosticsBuilder<'a, ParserDiagnostic<'a>>,
226 file_id: FileId<'a>,
227 token_stream: &dyn ToPrimitiveTokenStream<Iter = impl Iterator<Item = PrimitiveToken>>,
228 ) -> SyntaxFile<'a> {
229 let (content, offset) = primitive_token_stream_content_and_offset(token_stream);
230 let file_content = db.file_content(file_id).unwrap();
231 let file_content_at_offset = offset.unwrap_or_default().take_from(file_content);
232 assert!(
233 file_content_at_offset.starts_with(&content),
234 "The content of the file at the offset is not the same as the content of the token \
235 stream"
236 );
237 let content = &file_content_at_offset[..content.len()];
238 let parser = Parser::new(db, file_id, content, diagnostics);
239 let green = parser.parse_syntax_file();
240 SyntaxFile::from_syntax_node(
241 db,
242 SyntaxNode::new_root_with_offset(db, file_id, green.0, offset),
243 )
244 }
245
246 pub fn parse_token_stream_expr(
248 db: &'a dyn Database,
249 diagnostics: &'mt mut DiagnosticsBuilder<'a, ParserDiagnostic<'a>>,
250 file_id: FileId<'a>,
251 offset: Option<TextOffset>,
252 ) -> Expr<'a> {
253 let content = db.file_content(file_id).unwrap();
254 let mut parser = Parser::new(db, file_id, content, diagnostics);
255 let green = parser.parse_expr();
256 if let Err(SkippedError(span)) = parser.skip_until(is_of_kind!()) {
257 parser.diagnostics.add(ParserDiagnostic {
258 file_id: parser.file_id,
259 kind: ParserDiagnosticKind::SkippedElement { element_name: "end of expr".into() },
260 span,
261 });
262 }
263 Expr::from_syntax_node(db, SyntaxNode::new_root_with_offset(db, file_id, green.0, offset))
264 }
265
266 fn create_and_report_missing<T: TypedSyntaxNode<'a>>(
268 &mut self,
269 missing_kind: ParserDiagnosticKind,
270 ) -> T::Green {
271 let next_offset = self.offset.add_width(self.current_width - self.last_trivia_length);
272 self.add_diagnostic(missing_kind, TextSpan::cursor(next_offset));
273 T::missing(self.db)
274 }
275
276 fn create_and_report_missing_terminal<Terminal: syntax::node::Terminal<'a>>(
279 &mut self,
280 ) -> Terminal::Green {
281 self.create_and_report_missing::<Terminal>(ParserDiagnosticKind::MissingToken(
282 Terminal::KIND,
283 ))
284 }
285
286 pub fn parse_syntax_file(mut self) -> SyntaxFileGreen<'a> {
287 let mut module_items = vec![];
288 if let Some(doc_item) = self.take_doc() {
289 module_items.push(doc_item.into());
290 }
291 module_items.extend(self.parse_attributed_list(
292 Self::try_parse_module_item,
293 is_of_kind!(),
294 MODULE_ITEM_DESCRIPTION,
295 ));
296 let items = ModuleItemList::new_green(self.db, &module_items);
298 assert_eq!(self.peek().kind, SyntaxKind::TerminalEndOfFile);
300
301 self.offset = self.offset.add_width(self.current_width);
305
306 let eof =
307 self.add_trivia_to_terminal::<TerminalEndOfFile<'_>>(self.next_terminal().clone());
308 SyntaxFile::new_green(self.db, items, eof)
309 }
310
311 pub fn try_parse_module_item(&mut self) -> TryParseResult<ModuleItemGreen<'a>> {
318 let maybe_attributes = self.try_parse_attribute_list(MODULE_ITEM_DESCRIPTION);
319 let (has_attrs, attributes) = match maybe_attributes {
320 Ok(attributes) => (true, attributes),
321 Err(_) => (false, AttributeList::new_green(self.db, &[])),
322 };
323 let post_attributes_offset = self.offset.add_width(self.current_width);
324
325 let visibility_pub = self.try_parse_visibility_pub();
326 let visibility = match visibility_pub {
327 Some(visibility) => visibility.into(),
328 None => VisibilityDefault::new_green(self.db).into(),
329 };
330 let post_visibility_offset = self.offset.add_width(self.current_width);
331
332 match self.peek().kind {
333 SyntaxKind::TerminalConst => {
334 let const_kw = self.take::<TerminalConst<'_>>();
335 Ok(if self.peek().kind == SyntaxKind::TerminalFunction {
336 self.expect_item_function_with_body(attributes, visibility, const_kw.into())
337 .into()
338 } else {
339 self.expect_item_const(attributes, visibility, const_kw).into()
340 })
341 }
342 SyntaxKind::TerminalModule => {
343 Ok(self.expect_item_module(attributes, visibility).into())
344 }
345 SyntaxKind::TerminalStruct => {
346 Ok(self.expect_item_struct(attributes, visibility).into())
347 }
348 SyntaxKind::TerminalEnum => Ok(self.expect_item_enum(attributes, visibility).into()),
349 SyntaxKind::TerminalType => {
350 Ok(self.expect_item_type_alias(attributes, visibility).into())
351 }
352 SyntaxKind::TerminalExtern => Ok(self.expect_item_extern(attributes, visibility)),
353 SyntaxKind::TerminalFunction => Ok(self
354 .expect_item_function_with_body(
355 attributes,
356 visibility,
357 OptionTerminalConstEmpty::new_green(self.db).into(),
358 )
359 .into()),
360 SyntaxKind::TerminalUse => Ok(self.expect_item_use(attributes, visibility).into()),
361 SyntaxKind::TerminalTrait => Ok(self.expect_item_trait(attributes, visibility).into()),
362 SyntaxKind::TerminalImpl => Ok(self.expect_module_item_impl(attributes, visibility)),
363 SyntaxKind::TerminalMacro => {
364 Ok(self.expect_item_macro_declaration(attributes, visibility).into())
365 }
366 SyntaxKind::TerminalIdentifier | SyntaxKind::TerminalDollar => {
367 let path = self.parse_path();
372 let post_path_offset = self.offset.add_width(self.current_width);
373 match self.peek().kind {
374 SyntaxKind::TerminalLParen
375 | SyntaxKind::TerminalLBrace
376 | SyntaxKind::TerminalLBrack => {
377 self.add_diagnostic(
379 ParserDiagnosticKind::ItemInlineMacroWithoutBang {
380 identifier: path.identifier(self.db).long(self.db).to_string(),
381 bracket_type: self.peek().kind,
382 },
383 TextSpan::new(self.offset, self.offset.add_width(self.current_width)),
384 );
385 Ok(self
386 .parse_item_inline_macro_given_bang(
387 attributes,
388 path,
389 TerminalNot::missing(self.db),
390 )
391 .into())
392 }
393 SyntaxKind::TerminalNot => {
394 Ok(self.expect_item_inline_macro(attributes, path).into())
395 }
396 _ => {
397 if has_attrs {
398 self.skip_taken_node_with_offset(
399 attributes,
400 ParserDiagnosticKind::SkippedElement {
401 element_name: or_an_attribute!(MODULE_ITEM_DESCRIPTION),
402 },
403 post_attributes_offset,
404 );
405 }
406 if let Some(visibility_pub) = visibility_pub {
407 self.skip_taken_node_with_offset(
408 visibility_pub,
409 ParserDiagnosticKind::SkippedElement {
410 element_name: or_an_attribute!(MODULE_ITEM_DESCRIPTION),
411 },
412 post_visibility_offset,
413 );
414 }
415 self.skip_taken_node_with_offset(
417 path,
418 ParserDiagnosticKind::SkippedElement {
419 element_name: or_an_attribute!(MODULE_ITEM_DESCRIPTION),
420 },
421 post_path_offset,
422 );
423 Err(TryParseFailure::DoNothing)
425 }
426 }
427 }
428 _ => {
429 let mut result = Err(TryParseFailure::SkipToken);
430 if has_attrs {
431 self.skip_taken_node_with_offset(
432 attributes,
433 ParserDiagnosticKind::AttributesWithoutItem,
434 post_attributes_offset,
435 );
436 result = Ok(ModuleItem::missing(self.db));
437 }
438 if let Some(visibility_pub) = visibility_pub {
439 self.skip_taken_node_with_offset(
440 visibility_pub,
441 ParserDiagnosticKind::VisibilityWithoutItem,
442 post_visibility_offset,
443 );
444 result = Ok(ModuleItem::missing(self.db));
445 }
446 result
447 }
448 }
449 }
450
451 fn expect_item_module(
454 &mut self,
455 attributes: AttributeListGreen<'a>,
456 visibility: VisibilityGreen<'a>,
457 ) -> ItemModuleGreen<'a> {
458 let module_kw = self.take::<TerminalModule<'_>>();
459 let name = self.parse_identifier();
460
461 let body = match self.peek().kind {
462 SyntaxKind::TerminalLBrace => {
463 let lbrace = self.take::<TerminalLBrace<'_>>();
464 let mut module_items = vec![];
465 if let Some(doc_item) = self.take_doc() {
466 module_items.push(doc_item.into());
467 }
468 module_items.extend(self.parse_attributed_list(
469 Self::try_parse_module_item,
470 is_of_kind!(rbrace),
471 MODULE_ITEM_DESCRIPTION,
472 ));
473 let items = ModuleItemList::new_green(self.db, &module_items);
474 let rbrace = self.parse_token::<TerminalRBrace<'_>>();
475 ModuleBody::new_green(self.db, lbrace, items, rbrace).into()
476 }
477 SyntaxKind::TerminalSemicolon => self.take::<TerminalSemicolon<'_>>().into(),
478 _ => self
479 .create_and_report_missing::<TerminalSemicolon<'_>>(
480 ParserDiagnosticKind::ExpectedSemicolonOrBody,
481 )
482 .into(),
483 };
484
485 ItemModule::new_green(self.db, attributes, visibility, module_kw, name, body)
486 }
487
488 fn expect_item_struct(
491 &mut self,
492 attributes: AttributeListGreen<'a>,
493 visibility: VisibilityGreen<'a>,
494 ) -> ItemStructGreen<'a> {
495 let struct_kw = self.take::<TerminalStruct<'_>>();
496 let name = self.parse_identifier();
497 let generic_params = self.parse_optional_generic_params();
498 let lbrace = self.parse_token::<TerminalLBrace<'_>>();
499 let members = self.parse_member_list();
500 let rbrace = self.parse_token::<TerminalRBrace<'_>>();
501 ItemStruct::new_green(
502 self.db,
503 attributes,
504 visibility,
505 struct_kw,
506 name,
507 generic_params,
508 lbrace,
509 members,
510 rbrace,
511 )
512 }
513
514 fn expect_item_enum(
517 &mut self,
518 attributes: AttributeListGreen<'a>,
519 visibility: VisibilityGreen<'a>,
520 ) -> ItemEnumGreen<'a> {
521 let enum_kw = self.take::<TerminalEnum<'_>>();
522 let name = self.parse_identifier();
523 let generic_params = self.parse_optional_generic_params();
524 let lbrace = self.parse_token::<TerminalLBrace<'_>>();
525 let variants = self.parse_variant_list();
526 let rbrace = self.parse_token::<TerminalRBrace<'_>>();
527 ItemEnum::new_green(
528 self.db,
529 attributes,
530 visibility,
531 enum_kw,
532 name,
533 generic_params,
534 lbrace,
535 variants,
536 rbrace,
537 )
538 }
539
540 fn expect_item_type_alias(
543 &mut self,
544 attributes: AttributeListGreen<'a>,
545 visibility: VisibilityGreen<'a>,
546 ) -> ItemTypeAliasGreen<'a> {
547 let type_kw = self.take::<TerminalType<'_>>();
548 let name = self.parse_identifier();
549 let generic_params = self.parse_optional_generic_params();
550 let eq = self.parse_token::<TerminalEq<'_>>();
551 let ty = self.parse_type_expr();
552 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
553 ItemTypeAlias::new_green(
554 self.db,
555 attributes,
556 visibility,
557 type_kw,
558 name,
559 generic_params,
560 eq,
561 ty,
562 semicolon,
563 )
564 }
565
566 fn expect_function_signature(&mut self) -> FunctionSignatureGreen<'a> {
568 let lparen = self.parse_token::<TerminalLParen<'_>>();
569 let params = self.parse_param_list();
570 let rparen = self.parse_token::<TerminalRParen<'_>>();
571 let return_type_clause = self.parse_option_return_type_clause();
572 let implicits_clause = self.parse_option_implicits_clause();
573 let optional_no_panic = if self.peek().kind == SyntaxKind::TerminalNoPanic {
574 self.take::<TerminalNoPanic<'_>>().into()
575 } else {
576 OptionTerminalNoPanicEmpty::new_green(self.db).into()
577 };
578
579 FunctionSignature::new_green(
580 self.db,
581 lparen,
582 params,
583 rparen,
584 return_type_clause,
585 implicits_clause,
586 optional_no_panic,
587 )
588 }
589
590 fn expect_item_const(
593 &mut self,
594 attributes: AttributeListGreen<'a>,
595 visibility: VisibilityGreen<'a>,
596 const_kw: TerminalConstGreen<'a>,
597 ) -> ItemConstantGreen<'a> {
598 let name = self.parse_identifier();
599 let type_clause = self.parse_type_clause(ErrorRecovery {
600 should_stop: is_of_kind!(eq, semicolon, module_item_kw),
601 });
602 let eq = self.parse_token::<TerminalEq<'_>>();
603 let expr = self.parse_expr();
604 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
605
606 ItemConstant::new_green(
607 self.db,
608 attributes,
609 visibility,
610 const_kw,
611 name,
612 type_clause,
613 eq,
614 expr,
615 semicolon,
616 )
617 }
618
619 fn expect_item_extern<T: From<ItemExternFunctionGreen<'a>> + From<ItemExternTypeGreen<'a>>>(
622 &mut self,
623 attributes: AttributeListGreen<'a>,
624 visibility: VisibilityGreen<'a>,
625 ) -> T {
626 match self.expect_item_extern_inner(attributes, visibility) {
627 ExternItem::Function(x) => x.into(),
628 ExternItem::Type(x) => x.into(),
629 }
630 }
631
632 fn expect_item_extern_inner(
635 &mut self,
636 attributes: AttributeListGreen<'a>,
637 visibility: VisibilityGreen<'a>,
638 ) -> ExternItem<'a> {
639 let extern_kw = self.take::<TerminalExtern<'_>>();
640 match self.peek().kind {
641 kind @ (SyntaxKind::TerminalFunction | SyntaxKind::TerminalConst) => {
642 let (optional_const, function_kw) = if kind == SyntaxKind::TerminalConst {
643 (
644 self.take::<TerminalConst<'_>>().into(),
645 self.parse_token::<TerminalFunction<'_>>(),
646 )
647 } else {
648 (
649 OptionTerminalConstEmpty::new_green(self.db).into(),
650 self.take::<TerminalFunction<'_>>(),
651 )
652 };
653 let declaration = self.expect_function_declaration_ex(optional_const, function_kw);
654 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
655 ExternItem::Function(ItemExternFunction::new_green(
656 self.db,
657 attributes,
658 visibility,
659 extern_kw,
660 declaration,
661 semicolon,
662 ))
663 }
664 _ => {
665 let type_kw = self.parse_token::<TerminalType<'_>>();
667
668 let name = self.parse_identifier();
669 let generic_params = self.parse_optional_generic_params();
670 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
671 ExternItem::Type(ItemExternType::new_green(
673 self.db,
674 attributes,
675 visibility,
676 extern_kw,
677 type_kw,
678 name,
679 generic_params,
680 semicolon,
681 ))
682 }
683 }
684 }
685
686 fn expect_item_use(
689 &mut self,
690 attributes: AttributeListGreen<'a>,
691 visibility: VisibilityGreen<'a>,
692 ) -> ItemUseGreen<'a> {
693 let use_kw = self.take::<TerminalUse<'_>>();
694 let dollar = match self.peek().kind {
695 SyntaxKind::TerminalDollar => self.take::<TerminalDollar<'_>>().into(),
696 _ => OptionTerminalDollarEmpty::new_green(self.db).into(),
697 };
698 let use_path = self.parse_use_path();
699 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
700 ItemUse::new_green(self.db, attributes, visibility, use_kw, dollar, use_path, semicolon)
701 }
702
703 fn expect_item_macro_declaration(
706 &mut self,
707 attributes: AttributeListGreen<'a>,
708 visibility: VisibilityGreen<'a>,
709 ) -> ItemMacroDeclarationGreen<'a> {
710 let macro_kw = self.take::<TerminalMacro<'_>>();
711 let name = self.parse_identifier();
712 let lbrace = self.parse_token::<TerminalLBrace<'_>>();
713 let macro_rules = MacroRulesList::new_green(
714 self.db,
715 &self.parse_list(Self::try_parse_macro_rule, is_of_kind!(rbrace), "macro rule"),
716 );
717 let rbrace = self.parse_token::<TerminalRBrace<'_>>();
718 ItemMacroDeclaration::new_green(
719 self.db,
720 attributes,
721 visibility,
722 macro_kw,
723 name,
724 lbrace,
725 macro_rules,
726 rbrace,
727 )
728 }
729
730 fn try_parse_macro_rule(&mut self) -> TryParseResult<MacroRuleGreen<'a>> {
733 let previous_macro_parsing_context =
734 mem::replace(&mut self.macro_parsing_context, MacroParsingContext::MacroRule);
735 let wrapped_macro = match self.peek().kind {
736 SyntaxKind::TerminalLParen => self
737 .wrap_macro::<TerminalLParen<'_>, TerminalRParen<'_>, _, _>(
738 ParenthesizedMacro::new_green,
739 )
740 .into(),
741 SyntaxKind::TerminalLBrace => self
742 .wrap_macro::<TerminalLBrace<'_>, TerminalRBrace<'_>, _, _>(BracedMacro::new_green)
743 .into(),
744 SyntaxKind::TerminalLBrack => self
745 .wrap_macro::<TerminalLBrack<'_>, TerminalRBrack<'_>, _, _>(
746 BracketedMacro::new_green,
747 )
748 .into(),
749 _ => {
750 self.macro_parsing_context = previous_macro_parsing_context;
751 return Err(TryParseFailure::SkipToken);
752 }
753 };
754 let arrow = self.parse_token::<TerminalMatchArrow<'_>>();
755 if let Err(SkippedError(span)) = self.skip_until(is_of_kind!(rbrace, lbrace)) {
756 self.add_diagnostic(
757 ParserDiagnosticKind::SkippedElement { element_name: "'{'".into() },
758 span,
759 );
760 }
761 let macro_body = if self.peek().kind == SyntaxKind::TerminalLBrace {
762 self.macro_parsing_context = MacroParsingContext::MacroExpansion;
763 self.wrap_macro::<TerminalLBrace<'_>, TerminalRBrace<'_>, _, _>(BracedMacro::new_green)
764 } else {
765 BracedMacro::new_green(
766 self.db,
767 self.create_and_report_missing_terminal::<TerminalLBrace<'_>>(),
768 MacroElements::new_green(self.db, &[]),
769 self.create_and_report_missing_terminal::<TerminalRBrace<'_>>(),
770 )
771 };
772 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
773 self.macro_parsing_context = previous_macro_parsing_context;
774 Ok(MacroRule::new_green(self.db, wrapped_macro, arrow, macro_body, semicolon))
775 }
776 fn try_parse_macro_element(&mut self) -> TryParseResult<MacroElementGreen<'a>> {
780 match self.peek().kind {
781 SyntaxKind::TerminalDollar => {
782 let dollar: TerminalDollarGreen<'_> = self.take::<TerminalDollar<'_>>();
783 match self.peek().kind {
784 SyntaxKind::TerminalLParen => {
785 let lparen = self.take::<TerminalLParen<'_>>();
786 let elements = self.expect_wrapped_macro();
787 let rparen = self.parse_token::<TerminalRParen<'_>>();
788 let separator: OptionTerminalCommaGreen<'_> = match self.peek().kind {
789 SyntaxKind::TerminalComma => self.take::<TerminalComma<'_>>().into(),
790 _ => OptionTerminalCommaEmpty::new_green(self.db).into(),
791 };
792 let operator = match self.peek().kind {
793 SyntaxKind::TerminalQuestionMark => {
794 self.take::<TerminalQuestionMark<'_>>().into()
795 }
796 SyntaxKind::TerminalPlus => self.take::<TerminalPlus<'_>>().into(),
797 SyntaxKind::TerminalMul => self.take::<TerminalMul<'_>>().into(),
798 _ => self.create_and_report_missing::<MacroRepetitionOperator<'_>>(
799 ParserDiagnosticKind::MissingMacroRepetitionOperator,
800 ),
801 };
802 Ok(MacroRepetition::new_green(
803 self.db, dollar, lparen, elements, rparen, separator, operator,
804 )
805 .into())
806 }
807 _ => {
808 let ident = self.parse_identifier();
809 let param_kind: OptionParamKindGreen<'_> = if self.peek().kind
810 == SyntaxKind::TerminalColon
811 {
812 let colon = self.parse_token::<TerminalColon<'_>>();
813 let kind = self.parse_macro_rule_param_kind();
814 let result = ParamKind::new_green(self.db, colon, kind).into();
815 if let MacroParsingContext::MacroExpansion = self.macro_parsing_context
816 {
817 self.add_diagnostic(
818 ParserDiagnosticKind::InvalidParamKindInMacroExpansion,
819 TextSpan::new_with_width(self.offset, self.current_width),
820 );
821 }
822 result
823 } else {
824 if let MacroParsingContext::MacroRule = self.macro_parsing_context {
825 self.add_diagnostic(
826 ParserDiagnosticKind::InvalidParamKindInMacroRule,
827 TextSpan::new_with_width(self.offset, self.current_width),
828 );
829 }
830 OptionParamKindEmpty::new_green(self.db).into()
831 };
832 self.macro_parsing_context = MacroParsingContext::None;
833 Ok(MacroParam::new_green(self.db, dollar, ident, param_kind).into())
834 }
835 }
836 }
837 SyntaxKind::TerminalLParen
838 | SyntaxKind::TerminalLBrace
839 | SyntaxKind::TerminalLBrack => {
840 let subtree = self.parse_macro_elements();
841 Ok(MacroWrapper::new_green(self.db, subtree).into())
842 }
843 _ => {
844 let token = self.parse_token_tree_leaf();
845 Ok(token.into())
846 }
847 }
848 }
849
850 fn parse_macro_elements(&mut self) -> WrappedMacroGreen<'a> {
851 match self.peek().kind {
852 SyntaxKind::TerminalLParen => self
853 .wrap_macro::<TerminalLParen<'_>, TerminalRParen<'_>, _, _>(
854 ParenthesizedMacro::new_green,
855 )
856 .into(),
857 SyntaxKind::TerminalLBrace => self
858 .wrap_macro::<TerminalLBrace<'_>, TerminalRBrace<'_>, _, _>(BracedMacro::new_green)
859 .into(),
860 SyntaxKind::TerminalLBrack => self
861 .wrap_macro::<TerminalLBrack<'_>, TerminalRBrack<'_>, _, _>(
862 BracketedMacro::new_green,
863 )
864 .into(),
865 _ => unreachable!("parse_macro_elements called on non-delimiter token"),
866 }
867 }
868
869 fn expect_wrapped_macro(&mut self) -> MacroElementsGreen<'a> {
870 let mut elements: Vec<MacroElementGreen<'a>> = vec![];
871 while !matches!(
872 self.peek().kind,
873 SyntaxKind::TerminalRParen
874 | SyntaxKind::TerminalRBrace
875 | SyntaxKind::TerminalRBrack
876 | SyntaxKind::TerminalEndOfFile
877 ) {
878 let element = self.try_parse_macro_element();
879 match element {
880 Ok(element) => elements.push(element),
881 Err(TryParseFailure::SkipToken) => {
882 let _ = self.skip_until(is_of_kind!(rparen, rbrace, rbrack));
883 break;
884 }
885 Err(TryParseFailure::DoNothing) => break,
886 }
887 }
888 MacroElements::new_green(self.db, &elements)
889 }
890
891 fn wrap_macro<
892 LTerminal: syntax::node::Terminal<'a>,
893 RTerminal: syntax::node::Terminal<'a>,
894 ListGreen,
895 NewGreen: Fn(
896 &'a dyn Database,
897 LTerminal::Green,
898 MacroElementsGreen<'a>,
899 RTerminal::Green,
900 ) -> ListGreen,
901 >(
902 &mut self,
903 new_green: NewGreen,
904 ) -> ListGreen {
905 let l_term = self.take::<LTerminal>();
906 let elements = self.expect_wrapped_macro();
907 let r_term = self.parse_token::<RTerminal>();
908 new_green(self.db, l_term, elements, r_term)
909 }
910
911 fn parse_macro_rule_param_kind(&mut self) -> MacroParamKindGreen<'a> {
913 let peeked = self.peek();
914 match (peeked.kind, peeked.text.long(self.db).as_str()) {
915 (SyntaxKind::TerminalIdentifier, "ident") => {
916 ParamIdent::new_green(self.db, self.parse_token::<TerminalIdentifier<'_>>()).into()
917 }
918 (SyntaxKind::TerminalIdentifier, "expr") => {
919 ParamExpr::new_green(self.db, self.parse_token::<TerminalIdentifier<'_>>()).into()
920 }
921 _ => self.create_and_report_missing::<MacroParamKind<'_>>(
922 ParserDiagnosticKind::MissingMacroRuleParamKind,
923 ),
924 }
925 }
926
927 fn try_parse_use_path(&mut self) -> TryParseResult<UsePathGreen<'a>> {
929 if !matches!(
930 self.peek().kind,
931 SyntaxKind::TerminalLBrace | SyntaxKind::TerminalIdentifier | SyntaxKind::TerminalMul
932 ) {
933 return Err(TryParseFailure::SkipToken);
934 }
935 Ok(self.parse_use_path())
936 }
937
938 fn parse_use_path(&mut self) -> UsePathGreen<'a> {
940 match self.peek().kind {
941 SyntaxKind::TerminalLBrace => {
942 let lbrace = self.parse_token::<TerminalLBrace<'_>>();
943 let items = UsePathList::new_green(self.db,
944 &self.parse_separated_list::<
945 UsePath<'_>, TerminalComma<'_>, UsePathListElementOrSeparatorGreen<'_>
946 >(
947 Self::try_parse_use_path,
948 is_of_kind!(rbrace, module_item_kw),
949 "path segment",
950 ));
951 let rbrace = self.parse_token::<TerminalRBrace<'_>>();
952 UsePathMulti::new_green(self.db, lbrace, items, rbrace).into()
953 }
954 SyntaxKind::TerminalMul => {
955 let star = self.parse_token::<TerminalMul<'_>>();
956 UsePathStar::new_green(self.db, star).into()
957 }
958 _ => {
959 if let Ok(ident) = self.try_parse_identifier() {
960 let ident = PathSegmentSimple::new_green(self.db, ident).into();
961 match self.peek().kind {
962 SyntaxKind::TerminalColonColon => {
963 let colon_colon = self.parse_token::<TerminalColonColon<'_>>();
964 let use_path = self.parse_use_path();
965 UsePathSingle::new_green(self.db, ident, colon_colon, use_path).into()
966 }
967 SyntaxKind::TerminalAs => {
968 let as_kw = self.take::<TerminalAs<'_>>();
969 let alias = self.parse_identifier();
970 let alias_clause = AliasClause::new_green(self.db, as_kw, alias).into();
971 UsePathLeaf::new_green(self.db, ident, alias_clause).into()
972 }
973 _ => {
974 let alias_clause = OptionAliasClauseEmpty::new_green(self.db).into();
975 UsePathLeaf::new_green(self.db, ident, alias_clause).into()
976 }
977 }
978 } else {
979 let missing = self.create_and_report_missing::<TerminalIdentifier<'_>>(
980 ParserDiagnosticKind::MissingPathSegment,
981 );
982 let ident = PathSegmentSimple::new_green(self.db, missing).into();
983 UsePathLeaf::new_green(
984 self.db,
985 ident,
986 OptionAliasClauseEmpty::new_green(self.db).into(),
987 )
988 .into()
989 }
990 }
991 }
992 }
993
994 fn try_parse_identifier(&mut self) -> TryParseResult<TerminalIdentifierGreen<'a>> {
999 let peeked = self.peek();
1000 if peeked.kind.is_keyword_terminal() {
1001 Ok(self.skip_token_and_return_missing::<TerminalIdentifier<'_>>(
1003 ParserDiagnosticKind::ReservedIdentifier {
1004 identifier: peeked.text.long(self.db).to_string(),
1005 },
1006 ))
1007 } else if peeked.kind == SyntaxKind::TerminalUnderscore {
1008 Ok(self.skip_token_and_return_missing::<TerminalIdentifier<'_>>(
1009 ParserDiagnosticKind::UnderscoreNotAllowedAsIdentifier,
1010 ))
1011 } else {
1012 self.try_parse_token::<TerminalIdentifier<'_>>()
1013 }
1014 }
1015 fn is_peek_identifier_like(&self) -> bool {
1021 let kind = self.peek().kind;
1022 kind.is_keyword_terminal()
1023 || matches!(
1024 kind,
1025 SyntaxKind::TerminalUnderscore
1026 | SyntaxKind::TerminalIdentifier
1027 | SyntaxKind::TerminalDollar
1028 )
1029 }
1030
1031 fn parse_identifier(&mut self) -> TerminalIdentifierGreen<'a> {
1033 match self.try_parse_identifier() {
1034 Ok(identifier) => identifier,
1035 Err(_) => self.create_and_report_missing_terminal::<TerminalIdentifier<'_>>(),
1036 }
1037 }
1038
1039 fn parse_visibility(&mut self) -> VisibilityGreen<'a> {
1041 match self.try_parse_visibility_pub() {
1042 Some(visibility) => visibility.into(),
1043 None => VisibilityDefault::new_green(self.db).into(),
1044 }
1045 }
1046
1047 fn try_parse_visibility_pub(&mut self) -> Option<VisibilityPubGreen<'a>> {
1049 require(self.peek().kind == SyntaxKind::TerminalPub)?;
1050 let pub_kw = self.take::<TerminalPub<'_>>();
1051 let argument_clause = if self.peek().kind != SyntaxKind::TerminalLParen {
1052 OptionVisibilityPubArgumentClauseEmpty::new_green(self.db).into()
1053 } else {
1054 let lparen = self.parse_token::<TerminalLParen<'_>>();
1055 let argument = self.parse_token::<TerminalIdentifier<'_>>();
1056 let rparen = self.parse_token::<TerminalRParen<'_>>();
1057 VisibilityPubArgumentClause::new_green(self.db, lparen, argument, rparen).into()
1058 };
1059 Some(VisibilityPub::new_green(self.db, pub_kw, argument_clause))
1060 }
1061
1062 fn try_parse_attribute_list(
1067 &mut self,
1068 expected_elements_str: &str,
1069 ) -> TryParseResult<AttributeListGreen<'a>> {
1070 if self.peek().kind == SyntaxKind::TerminalHash {
1071 Ok(self.parse_attribute_list(expected_elements_str))
1072 } else {
1073 Err(TryParseFailure::SkipToken)
1074 }
1075 }
1076
1077 fn parse_attribute_list(&mut self, expected_elements_str: &str) -> AttributeListGreen<'a> {
1081 AttributeList::new_green(
1082 self.db,
1083 &self.parse_list(
1084 Self::try_parse_attribute,
1085 |x| x != SyntaxKind::TerminalHash,
1086 &or_an_attribute!(expected_elements_str),
1087 ),
1088 )
1089 }
1090
1091 fn try_parse_attribute(&mut self) -> TryParseResult<AttributeGreen<'a>> {
1094 match self.peek().kind {
1095 SyntaxKind::TerminalHash => {
1096 let hash = self.take::<TerminalHash<'_>>();
1097 let lbrack = self.parse_token::<TerminalLBrack<'_>>();
1098 let attr = self.parse_path();
1099 let arguments = self.try_parse_parenthesized_argument_list();
1100 let rbrack = self.parse_token::<TerminalRBrack<'_>>();
1101
1102 Ok(Attribute::new_green(self.db, hash, lbrack, attr, arguments, rbrack))
1103 }
1104 _ => Err(TryParseFailure::SkipToken),
1105 }
1106 }
1107
1108 fn expect_function_declaration(
1111 &mut self,
1112 optional_const: OptionTerminalConstGreen<'a>,
1113 ) -> FunctionDeclarationGreen<'a> {
1114 let function_kw = self.take::<TerminalFunction<'_>>();
1115 self.expect_function_declaration_ex(optional_const, function_kw)
1116 }
1117
1118 fn expect_function_declaration_ex(
1121 &mut self,
1122 optional_const: OptionTerminalConstGreen<'a>,
1123 function_kw: TerminalFunctionGreen<'a>,
1124 ) -> FunctionDeclarationGreen<'a> {
1125 let name = self.parse_identifier();
1126 let generic_params = self.parse_optional_generic_params();
1127 let signature = self.expect_function_signature();
1128
1129 FunctionDeclaration::new_green(
1130 self.db,
1131 optional_const,
1132 function_kw,
1133 name,
1134 generic_params,
1135 signature,
1136 )
1137 }
1138
1139 fn expect_item_function_with_body(
1142 &mut self,
1143 attributes: AttributeListGreen<'a>,
1144 visibility: VisibilityGreen<'a>,
1145 optional_const: OptionTerminalConstGreen<'a>,
1146 ) -> FunctionWithBodyGreen<'a> {
1147 let declaration = self.expect_function_declaration(optional_const);
1148 let function_body = self.parse_block();
1149 FunctionWithBody::new_green(self.db, attributes, visibility, declaration, function_body)
1150 }
1151
1152 fn expect_item_trait(
1154 &mut self,
1155 attributes: AttributeListGreen<'a>,
1156 visibility: VisibilityGreen<'a>,
1157 ) -> ItemTraitGreen<'a> {
1158 let trait_kw = self.take::<TerminalTrait<'_>>();
1159 let name = self.parse_identifier();
1160 let generic_params = self.parse_optional_generic_params();
1161 let body = if self.peek().kind == SyntaxKind::TerminalLBrace {
1162 let lbrace = self.take::<TerminalLBrace<'_>>();
1163 let items = TraitItemList::new_green(
1164 self.db,
1165 &self.parse_attributed_list(
1166 Self::try_parse_trait_item,
1167 is_of_kind!(rbrace, module_item_kw),
1168 TRAIT_ITEM_DESCRIPTION,
1169 ),
1170 );
1171 let rbrace = self.parse_token::<TerminalRBrace<'_>>();
1172 TraitBody::new_green(self.db, lbrace, items, rbrace).into()
1173 } else {
1174 self.parse_token::<TerminalSemicolon<'_>>().into()
1175 };
1176
1177 ItemTrait::new_green(self.db, attributes, visibility, trait_kw, name, generic_params, body)
1178 }
1179
1180 pub fn try_parse_trait_item(&mut self) -> TryParseResult<TraitItemGreen<'a>> {
1183 let maybe_attributes = self.try_parse_attribute_list(TRAIT_ITEM_DESCRIPTION);
1184
1185 let (has_attrs, attributes) = match maybe_attributes {
1186 Ok(attributes) => (true, attributes),
1187 Err(_) => (false, AttributeList::new_green(self.db, &[])),
1188 };
1189
1190 match self.peek().kind {
1191 SyntaxKind::TerminalFunction => Ok(self
1192 .expect_trait_item_function(
1193 attributes,
1194 OptionTerminalConstEmpty::new_green(self.db).into(),
1195 )
1196 .into()),
1197 SyntaxKind::TerminalType => Ok(self.expect_trait_item_type(attributes).into()),
1198 SyntaxKind::TerminalConst => {
1199 let const_kw = self.take::<TerminalConst<'_>>();
1200 Ok(if self.peek().kind == SyntaxKind::TerminalFunction {
1201 self.expect_trait_item_function(attributes, const_kw.into()).into()
1202 } else {
1203 self.expect_trait_item_const(attributes, const_kw).into()
1204 })
1205 }
1206 SyntaxKind::TerminalImpl => Ok(self.expect_trait_item_impl(attributes).into()),
1207 _ => {
1208 if has_attrs {
1209 Ok(self.skip_taken_node_and_return_missing::<TraitItem<'_>>(
1210 attributes,
1211 ParserDiagnosticKind::AttributesWithoutTraitItem,
1212 ))
1213 } else {
1214 Err(TryParseFailure::SkipToken)
1215 }
1216 }
1217 }
1218 }
1219
1220 fn expect_trait_item_function(
1223 &mut self,
1224 attributes: AttributeListGreen<'a>,
1225 optional_const: OptionTerminalConstGreen<'a>,
1226 ) -> TraitItemFunctionGreen<'a> {
1227 let declaration = self.expect_function_declaration(optional_const);
1228 let body = if self.peek().kind == SyntaxKind::TerminalLBrace {
1229 self.parse_block().into()
1230 } else {
1231 self.parse_token::<TerminalSemicolon<'_>>().into()
1232 };
1233 TraitItemFunction::new_green(self.db, attributes, declaration, body)
1234 }
1235
1236 fn expect_trait_item_type(
1239 &mut self,
1240 attributes: AttributeListGreen<'a>,
1241 ) -> TraitItemTypeGreen<'a> {
1242 let type_kw = self.take::<TerminalType<'_>>();
1243 let name = self.parse_identifier();
1244 let generic_params = self.parse_optional_generic_params();
1245 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
1246 TraitItemType::new_green(self.db, attributes, type_kw, name, generic_params, semicolon)
1247 }
1248
1249 fn expect_trait_item_const(
1252 &mut self,
1253 attributes: AttributeListGreen<'a>,
1254 const_kw: TerminalConstGreen<'a>,
1255 ) -> TraitItemConstantGreen<'a> {
1256 let name = self.parse_identifier();
1257 let type_clause = self.parse_type_clause(ErrorRecovery {
1258 should_stop: is_of_kind!(eq, semicolon, module_item_kw),
1259 });
1260 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
1261
1262 TraitItemConstant::new_green(self.db, attributes, const_kw, name, type_clause, semicolon)
1263 }
1264
1265 fn expect_trait_item_impl(
1268 &mut self,
1269 attributes: AttributeListGreen<'a>,
1270 ) -> TraitItemImplGreen<'a> {
1271 let impl_kw = self.take::<TerminalImpl<'_>>();
1272 let name = self.parse_identifier();
1273 let colon = self.parse_token::<TerminalColon<'_>>();
1274 let trait_path = self.parse_type_path();
1275 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
1276 TraitItemImpl::new_green(self.db, attributes, impl_kw, name, colon, trait_path, semicolon)
1277 }
1278
1279 fn expect_module_item_impl(
1281 &mut self,
1282 attributes: AttributeListGreen<'a>,
1283 visibility: VisibilityGreen<'a>,
1284 ) -> ModuleItemGreen<'a> {
1285 match self.expect_item_impl_inner(attributes, visibility, false) {
1286 ImplItemOrAlias::Item(green) => green.into(),
1287 ImplItemOrAlias::Alias(green) => green.into(),
1288 }
1289 }
1290
1291 fn expect_impl_item_impl(
1294 &mut self,
1295 attributes: AttributeListGreen<'a>,
1296 visibility: VisibilityGreen<'a>,
1297 ) -> ItemImplAliasGreen<'a> {
1298 extract_matches!(
1299 self.expect_item_impl_inner(attributes, visibility, true),
1300 ImplItemOrAlias::Alias
1301 )
1302 }
1303
1304 fn expect_item_impl_inner(
1309 &mut self,
1310 attributes: AttributeListGreen<'a>,
1311 visibility: VisibilityGreen<'a>,
1312 only_allow_alias: bool,
1313 ) -> ImplItemOrAlias<'a> {
1314 let impl_kw = self.take::<TerminalImpl<'_>>();
1315 let name = self.parse_identifier();
1316 let generic_params = self.parse_optional_generic_params();
1317
1318 if self.peek().kind == SyntaxKind::TerminalEq || only_allow_alias {
1319 let eq = self.parse_token::<TerminalEq<'_>>();
1320 let impl_path = self.parse_type_path();
1321 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
1322
1323 return ImplItemOrAlias::Alias(ItemImplAlias::new_green(
1324 self.db,
1325 attributes,
1326 visibility,
1327 impl_kw,
1328 name,
1329 generic_params,
1330 eq,
1331 impl_path,
1332 semicolon,
1333 ));
1334 }
1335
1336 let of_kw = self.parse_token::<TerminalOf<'_>>();
1337 let trait_path = self.parse_type_path();
1338 let body = if self.peek().kind == SyntaxKind::TerminalLBrace {
1339 let lbrace = self.take::<TerminalLBrace<'_>>();
1340 let items = ImplItemList::new_green(
1341 self.db,
1342 &self.parse_attributed_list(
1343 Self::try_parse_impl_item,
1344 is_of_kind!(rbrace),
1345 IMPL_ITEM_DESCRIPTION,
1346 ),
1347 );
1348 let rbrace = self.parse_token::<TerminalRBrace<'_>>();
1349 ImplBody::new_green(self.db, lbrace, items, rbrace).into()
1350 } else {
1351 self.parse_token::<TerminalSemicolon<'_>>().into()
1352 };
1353
1354 ImplItemOrAlias::Item(ItemImpl::new_green(
1355 self.db,
1356 attributes,
1357 visibility,
1358 impl_kw,
1359 name,
1360 generic_params,
1361 of_kw,
1362 trait_path,
1363 body,
1364 ))
1365 }
1366
1367 pub fn try_parse_impl_item(&mut self) -> TryParseResult<ImplItemGreen<'a>> {
1370 let maybe_attributes = self.try_parse_attribute_list(IMPL_ITEM_DESCRIPTION);
1371
1372 let (has_attrs, attributes) = match maybe_attributes {
1373 Ok(attributes) => (true, attributes),
1374 Err(_) => (false, AttributeList::new_green(self.db, &[])),
1375 };
1376
1377 let visibility = VisibilityDefault::new_green(self.db).into();
1380
1381 match self.peek().kind {
1382 SyntaxKind::TerminalFunction => Ok(self
1383 .expect_item_function_with_body(
1384 attributes,
1385 visibility,
1386 OptionTerminalConstEmpty::new_green(self.db).into(),
1387 )
1388 .into()),
1389 SyntaxKind::TerminalType => {
1390 Ok(self.expect_item_type_alias(attributes, visibility).into())
1391 }
1392 SyntaxKind::TerminalConst => {
1393 let const_kw = self.take::<TerminalConst<'_>>();
1394 Ok(if self.peek().kind == SyntaxKind::TerminalFunction {
1395 self.expect_item_function_with_body(attributes, visibility, const_kw.into())
1396 .into()
1397 } else {
1398 self.expect_item_const(attributes, visibility, const_kw).into()
1399 })
1400 }
1401 SyntaxKind::TerminalImpl => {
1402 Ok(self.expect_impl_item_impl(attributes, visibility).into())
1403 }
1404 SyntaxKind::TerminalModule => {
1406 Ok(self.expect_item_module(attributes, visibility).into())
1407 }
1408 SyntaxKind::TerminalStruct => {
1409 Ok(self.expect_item_struct(attributes, visibility).into())
1410 }
1411 SyntaxKind::TerminalEnum => Ok(self.expect_item_enum(attributes, visibility).into()),
1412 SyntaxKind::TerminalExtern => Ok(self.expect_item_extern(attributes, visibility)),
1413 SyntaxKind::TerminalUse => Ok(self.expect_item_use(attributes, visibility).into()),
1414 SyntaxKind::TerminalTrait => Ok(self.expect_item_trait(attributes, visibility).into()),
1415 _ => {
1416 if has_attrs {
1417 Ok(self.skip_taken_node_and_return_missing::<ImplItem<'_>>(
1418 attributes,
1419 ParserDiagnosticKind::AttributesWithoutImplItem,
1420 ))
1421 } else {
1422 Err(TryParseFailure::SkipToken)
1423 }
1424 }
1425 }
1426 }
1427
1428 fn expect_item_inline_macro(
1430 &mut self,
1431 attributes: AttributeListGreen<'a>,
1432 path: ExprPathGreen<'a>,
1433 ) -> ItemInlineMacroGreen<'a> {
1434 let bang = self.parse_token::<TerminalNot<'_>>();
1435 self.parse_item_inline_macro_given_bang(attributes, path, bang)
1436 }
1437
1438 fn parse_item_inline_macro_given_bang(
1440 &mut self,
1441 attributes: AttributeListGreen<'a>,
1442 path: ExprPathGreen<'a>,
1443 bang: TerminalNotGreen<'a>,
1444 ) -> ItemInlineMacroGreen<'a> {
1445 let token_tree_node = self.parse_token_tree_node();
1446 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
1447 ItemInlineMacro::new_green(self.db, attributes, path, bang, token_tree_node, semicolon)
1448 }
1449
1450 pub fn try_parse_expr(&mut self) -> TryParseResult<ExprGreen<'a>> {
1455 self.try_parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Allow, AndLetBehavior::Simple)
1456 }
1457 pub fn parse_expr(&mut self) -> ExprGreen<'a> {
1460 match self.try_parse_expr() {
1461 Ok(green) => green,
1462 Err(_) => {
1463 self.create_and_report_missing::<Expr<'_>>(ParserDiagnosticKind::MissingExpression)
1464 }
1465 }
1466 }
1467
1468 fn parse_binary_operator(&mut self) -> BinaryOperatorGreen<'a> {
1472 match self.peek().kind {
1475 SyntaxKind::TerminalDot => self.take::<TerminalDot<'_>>().into(),
1476 SyntaxKind::TerminalMul => self.take::<TerminalMul<'_>>().into(),
1477 SyntaxKind::TerminalMulEq => self.take::<TerminalMulEq<'_>>().into(),
1478 SyntaxKind::TerminalDiv => self.take::<TerminalDiv<'_>>().into(),
1479 SyntaxKind::TerminalDivEq => self.take::<TerminalDivEq<'_>>().into(),
1480 SyntaxKind::TerminalMod => self.take::<TerminalMod<'_>>().into(),
1481 SyntaxKind::TerminalModEq => self.take::<TerminalModEq<'_>>().into(),
1482 SyntaxKind::TerminalPlus => self.take::<TerminalPlus<'_>>().into(),
1483 SyntaxKind::TerminalPlusEq => self.take::<TerminalPlusEq<'_>>().into(),
1484 SyntaxKind::TerminalMinus => self.take::<TerminalMinus<'_>>().into(),
1485 SyntaxKind::TerminalMinusEq => self.take::<TerminalMinusEq<'_>>().into(),
1486 SyntaxKind::TerminalEq => self.take::<TerminalEq<'_>>().into(),
1487 SyntaxKind::TerminalEqEq => self.take::<TerminalEqEq<'_>>().into(),
1488 SyntaxKind::TerminalNeq => self.take::<TerminalNeq<'_>>().into(),
1489 SyntaxKind::TerminalLT => self.take::<TerminalLT<'_>>().into(),
1490 SyntaxKind::TerminalGT => self.take::<TerminalGT<'_>>().into(),
1491 SyntaxKind::TerminalLE => self.take::<TerminalLE<'_>>().into(),
1492 SyntaxKind::TerminalGE => self.take::<TerminalGE<'_>>().into(),
1493 SyntaxKind::TerminalAnd => self.take::<TerminalAnd<'_>>().into(),
1494 SyntaxKind::TerminalAndAnd => self.take::<TerminalAndAnd<'_>>().into(),
1495 SyntaxKind::TerminalOrOr => self.take::<TerminalOrOr<'_>>().into(),
1496 SyntaxKind::TerminalOr => self.take::<TerminalOr<'_>>().into(),
1497 SyntaxKind::TerminalXor => self.take::<TerminalXor<'_>>().into(),
1498 SyntaxKind::TerminalDotDot => self.take::<TerminalDotDot<'_>>().into(),
1499 SyntaxKind::TerminalDotDotEq => self.take::<TerminalDotDotEq<'_>>().into(),
1500 _ => unreachable!(),
1501 }
1502 }
1503
1504 fn expect_unary_operator(&mut self) -> UnaryOperatorGreen<'a> {
1506 match self.peek().kind {
1507 SyntaxKind::TerminalAt => self.take::<TerminalAt<'_>>().into(),
1508 SyntaxKind::TerminalAnd | SyntaxKind::TerminalAndAnd => {
1509 self.unglue_andand_for_unary();
1510 self.take::<TerminalAnd<'_>>().into()
1511 }
1512 SyntaxKind::TerminalNot => self.take::<TerminalNot<'_>>().into(),
1513 SyntaxKind::TerminalBitNot => self.take::<TerminalBitNot<'_>>().into(),
1514 SyntaxKind::TerminalMinus => self.take::<TerminalMinus<'_>>().into(),
1515 SyntaxKind::TerminalMul => self.take::<TerminalMul<'_>>().into(),
1516 _ => unreachable!(),
1517 }
1518 }
1519
1520 fn is_comparison_operator(&self, kind: SyntaxKind) -> bool {
1532 matches!(
1533 kind,
1534 SyntaxKind::TerminalLT
1535 | SyntaxKind::TerminalGT
1536 | SyntaxKind::TerminalLE
1537 | SyntaxKind::TerminalGE
1538 | SyntaxKind::TerminalEqEq
1539 | SyntaxKind::TerminalNeq
1540 )
1541 }
1542
1543 fn try_parse_expr_limited(
1550 &mut self,
1551 parent_precedence: usize,
1552 lbrace_allowed: LbraceAllowed,
1553 and_let_behavior: AndLetBehavior,
1554 ) -> TryParseResult<ExprGreen<'a>> {
1555 let mut expr = self.try_parse_atom_or_unary(lbrace_allowed)?;
1556 let mut child_op: Option<SyntaxKind> = None;
1557 loop {
1558 let peeked_kind = self.peek().kind;
1559 let Some(precedence) = get_post_operator_precedence(peeked_kind) else {
1560 return Ok(expr);
1561 };
1562 if precedence >= parent_precedence {
1563 return Ok(expr);
1564 }
1565 expr = match peeked_kind {
1566 SyntaxKind::TerminalAndAnd
1569 if and_let_behavior == AndLetBehavior::Stop
1570 && self.peek_next_next_kind() == SyntaxKind::TerminalLet =>
1571 {
1572 return Ok(expr);
1573 }
1574 SyntaxKind::TerminalQuestionMark => ExprErrorPropagate::new_green(
1575 self.db,
1576 expr,
1577 self.take::<TerminalQuestionMark<'_>>(),
1578 )
1579 .into(),
1580 SyntaxKind::TerminalLBrack => {
1581 let lbrack = self.take::<TerminalLBrack<'_>>();
1582 let index_expr = self.parse_expr();
1583 let rbrack = self.parse_token::<TerminalRBrack<'_>>();
1584 ExprIndexed::new_green(self.db, expr, lbrack, index_expr, rbrack).into()
1585 }
1586 current_op => {
1587 if let Some(child_op_kind) = child_op
1588 && self.is_comparison_operator(child_op_kind)
1589 && self.is_comparison_operator(current_op)
1590 {
1591 self.add_diagnostic(
1592 ParserDiagnosticKind::ConsecutiveMathOperators {
1593 first_op: child_op_kind,
1594 second_op: current_op,
1595 },
1596 TextSpan::cursor(self.offset.add_width(self.current_width)),
1597 );
1598 }
1599 child_op = Some(current_op);
1600 let op = self.parse_binary_operator();
1601 let rhs = self.parse_expr_limited(precedence, lbrace_allowed, and_let_behavior);
1602 ExprBinary::new_green(self.db, expr, op, rhs).into()
1603 }
1604 };
1605 }
1606 }
1607
1608 fn try_parse_atom_or_unary(
1614 &mut self,
1615 lbrace_allowed: LbraceAllowed,
1616 ) -> TryParseResult<ExprGreen<'a>> {
1617 let Some(precedence) = get_unary_operator_precedence(self.peek().kind) else {
1618 return self.try_parse_atom(lbrace_allowed);
1619 };
1620 let op = self.expect_unary_operator();
1621 let expr = self.parse_expr_limited(precedence, lbrace_allowed, AndLetBehavior::Simple);
1622 Ok(ExprUnary::new_green(self.db, op, expr).into())
1623 }
1624
1625 fn parse_expr_limited(
1630 &mut self,
1631 parent_precedence: usize,
1632 lbrace_allowed: LbraceAllowed,
1633 and_let_behavior: AndLetBehavior,
1634 ) -> ExprGreen<'a> {
1635 match self.try_parse_expr_limited(parent_precedence, lbrace_allowed, and_let_behavior) {
1636 Ok(green) => green,
1637 Err(_) => {
1638 self.create_and_report_missing::<Expr<'_>>(ParserDiagnosticKind::MissingExpression)
1639 }
1640 }
1641 }
1642
1643 fn try_parse_atom(&mut self, lbrace_allowed: LbraceAllowed) -> TryParseResult<ExprGreen<'a>> {
1649 match self.peek().kind {
1651 SyntaxKind::TerminalIdentifier | SyntaxKind::TerminalDollar => {
1652 let path = self.parse_path();
1654 match self.peek().kind {
1655 SyntaxKind::TerminalLParen => Ok(self.expect_function_call(path).into()),
1656 SyntaxKind::TerminalLBrace if lbrace_allowed == LbraceAllowed::Allow => {
1657 Ok(self.expect_constructor_call(path).into())
1658 }
1659 SyntaxKind::TerminalNot => Ok(self.expect_macro_call(path).into()),
1660 _ => Ok(path.into()),
1661 }
1662 }
1663 SyntaxKind::TerminalFalse => Ok(self.take::<TerminalFalse<'_>>().into()),
1664 SyntaxKind::TerminalTrue => Ok(self.take::<TerminalTrue<'_>>().into()),
1665 SyntaxKind::TerminalLiteralNumber => Ok(self.take_terminal_literal_number().into()),
1666 SyntaxKind::TerminalShortString => Ok(self.take_terminal_short_string().into()),
1667 SyntaxKind::TerminalString => Ok(self.take_terminal_string().into()),
1668 SyntaxKind::TerminalLParen => {
1669 Ok(self.expect_parenthesized_expr())
1672 }
1673 SyntaxKind::TerminalLBrack => Ok(self.expect_fixed_size_array_expr().into()),
1674 SyntaxKind::TerminalLBrace if lbrace_allowed == LbraceAllowed::Allow => {
1675 Ok(self.parse_block().into())
1676 }
1677 SyntaxKind::TerminalMatch if lbrace_allowed == LbraceAllowed::Allow => {
1678 Ok(self.expect_match_expr().into())
1679 }
1680 SyntaxKind::TerminalIf if lbrace_allowed == LbraceAllowed::Allow => {
1681 Ok(self.expect_if_expr().into())
1682 }
1683 SyntaxKind::TerminalLoop if lbrace_allowed == LbraceAllowed::Allow => {
1684 Ok(self.expect_loop_expr().into())
1685 }
1686 SyntaxKind::TerminalWhile if lbrace_allowed == LbraceAllowed::Allow => {
1687 Ok(self.expect_while_expr().into())
1688 }
1689 SyntaxKind::TerminalFor if lbrace_allowed == LbraceAllowed::Allow => {
1690 Ok(self.expect_for_expr().into())
1691 }
1692 SyntaxKind::TerminalOr | SyntaxKind::TerminalOrOr
1693 if lbrace_allowed == LbraceAllowed::Allow =>
1694 {
1695 Ok(self.expect_closure_expr().into())
1696 }
1697 _ => {
1698 Err(TryParseFailure::SkipToken)
1700 }
1701 }
1702 }
1703
1704 fn try_parse_type_expr(&mut self) -> TryParseResult<ExprGreen<'a>> {
1707 match self.peek().kind {
1709 SyntaxKind::TerminalUnderscore => Ok(self.take::<TerminalUnderscore<'_>>().into()),
1710 SyntaxKind::TerminalAt => {
1711 let op = self.take::<TerminalAt<'_>>().into();
1712 let expr = self.parse_type_expr();
1713 Ok(ExprUnary::new_green(self.db, op, expr).into())
1714 }
1715 SyntaxKind::TerminalAnd | SyntaxKind::TerminalAndAnd => {
1716 self.unglue_andand_for_unary();
1717 let op = self.take::<TerminalAnd<'_>>().into();
1718 let expr = self.parse_type_expr();
1719 Ok(ExprUnary::new_green(self.db, op, expr).into())
1720 }
1721 SyntaxKind::TerminalIdentifier | SyntaxKind::TerminalDollar => {
1722 Ok(self.parse_type_path().into())
1723 }
1724 SyntaxKind::TerminalLParen => Ok(self.expect_type_tuple_expr()),
1725 SyntaxKind::TerminalLBrack => Ok(self.expect_type_fixed_size_array_expr()),
1726 _ => {
1727 Err(TryParseFailure::SkipToken)
1729 }
1730 }
1731 }
1732
1733 fn parse_type_expr(&mut self) -> ExprGreen<'a> {
1736 match self.try_parse_type_expr() {
1737 Ok(expr) => expr,
1738 Err(_) => self
1739 .create_and_report_missing::<Expr<'_>>(ParserDiagnosticKind::MissingTypeExpression),
1740 }
1741 }
1742
1743 fn expect_struct_ctor_argument_list_braced(&mut self) -> StructArgListBracedGreen<'a> {
1746 let lbrace = self.take::<TerminalLBrace<'_>>();
1747 let arg_list = StructArgList::new_green(
1748 self.db,
1749 &self.parse_separated_list::<StructArg<'_>, TerminalComma<'_>, StructArgListElementOrSeparatorGreen<'_>>(
1750 Self::try_parse_struct_ctor_argument,
1751 is_of_kind!(rparen, block, rbrace, module_item_kw),
1752 "struct constructor argument",
1753 ),
1754 );
1755 let rbrace = self.parse_token::<TerminalRBrace<'_>>();
1756
1757 StructArgListBraced::new_green(self.db, lbrace, arg_list, rbrace)
1758 }
1759
1760 fn expect_function_call(&mut self, path: ExprPathGreen<'a>) -> ExprFunctionCallGreen<'a> {
1763 let func_name = path;
1764 let parenthesized_args = self.expect_parenthesized_argument_list();
1765 ExprFunctionCall::new_green(self.db, func_name, parenthesized_args)
1766 }
1767
1768 fn expect_macro_call(&mut self, path: ExprPathGreen<'a>) -> ExprInlineMacroGreen<'a> {
1771 let bang = self.take::<TerminalNot<'_>>();
1772 let macro_name = path;
1773 let token_tree_node = self.parse_token_tree_node();
1774 ExprInlineMacro::new_green(self.db, macro_name, bang, token_tree_node)
1775 }
1776
1777 fn parse_token_tree(&mut self) -> TokenTreeGreen<'a> {
1782 match self.peek().kind {
1783 SyntaxKind::TerminalLBrace
1784 | SyntaxKind::TerminalLParen
1785 | SyntaxKind::TerminalLBrack => self.parse_token_tree_node().into(),
1786 _ => self.parse_token_tree_leaf().into(),
1787 }
1788 }
1789
1790 fn parse_token_tree_leaf(&mut self) -> TokenTreeLeafGreen<'a> {
1791 let token_node = self.take_token_node();
1792 TokenTreeLeaf::new_green(self.db, token_node)
1793 }
1794
1795 fn parse_token_tree_node(&mut self) -> TokenTreeNodeGreen<'a> {
1796 let wrapped_token_tree = match self.peek().kind {
1797 SyntaxKind::TerminalLBrace => self
1798 .expect_wrapped_token_tree::<TerminalLBrace<'_>, TerminalRBrace<'_>, _, _>(
1799 BracedTokenTree::new_green,
1800 )
1801 .into(),
1802 SyntaxKind::TerminalLParen => self
1803 .expect_wrapped_token_tree::<TerminalLParen<'_>, TerminalRParen<'_>, _, _>(
1804 ParenthesizedTokenTree::new_green,
1805 )
1806 .into(),
1807 SyntaxKind::TerminalLBrack => self
1808 .expect_wrapped_token_tree::<TerminalLBrack<'_>, TerminalRBrack<'_>, _, _>(
1809 BracketedTokenTree::new_green,
1810 )
1811 .into(),
1812 _ => {
1813 return self.create_and_report_missing::<TokenTreeNode<'_>>(
1814 ParserDiagnosticKind::MissingWrappedArgList,
1815 );
1816 }
1817 };
1818 TokenTreeNode::new_green(self.db, wrapped_token_tree)
1819 }
1820
1821 fn expect_wrapped_token_tree<
1826 LTerminal: syntax::node::Terminal<'a>,
1827 RTerminal: syntax::node::Terminal<'a>,
1828 ListGreen,
1829 NewGreen: Fn(&'a dyn Database, LTerminal::Green, TokenListGreen<'a>, RTerminal::Green) -> ListGreen,
1830 >(
1831 &mut self,
1832 new_green: NewGreen,
1833 ) -> ListGreen {
1834 let l_term = self.take::<LTerminal>();
1835 let tokens = self.parse_token_list();
1836 let r_term: <RTerminal as TypedSyntaxNode<'_>>::Green = self.parse_token::<RTerminal>();
1837 new_green(self.db, l_term, TokenList::new_green(self.db, &tokens), r_term)
1838 }
1839
1840 fn parse_token_list(&mut self) -> Vec<TokenTreeGreen<'a>> {
1841 let mut tokens: Vec<TokenTreeGreen<'_>> = vec![];
1842 while !matches!(
1843 self.peek().kind,
1844 SyntaxKind::TerminalRParen
1845 | SyntaxKind::TerminalRBrace
1846 | SyntaxKind::TerminalRBrack
1847 | SyntaxKind::TerminalEndOfFile
1848 ) {
1849 tokens.push(self.parse_token_tree());
1850 }
1851 tokens
1852 }
1853
1854 fn take_token_node(&mut self) -> TokenNodeGreen<'a> {
1856 match self.peek().kind {
1857 SyntaxKind::TerminalIdentifier => self.take::<TerminalIdentifier<'_>>().into(),
1858 SyntaxKind::TerminalLiteralNumber => self.take::<TerminalLiteralNumber<'_>>().into(),
1859 SyntaxKind::TerminalShortString => self.take::<TerminalShortString<'_>>().into(),
1860 SyntaxKind::TerminalString => self.take::<TerminalString<'_>>().into(),
1861 SyntaxKind::TerminalAs => self.take::<TerminalAs<'_>>().into(),
1862 SyntaxKind::TerminalConst => self.take::<TerminalConst<'_>>().into(),
1863 SyntaxKind::TerminalElse => self.take::<TerminalElse<'_>>().into(),
1864 SyntaxKind::TerminalEnum => self.take::<TerminalEnum<'_>>().into(),
1865 SyntaxKind::TerminalExtern => self.take::<TerminalExtern<'_>>().into(),
1866 SyntaxKind::TerminalFalse => self.take::<TerminalFalse<'_>>().into(),
1867 SyntaxKind::TerminalFunction => self.take::<TerminalFunction<'_>>().into(),
1868 SyntaxKind::TerminalIf => self.take::<TerminalIf<'_>>().into(),
1869 SyntaxKind::TerminalWhile => self.take::<TerminalWhile<'_>>().into(),
1870 SyntaxKind::TerminalFor => self.take::<TerminalFor<'_>>().into(),
1871 SyntaxKind::TerminalLoop => self.take::<TerminalLoop<'_>>().into(),
1872 SyntaxKind::TerminalImpl => self.take::<TerminalImpl<'_>>().into(),
1873 SyntaxKind::TerminalImplicits => self.take::<TerminalImplicits<'_>>().into(),
1874 SyntaxKind::TerminalLet => self.take::<TerminalLet<'_>>().into(),
1875 SyntaxKind::TerminalMatch => self.take::<TerminalMatch<'_>>().into(),
1876 SyntaxKind::TerminalModule => self.take::<TerminalModule<'_>>().into(),
1877 SyntaxKind::TerminalMut => self.take::<TerminalMut<'_>>().into(),
1878 SyntaxKind::TerminalNoPanic => self.take::<TerminalNoPanic<'_>>().into(),
1879 SyntaxKind::TerminalOf => self.take::<TerminalOf<'_>>().into(),
1880 SyntaxKind::TerminalRef => self.take::<TerminalRef<'_>>().into(),
1881 SyntaxKind::TerminalContinue => self.take::<TerminalContinue<'_>>().into(),
1882 SyntaxKind::TerminalReturn => self.take::<TerminalReturn<'_>>().into(),
1883 SyntaxKind::TerminalBreak => self.take::<TerminalBreak<'_>>().into(),
1884 SyntaxKind::TerminalStruct => self.take::<TerminalStruct<'_>>().into(),
1885 SyntaxKind::TerminalTrait => self.take::<TerminalTrait<'_>>().into(),
1886 SyntaxKind::TerminalTrue => self.take::<TerminalTrue<'_>>().into(),
1887 SyntaxKind::TerminalType => self.take::<TerminalType<'_>>().into(),
1888 SyntaxKind::TerminalUse => self.take::<TerminalUse<'_>>().into(),
1889 SyntaxKind::TerminalPub => self.take::<TerminalPub<'_>>().into(),
1890 SyntaxKind::TerminalAnd => self.take::<TerminalAnd<'_>>().into(),
1891 SyntaxKind::TerminalAndAnd => self.take::<TerminalAndAnd<'_>>().into(),
1892 SyntaxKind::TerminalArrow => self.take::<TerminalArrow<'_>>().into(),
1893 SyntaxKind::TerminalAt => self.take::<TerminalAt<'_>>().into(),
1894 SyntaxKind::TerminalBadCharacters => self.take::<TerminalBadCharacters<'_>>().into(),
1895 SyntaxKind::TerminalColon => self.take::<TerminalColon<'_>>().into(),
1896 SyntaxKind::TerminalColonColon => self.take::<TerminalColonColon<'_>>().into(),
1897 SyntaxKind::TerminalComma => self.take::<TerminalComma<'_>>().into(),
1898 SyntaxKind::TerminalDiv => self.take::<TerminalDiv<'_>>().into(),
1899 SyntaxKind::TerminalDivEq => self.take::<TerminalDivEq<'_>>().into(),
1900 SyntaxKind::TerminalDollar => self.take::<TerminalDollar<'_>>().into(),
1901 SyntaxKind::TerminalDot => self.take::<TerminalDot<'_>>().into(),
1902 SyntaxKind::TerminalDotDot => self.take::<TerminalDotDot<'_>>().into(),
1903 SyntaxKind::TerminalDotDotEq => self.take::<TerminalDotDotEq<'_>>().into(),
1904 SyntaxKind::TerminalEndOfFile => self.take::<TerminalEndOfFile<'_>>().into(),
1905 SyntaxKind::TerminalEq => self.take::<TerminalEq<'_>>().into(),
1906 SyntaxKind::TerminalEqEq => self.take::<TerminalEqEq<'_>>().into(),
1907 SyntaxKind::TerminalGE => self.take::<TerminalGE<'_>>().into(),
1908 SyntaxKind::TerminalGT => self.take::<TerminalGT<'_>>().into(),
1909 SyntaxKind::TerminalHash => self.take::<TerminalHash<'_>>().into(),
1910 SyntaxKind::TerminalLBrace => self.take::<TerminalLBrace<'_>>().into(),
1911 SyntaxKind::TerminalLBrack => self.take::<TerminalLBrack<'_>>().into(),
1912 SyntaxKind::TerminalLE => self.take::<TerminalLE<'_>>().into(),
1913 SyntaxKind::TerminalLParen => self.take::<TerminalLParen<'_>>().into(),
1914 SyntaxKind::TerminalLT => self.take::<TerminalLT<'_>>().into(),
1915 SyntaxKind::TerminalMatchArrow => self.take::<TerminalMatchArrow<'_>>().into(),
1916 SyntaxKind::TerminalMinus => self.take::<TerminalMinus<'_>>().into(),
1917 SyntaxKind::TerminalMinusEq => self.take::<TerminalMinusEq<'_>>().into(),
1918 SyntaxKind::TerminalMod => self.take::<TerminalMod<'_>>().into(),
1919 SyntaxKind::TerminalModEq => self.take::<TerminalModEq<'_>>().into(),
1920 SyntaxKind::TerminalMul => self.take::<TerminalMul<'_>>().into(),
1921 SyntaxKind::TerminalMulEq => self.take::<TerminalMulEq<'_>>().into(),
1922 SyntaxKind::TerminalNeq => self.take::<TerminalNeq<'_>>().into(),
1923 SyntaxKind::TerminalNot => self.take::<TerminalNot<'_>>().into(),
1924 SyntaxKind::TerminalBitNot => self.take::<TerminalBitNot<'_>>().into(),
1925 SyntaxKind::TerminalOr => self.take::<TerminalOr<'_>>().into(),
1926 SyntaxKind::TerminalOrOr => self.take::<TerminalOrOr<'_>>().into(),
1927 SyntaxKind::TerminalPlus => self.take::<TerminalPlus<'_>>().into(),
1928 SyntaxKind::TerminalPlusEq => self.take::<TerminalPlusEq<'_>>().into(),
1929 SyntaxKind::TerminalQuestionMark => self.take::<TerminalQuestionMark<'_>>().into(),
1930 SyntaxKind::TerminalRBrace => self.take::<TerminalRBrace<'_>>().into(),
1931 SyntaxKind::TerminalRBrack => self.take::<TerminalRBrack<'_>>().into(),
1932 SyntaxKind::TerminalRParen => self.take::<TerminalRParen<'_>>().into(),
1933 SyntaxKind::TerminalSemicolon => self.take::<TerminalSemicolon<'_>>().into(),
1934 SyntaxKind::TerminalUnderscore => self.take::<TerminalUnderscore<'_>>().into(),
1935 SyntaxKind::TerminalXor => self.take::<TerminalXor<'_>>().into(),
1936 other => unreachable!("Unexpected token kind: {other:?}"),
1937 }
1938 }
1939 pub(crate) fn parse_wrapped_arg_list(&mut self) -> WrappedArgListGreen<'a> {
1942 match self.peek().kind {
1943 SyntaxKind::TerminalLParen => self
1944 .expect_wrapped_argument_list::<TerminalLParen<'_>, TerminalRParen<'_>, _, _>(
1945 ArgListParenthesized::new_green,
1946 )
1947 .into(),
1948 SyntaxKind::TerminalLBrack => self
1949 .expect_wrapped_argument_list::<TerminalLBrack<'_>, TerminalRBrack<'_>, _, _>(
1950 ArgListBracketed::new_green,
1951 )
1952 .into(),
1953 SyntaxKind::TerminalLBrace => self
1954 .expect_wrapped_argument_list::<TerminalLBrace<'_>, TerminalRBrace<'_>, _, _>(
1955 ArgListBraced::new_green,
1956 )
1957 .into(),
1958 _ => self.create_and_report_missing::<WrappedArgList<'_>>(
1959 ParserDiagnosticKind::MissingWrappedArgList,
1960 ),
1961 }
1962 }
1963
1964 fn expect_wrapped_argument_list<
1969 LTerminal: syntax::node::Terminal<'a>,
1970 RTerminal: syntax::node::Terminal<'a>,
1971 ListGreen,
1972 NewGreen: Fn(&'a dyn Database, LTerminal::Green, ArgListGreen<'a>, RTerminal::Green) -> ListGreen,
1973 >(
1974 &mut self,
1975 new_green: NewGreen,
1976 ) -> ListGreen {
1977 let l_term = self.take::<LTerminal>();
1978 let exprs: Vec<ArgListElementOrSeparatorGreen<'_>> = self
1979 .parse_separated_list::<Arg<'_>, TerminalComma<'_>, ArgListElementOrSeparatorGreen<'_>>(
1980 Self::try_parse_function_argument,
1981 is_of_kind!(rparen, rbrace, rbrack, block, module_item_kw),
1982 "argument",
1983 );
1984 let r_term: <RTerminal as TypedSyntaxNode<'_>>::Green = self.parse_token::<RTerminal>();
1985 new_green(self.db, l_term, ArgList::new_green(self.db, &exprs), r_term)
1986 }
1987
1988 fn expect_parenthesized_argument_list(&mut self) -> ArgListParenthesizedGreen<'a> {
1991 self.expect_wrapped_argument_list::<TerminalLParen<'_>, TerminalRParen<'_>, _, _>(
1992 ArgListParenthesized::new_green,
1993 )
1994 }
1995
1996 fn try_parse_parenthesized_argument_list(&mut self) -> OptionArgListParenthesizedGreen<'a> {
1999 if self.peek().kind == SyntaxKind::TerminalLParen {
2000 self.expect_parenthesized_argument_list().into()
2001 } else {
2002 OptionArgListParenthesizedEmpty::new_green(self.db).into()
2003 }
2004 }
2005
2006 fn try_parse_function_argument(&mut self) -> TryParseResult<ArgGreen<'a>> {
2009 let modifiers_list = self.parse_modifier_list();
2010 let arg_clause = self.try_parse_argument_clause();
2011 match arg_clause {
2012 Ok(arg_clause) => {
2013 let modifiers = ModifierList::new_green(self.db, &modifiers_list);
2014 Ok(Arg::new_green(self.db, modifiers, arg_clause))
2015 }
2016 Err(_) if !modifiers_list.is_empty() => {
2017 let modifiers = ModifierList::new_green(self.db, &modifiers_list);
2018 let arg_clause = ArgClauseUnnamed::new_green(self.db, self.parse_expr()).into();
2019 Ok(Arg::new_green(self.db, modifiers, arg_clause))
2020 }
2021 Err(err) => Err(err),
2022 }
2023 }
2024
2025 fn try_parse_argument_clause(&mut self) -> TryParseResult<ArgClauseGreen<'a>> {
2033 if self.peek().kind == SyntaxKind::TerminalColon {
2034 let colon = self.take::<TerminalColon<'_>>();
2035 let name = self.parse_identifier();
2036 return Ok(ArgClauseFieldInitShorthand::new_green(
2037 self.db,
2038 colon,
2039 ExprFieldInitShorthand::new_green(self.db, name),
2040 )
2041 .into());
2042 }
2043
2044 let value = self.try_parse_expr()?;
2046 Ok(
2049 if self.peek().kind == SyntaxKind::TerminalColon
2050 && let Some(argname) = self.try_extract_identifier(value)
2051 {
2052 let colon = self.take::<TerminalColon<'_>>();
2053 let expr = self.parse_expr();
2054 ArgClauseNamed::new_green(self.db, argname, colon, expr).into()
2055 } else {
2056 ArgClauseUnnamed::new_green(self.db, value).into()
2057 },
2058 )
2059 }
2060
2061 fn try_extract_identifier(&self, expr: ExprGreen<'a>) -> Option<TerminalIdentifierGreen<'a>> {
2064 let GreenNode {
2066 kind: SyntaxKind::ExprPath,
2067 details: GreenNodeDetails::Node { children: children0, .. },
2068 } = expr.0.long(self.db)
2069 else {
2070 return None;
2071 };
2072
2073 let [_dollar, path_inner] = children0[..] else {
2075 return None;
2076 };
2077
2078 let GreenNode {
2079 kind: SyntaxKind::ExprPathInner,
2080 details: GreenNodeDetails::Node { children: children1, .. },
2081 } = path_inner.long(self.db)
2082 else {
2083 return None;
2084 };
2085
2086 let [path_segment] = children1[..] else {
2088 return None;
2089 };
2090
2091 let GreenNode {
2093 kind: SyntaxKind::PathSegmentSimple,
2094 details: GreenNodeDetails::Node { children: children2, .. },
2095 } = path_segment.long(self.db)
2096 else {
2097 return None;
2098 };
2099
2100 let [ident] = children2[..] else {
2102 return None;
2103 };
2104
2105 let GreenNode { kind: SyntaxKind::TerminalIdentifier, .. } = ident.long(self.db) else {
2107 return None;
2108 };
2109
2110 Some(TerminalIdentifierGreen(ident))
2111 }
2112
2113 fn expect_constructor_call(&mut self, path: ExprPathGreen<'a>) -> ExprStructCtorCallGreen<'a> {
2116 let ctor_name = path;
2117 let args = self.expect_struct_ctor_argument_list_braced();
2118 ExprStructCtorCall::new_green(self.db, ctor_name, args)
2119 }
2120
2121 fn expect_parenthesized_expr(&mut self) -> ExprGreen<'a> {
2125 let lparen = self.take::<TerminalLParen<'_>>();
2126 let exprs: Vec<ExprListElementOrSeparatorGreen<'_>> = self
2127 .parse_separated_list::<Expr<'_>, TerminalComma<'_>, ExprListElementOrSeparatorGreen<'_>>(
2128 Self::try_parse_expr,
2129 is_of_kind!(rparen, block, rbrace, module_item_kw),
2130 "expression",
2131 );
2132 let rparen = self.parse_token::<TerminalRParen<'_>>();
2133
2134 if let [ExprListElementOrSeparatorGreen::Element(expr)] = &exprs[..] {
2135 ExprParenthesized::new_green(self.db, lparen, *expr, rparen).into()
2137 } else {
2138 ExprListParenthesized::new_green(
2139 self.db,
2140 lparen,
2141 ExprList::new_green(self.db, &exprs),
2142 rparen,
2143 )
2144 .into()
2145 }
2146 }
2147
2148 fn expect_type_tuple_expr(&mut self) -> ExprGreen<'a> {
2152 let lparen = self.take::<TerminalLParen<'_>>();
2153 let exprs: Vec<ExprListElementOrSeparatorGreen<'_>> = self
2154 .parse_separated_list::<Expr<'_>, TerminalComma<'_>, ExprListElementOrSeparatorGreen<'_>>(
2155 Self::try_parse_type_expr,
2156 is_of_kind!(rparen, block, rbrace, module_item_kw),
2157 "type expression",
2158 );
2159 let rparen = self.parse_token::<TerminalRParen<'_>>();
2160 if let [ExprListElementOrSeparatorGreen::Element(_)] = &exprs[..] {
2161 self.add_diagnostic(
2162 ParserDiagnosticKind::MissingToken(SyntaxKind::TerminalComma),
2163 TextSpan::cursor(self.offset),
2164 );
2165 }
2166 ExprListParenthesized::new_green(
2167 self.db,
2168 lparen,
2169 ExprList::new_green(self.db, &exprs),
2170 rparen,
2171 )
2172 .into()
2173 }
2174
2175 fn expect_type_fixed_size_array_expr(&mut self) -> ExprGreen<'a> {
2179 let lbrack = self.take::<TerminalLBrack<'_>>();
2180 let exprs: Vec<ExprListElementOrSeparatorGreen<'_>> = self
2181 .parse_separated_list::<Expr<'_>, TerminalComma<'_>, ExprListElementOrSeparatorGreen<'_>>(
2182 Self::try_parse_type_expr,
2183 is_of_kind!(rbrack, semicolon),
2184 "type expression",
2185 );
2186 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
2187 let size_expr = self.parse_expr();
2188 let fixed_size_array_size =
2189 FixedSizeArraySize::new_green(self.db, semicolon, size_expr).into();
2190 let rbrack = self.parse_token::<TerminalRBrack<'_>>();
2191 ExprFixedSizeArray::new_green(
2192 self.db,
2193 lbrack,
2194 ExprList::new_green(self.db, &exprs),
2195 fixed_size_array_size,
2196 rbrack,
2197 )
2198 .into()
2199 }
2200
2201 fn expect_struct_argument_tail(&mut self) -> StructArgTailGreen<'a> {
2204 let dotdot = self.take::<TerminalDotDot<'_>>(); let expr = self.parse_expr();
2207 StructArgTail::new_green(self.db, dotdot, expr)
2208 }
2209
2210 fn try_parse_struct_ctor_argument(&mut self) -> TryParseResult<StructArgGreen<'a>> {
2215 match self.peek().kind {
2216 SyntaxKind::TerminalDotDot => Ok(self.expect_struct_argument_tail().into()),
2217 _ => self.try_parse_argument_single().map(|arg| arg.into()),
2218 }
2219 }
2220
2221 fn parse_option_struct_arg_expression(&mut self) -> OptionStructArgExprGreen<'a> {
2224 if self.peek().kind == SyntaxKind::TerminalColon {
2225 let colon = self.take::<TerminalColon<'_>>();
2226 let value = self.parse_expr();
2227 StructArgExpr::new_green(self.db, colon, value).into()
2228 } else {
2229 OptionStructArgExprEmpty::new_green(self.db).into()
2230 }
2231 }
2232
2233 fn parse_option_expression_clause(&mut self) -> OptionExprClauseGreen<'a> {
2236 if self.peek().kind == SyntaxKind::TerminalSemicolon {
2237 OptionExprClauseEmpty::new_green(self.db).into()
2238 } else {
2239 let value = self.parse_expr();
2240 ExprClause::new_green(self.db, value).into()
2241 }
2242 }
2243
2244 fn try_parse_argument_single(&mut self) -> TryParseResult<StructArgSingleGreen<'a>> {
2246 let identifier = self.try_parse_identifier()?;
2247 let struct_arg_expr = self.parse_option_struct_arg_expression(); Ok(StructArgSingle::new_green(self.db, identifier, struct_arg_expr))
2249 }
2250
2251 fn parse_block(&mut self) -> ExprBlockGreen<'a> {
2253 let skipped_tokens = self.skip_until(is_of_kind!(rbrace, lbrace, module_item_kw, block));
2254
2255 if let Err(SkippedError(span)) = skipped_tokens {
2256 self.add_diagnostic(
2257 ParserDiagnosticKind::SkippedElement { element_name: "'{'".into() },
2258 span,
2259 );
2260 }
2261
2262 let is_rbrace_or_top_level = is_of_kind!(rbrace, module_item_kw);
2263 if is_rbrace_or_top_level(self.peek().kind) {
2264 return ExprBlock::new_green(
2265 self.db,
2266 self.create_and_report_missing_terminal::<TerminalLBrace<'_>>(),
2267 StatementList::new_green(self.db, &[]),
2268 TerminalRBrace::missing(self.db),
2269 );
2270 }
2271 let lbrace = self.parse_token_ex::<TerminalLBrace<'_>>(skipped_tokens.is_ok());
2273 let statements = StatementList::new_green(
2274 self.db,
2275 &self.parse_list(
2276 Self::try_parse_statement,
2277 is_of_kind!(rbrace, module_item_kw),
2278 "statement",
2279 ),
2280 );
2281 let rbrace = self.parse_token::<TerminalRBrace<'_>>();
2282 ExprBlock::new_green(self.db, lbrace, statements, rbrace)
2283 }
2284
2285 fn expect_match_expr(&mut self) -> ExprMatchGreen<'a> {
2288 let match_kw = self.take::<TerminalMatch<'_>>();
2289 let expr =
2290 self.parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Forbid, AndLetBehavior::Simple);
2291 let lbrace = self.parse_token::<TerminalLBrace<'_>>();
2292 let arms = MatchArms::new_green(
2293 self.db,
2294 &self
2295 .parse_separated_list::<MatchArm<'_>, TerminalComma<'_>, MatchArmsElementOrSeparatorGreen<'_>>(
2296 Self::try_parse_match_arm,
2297 is_of_kind!(block, rbrace, module_item_kw),
2298 "match arm",
2299 ),
2300 );
2301 let rbrace = self.parse_token::<TerminalRBrace<'_>>();
2302 ExprMatch::new_green(self.db, match_kw, expr, lbrace, arms, rbrace)
2303 }
2304
2305 fn expect_if_expr(&mut self) -> ExprIfGreen<'a> {
2307 let if_kw = self.take::<TerminalIf<'a>>();
2308
2309 let conditions = self.parse_condition_list();
2310 let if_block = self.parse_block();
2311 let else_clause = if self.peek().kind == SyntaxKind::TerminalElse {
2312 let else_kw = self.take::<TerminalElse<'a>>();
2313 let else_block_or_if = if self.peek().kind == SyntaxKind::TerminalIf {
2314 self.expect_if_expr().into()
2315 } else {
2316 self.parse_block().into()
2317 };
2318 ElseClause::new_green(self.db, else_kw, else_block_or_if).into()
2319 } else {
2320 OptionElseClauseEmpty::new_green(self.db).into()
2321 };
2322 ExprIf::new_green(self.db, if_kw, conditions, if_block, else_clause)
2323 }
2324
2325 fn get_binary_operator(&self, condition: ConditionGreen<'_>) -> Option<SyntaxKind> {
2329 let condition_expr_green = condition.0.long(self.db);
2330 require(condition_expr_green.kind == SyntaxKind::ConditionExpr)?;
2331
2332 let expr_binary_green = condition_expr_green.children()[0].long(self.db);
2333 require(expr_binary_green.kind == SyntaxKind::ExprBinary)?;
2334
2335 Some(expr_binary_green.children()[1].long(self.db).kind)
2336 }
2337
2338 fn parse_condition_list(&mut self) -> ConditionListAndGreen<'a> {
2344 let and_and_precedence = get_post_operator_precedence(SyntaxKind::TerminalAndAnd).unwrap();
2345
2346 let start_offset = self.offset.add_width(self.current_width);
2347 let condition = self.parse_condition_expr(false);
2348 let mut conditions: Vec<ConditionListAndElementOrSeparatorGreen<'_>> =
2349 vec![condition.into()];
2350
2351 if self.peek().kind == SyntaxKind::TerminalAndAnd
2354 && let Some(op) = self.get_binary_operator(condition)
2355 && let Some(precedence) = get_post_operator_precedence(op)
2356 && precedence > and_and_precedence
2357 {
2358 let offset = self.offset.add_width(self.current_width - self.last_trivia_length);
2359 self.add_diagnostic(
2360 ParserDiagnosticKind::LowPrecedenceOperatorInIfLet { op },
2361 TextSpan::new(start_offset, offset),
2362 );
2363 }
2364
2365 while self.peek().kind == SyntaxKind::TerminalAndAnd {
2366 let and_and = self.take::<TerminalAndAnd<'a>>();
2367 conditions.push(and_and.into());
2368
2369 let condition = self.parse_condition_expr(true);
2370 conditions.push(condition.into());
2371 }
2372
2373 let peek_item = self.peek();
2374 if let Some(op_precedence) = get_post_operator_precedence(peek_item.kind)
2375 && op_precedence > and_and_precedence
2376 {
2377 self.add_diagnostic(
2378 ParserDiagnosticKind::LowPrecedenceOperatorInIfLet { op: peek_item.kind },
2379 TextSpan::cursor(self.offset.add_width(self.current_width)),
2380 );
2381 let _ = self.skip_until(is_of_kind!(rbrace, lbrace, module_item_kw, block));
2383 }
2384 ConditionListAnd::new_green(self.db, &conditions)
2385 }
2386
2387 fn parse_condition_expr(&mut self, stop_at_and: bool) -> ConditionGreen<'a> {
2393 let and_and_precedence = get_post_operator_precedence(SyntaxKind::TerminalAndAnd).unwrap();
2394 if self.peek().kind == SyntaxKind::TerminalLet {
2395 let let_kw = self.take::<TerminalLet<'a>>();
2396 let pattern_list = self
2397 .parse_separated_list_inner::<Pattern<'_>, TerminalOr<'_>, PatternListOrElementOrSeparatorGreen<'_>>(
2398 Self::try_parse_pattern,
2399 is_of_kind!(eq),
2400 "pattern",
2401 Some(ParserDiagnosticKind::DisallowedTrailingSeparatorOr),
2402 );
2403
2404 let pattern_list_green = if pattern_list.is_empty() {
2405 self.create_and_report_missing::<PatternListOr<'_>>(
2406 ParserDiagnosticKind::MissingPattern,
2407 )
2408 } else {
2409 PatternListOr::new_green(self.db, &pattern_list)
2410 };
2411 let eq = self.parse_token::<TerminalEq<'a>>();
2412 let expr: ExprGreen<'_> = self.parse_expr_limited(
2413 and_and_precedence,
2414 LbraceAllowed::Forbid,
2415 AndLetBehavior::Stop,
2416 );
2417 ConditionLet::new_green(self.db, let_kw, pattern_list_green, eq, expr).into()
2418 } else {
2419 let condition = self.parse_expr_limited(
2420 if stop_at_and { and_and_precedence } else { MAX_PRECEDENCE },
2421 LbraceAllowed::Forbid,
2422 AndLetBehavior::Stop,
2423 );
2424 ConditionExpr::new_green(self.db, condition).into()
2425 }
2426 }
2427
2428 fn expect_loop_expr(&mut self) -> ExprLoopGreen<'a> {
2431 let loop_kw = self.take::<TerminalLoop<'a>>();
2432 let body = self.parse_block();
2433
2434 ExprLoop::new_green(self.db, loop_kw, body)
2435 }
2436
2437 fn expect_while_expr(&mut self) -> ExprWhileGreen<'a> {
2440 let while_kw = self.take::<TerminalWhile<'a>>();
2441 let conditions = self.parse_condition_list();
2442 let body = self.parse_block();
2443
2444 ExprWhile::new_green(self.db, while_kw, conditions, body)
2445 }
2446
2447 fn expect_for_expr(&mut self) -> ExprForGreen<'a> {
2451 let for_kw = self.take::<TerminalFor<'a>>();
2452 let pattern = self.parse_pattern();
2453 let ident = self.take_raw();
2454 let in_identifier: TerminalIdentifierGreen<'_> = match ident.text.long(self.db).as_str() {
2455 "in" => self.add_trivia_to_terminal::<TerminalIdentifier<'_>>(ident),
2456 _ => {
2457 self.append_skipped_token_to_pending_trivia(
2458 ident,
2459 ParserDiagnosticKind::SkippedElement { element_name: "'in'".into() },
2460 );
2461 TerminalIdentifier::missing(self.db)
2462 }
2463 };
2464 let expression =
2465 self.parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Forbid, AndLetBehavior::Simple);
2466 let body = self.parse_block();
2467 ExprFor::new_green(self.db, for_kw, pattern, in_identifier, expression, body)
2468 }
2469
2470 fn expect_closure_expr(&mut self) -> ExprClosureGreen<'a> {
2473 self.unglue::<TerminalOrOr<'_>, TerminalOr<'_>, TerminalOr<'_>>("|", "|");
2474 let leftor = self.take::<TerminalOr<'a>>();
2475 let params = self.parse_closure_param_list();
2476 let rightor = self.parse_token::<TerminalOr<'a>>();
2477 let params = ClosureParams::new_green(self.db, leftor, params, rightor);
2478 let mut block_required = self.peek().kind == SyntaxKind::TerminalArrow;
2479
2480 let return_ty = self.parse_option_return_type_clause();
2481 let optional_no_panic = if self.peek().kind == SyntaxKind::TerminalNoPanic {
2482 block_required = true;
2483 self.take::<TerminalNoPanic<'a>>().into()
2484 } else {
2485 OptionTerminalNoPanicEmpty::new_green(self.db).into()
2486 };
2487 let expr = if block_required { self.parse_block().into() } else { self.parse_expr() };
2488
2489 ExprClosure::new_green(self.db, params, return_ty, optional_no_panic, expr)
2490 }
2491
2492 fn expect_fixed_size_array_expr(&mut self) -> ExprFixedSizeArrayGreen<'a> {
2495 let lbrack = self.take::<TerminalLBrack<'_>>();
2496 let exprs: Vec<ExprListElementOrSeparatorGreen<'_>> = self
2497 .parse_separated_list::<Expr<'_>, TerminalComma<'_>, ExprListElementOrSeparatorGreen<'_>>(
2498 Self::try_parse_expr,
2499 is_of_kind!(rbrack, semicolon),
2500 "expression",
2501 );
2502 let size_green = if self.peek().kind == SyntaxKind::TerminalSemicolon {
2503 let semicolon = self.take::<TerminalSemicolon<'_>>();
2504 let size = self.parse_expr();
2505 FixedSizeArraySize::new_green(self.db, semicolon, size).into()
2506 } else {
2507 OptionFixedSizeArraySizeEmpty::new_green(self.db).into()
2508 };
2509 let rbrack = self.parse_token::<TerminalRBrack<'_>>();
2510 ExprFixedSizeArray::new_green(
2511 self.db,
2512 lbrack,
2513 ExprList::new_green(self.db, &exprs),
2514 size_green,
2515 rbrack,
2516 )
2517 }
2518
2519 pub fn try_parse_match_arm(&mut self) -> TryParseResult<MatchArmGreen<'a>> {
2522 let pattern_list = self
2523 .parse_separated_list_inner::<Pattern<'_>, TerminalOr<'_>, PatternListOrElementOrSeparatorGreen<'_>>(
2524 Self::try_parse_pattern,
2525 is_of_kind!(match_arrow, rparen, block, rbrace, module_item_kw),
2526 "pattern",
2527 Some(ParserDiagnosticKind::DisallowedTrailingSeparatorOr),
2528 );
2529 if pattern_list.is_empty() {
2530 return Err(TryParseFailure::SkipToken);
2531 }
2532
2533 let pattern_list_green = PatternListOr::new_green(self.db, &pattern_list);
2534
2535 let arrow = self.parse_token::<TerminalMatchArrow<'_>>();
2536 let expr = self.parse_expr();
2537 Ok(MatchArm::new_green(self.db, pattern_list_green, arrow, expr))
2538 }
2539
2540 fn try_parse_pattern(&mut self) -> TryParseResult<PatternGreen<'a>> {
2543 let modifier_list = self.parse_modifier_list();
2544 if !modifier_list.is_empty() {
2545 let modifiers = ModifierList::new_green(self.db, &modifier_list);
2546 let name = self.parse_identifier();
2547 return Ok(PatternIdentifier::new_green(self.db, modifiers, name).into());
2548 };
2549
2550 Ok(match self.peek().kind {
2552 SyntaxKind::TerminalLiteralNumber => self.take_terminal_literal_number().into(),
2553 SyntaxKind::TerminalShortString => self.take_terminal_short_string().into(),
2554 SyntaxKind::TerminalTrue => self.take::<TerminalTrue<'_>>().into(),
2555 SyntaxKind::TerminalFalse => self.take::<TerminalFalse<'_>>().into(),
2556 SyntaxKind::TerminalUnderscore => self.take::<TerminalUnderscore<'_>>().into(),
2557 SyntaxKind::TerminalIdentifier | SyntaxKind::TerminalDollar => {
2558 let path = self.parse_path();
2561 match self.peek().kind {
2562 SyntaxKind::TerminalLBrace => {
2563 let lbrace = self.take::<TerminalLBrace<'_>>();
2564 let params = PatternStructParamList::new_green(
2565 self.db,
2566 &self.parse_separated_list::<
2567 PatternStructParam<'_>,
2568 TerminalComma<'_>,
2569 PatternStructParamListElementOrSeparatorGreen<'_>>
2570 (
2571 Self::try_parse_pattern_struct_param,
2572 is_of_kind!(rparen, block, rbrace, module_item_kw),
2573 "struct pattern parameter",
2574 ),
2575 );
2576 let rbrace = self.parse_token::<TerminalRBrace<'_>>();
2577 PatternStruct::new_green(self.db, path, lbrace, params, rbrace).into()
2578 }
2579 SyntaxKind::TerminalLParen => {
2580 let lparen = self.take::<TerminalLParen<'_>>();
2582 let pattern = self.parse_pattern();
2583 let rparen = self.parse_token::<TerminalRParen<'_>>();
2584 let inner_pattern =
2585 PatternEnumInnerPattern::new_green(self.db, lparen, pattern, rparen);
2586 PatternEnum::new_green(self.db, path, inner_pattern.into()).into()
2587 }
2588 _ => {
2589 let GreenNode {
2591 kind: SyntaxKind::ExprPath,
2592 details: GreenNodeDetails::Node { children: path_children, .. },
2593 } = path.0.long(self.db)
2594 else {
2595 return Err(TryParseFailure::SkipToken);
2596 };
2597
2598 let [_dollar, path_inner] = path_children[..] else {
2600 return Err(TryParseFailure::SkipToken);
2601 };
2602
2603 let GreenNode {
2604 kind: SyntaxKind::ExprPathInner,
2605 details: GreenNodeDetails::Node { children: inner_path_children, .. },
2606 } = path_inner.long(self.db)
2607 else {
2608 return Err(TryParseFailure::SkipToken);
2609 };
2610
2611 match inner_path_children.len() {
2616 1 => path.into(),
2618 _ => PatternEnum::new_green(
2619 self.db,
2620 path,
2621 OptionPatternEnumInnerPatternEmpty::new_green(self.db).into(),
2622 )
2623 .into(),
2624 }
2625 }
2626 }
2627 }
2628 SyntaxKind::TerminalLParen => {
2629 let lparen = self.take::<TerminalLParen<'_>>();
2630 let patterns = PatternList::new_green(self.db, &self.parse_separated_list::<
2631 Pattern<'_>,
2632 TerminalComma<'_>,
2633 PatternListElementOrSeparatorGreen<'_>>
2634 (
2635 Self::try_parse_pattern,
2636 is_of_kind!(rparen, block, rbrace, module_item_kw),
2637 "pattern",
2638 ));
2639 let rparen = self.parse_token::<TerminalRParen<'_>>();
2640 PatternTuple::new_green(self.db, lparen, patterns, rparen).into()
2641 }
2642 SyntaxKind::TerminalLBrack => {
2643 let lbrack = self.take::<TerminalLBrack<'_>>();
2644 let patterns = PatternList::new_green(self.db, &self.parse_separated_list::<
2645 Pattern<'_>,
2646 TerminalComma<'_>,
2647 PatternListElementOrSeparatorGreen<'_>>
2648 (
2649 Self::try_parse_pattern,
2650 is_of_kind!(rbrack, block, rbrace, module_item_kw),
2651 "pattern",
2652 ));
2653 let rbrack = self.parse_token::<TerminalRBrack<'_>>();
2654 PatternFixedSizeArray::new_green(self.db, lbrack, patterns, rbrack).into()
2655 }
2656 _ => return Err(TryParseFailure::SkipToken),
2657 })
2658 }
2659 fn parse_pattern(&mut self) -> PatternGreen<'a> {
2662 match self.try_parse_pattern() {
2664 Ok(pattern) => pattern,
2665 Err(_) => self.create_and_report_missing_terminal::<TerminalUnderscore<'_>>().into(),
2666 }
2667 }
2668
2669 fn try_parse_pattern_struct_param(&mut self) -> TryParseResult<PatternStructParamGreen<'a>> {
2672 Ok(match self.peek().kind {
2673 SyntaxKind::TerminalDotDot => self.take::<TerminalDotDot<'_>>().into(),
2674 _ => {
2675 let modifier_list = self.parse_modifier_list();
2676 let name = if modifier_list.is_empty() {
2677 self.try_parse_identifier()?
2678 } else {
2679 self.parse_identifier()
2680 };
2681 let modifiers = ModifierList::new_green(self.db, &modifier_list);
2682 if self.peek().kind == SyntaxKind::TerminalColon {
2683 let colon = self.take::<TerminalColon<'_>>();
2684 let pattern = self.parse_pattern();
2685 PatternStructParamWithExpr::new_green(self.db, modifiers, name, colon, pattern)
2686 .into()
2687 } else {
2688 PatternIdentifier::new_green(self.db, modifiers, name).into()
2689 }
2690 }
2691 })
2692 }
2693
2694 pub fn try_parse_statement(&mut self) -> TryParseResult<StatementGreen<'a>> {
2699 let maybe_attributes = self.try_parse_attribute_list("Statement");
2700 let (has_attrs, attributes) = match maybe_attributes {
2701 Ok(attributes) => (true, attributes),
2702 Err(_) => (false, AttributeList::new_green(self.db, &[])),
2703 };
2704 match self.peek().kind {
2705 SyntaxKind::TerminalLet => {
2706 let let_kw = self.take::<TerminalLet<'_>>();
2707 let pattern = self.parse_pattern();
2708 let type_clause = self.parse_option_type_clause();
2709 let eq = self.parse_token::<TerminalEq<'_>>();
2710 let rhs = self.parse_expr();
2711
2712 let let_else_clause: OptionLetElseClauseGreen<'_> =
2714 if self.peek().kind == SyntaxKind::TerminalElse {
2715 let else_kw = self.take::<TerminalElse<'_>>();
2716 let else_block = self.parse_block();
2717 LetElseClause::new_green(self.db, else_kw, else_block).into()
2718 } else {
2719 OptionLetElseClauseEmpty::new_green(self.db).into()
2720 };
2721
2722 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
2723 Ok(StatementLet::new_green(
2724 self.db,
2725 attributes,
2726 let_kw,
2727 pattern,
2728 type_clause,
2729 eq,
2730 rhs,
2731 let_else_clause,
2732 semicolon,
2733 )
2734 .into())
2735 }
2736 SyntaxKind::TerminalContinue => {
2737 let continue_kw = self.take::<TerminalContinue<'_>>();
2738 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
2739 Ok(StatementContinue::new_green(self.db, attributes, continue_kw, semicolon).into())
2740 }
2741 SyntaxKind::TerminalReturn => {
2742 let return_kw = self.take::<TerminalReturn<'_>>();
2743 let expr = self.parse_option_expression_clause();
2744 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
2745 Ok(StatementReturn::new_green(self.db, attributes, return_kw, expr, semicolon)
2746 .into())
2747 }
2748 SyntaxKind::TerminalBreak => {
2749 let break_kw = self.take::<TerminalBreak<'_>>();
2750 let expr = self.parse_option_expression_clause();
2751 let semicolon = self.parse_token::<TerminalSemicolon<'_>>();
2752 Ok(StatementBreak::new_green(self.db, attributes, break_kw, expr, semicolon).into())
2753 }
2754 SyntaxKind::TerminalConst => {
2755 let const_kw = self.take::<TerminalConst<'_>>();
2756 Ok(StatementItem::new_green(
2757 self.db,
2758 self.expect_item_const(
2759 attributes,
2760 VisibilityDefault::new_green(self.db).into(),
2761 const_kw,
2762 )
2763 .into(),
2764 )
2765 .into())
2766 }
2767 SyntaxKind::TerminalUse => Ok(StatementItem::new_green(
2768 self.db,
2769 self.expect_item_use(attributes, VisibilityDefault::new_green(self.db).into())
2770 .into(),
2771 )
2772 .into()),
2773 SyntaxKind::TerminalType => Ok(StatementItem::new_green(
2774 self.db,
2775 self.expect_item_type_alias(
2776 attributes,
2777 VisibilityDefault::new_green(self.db).into(),
2778 )
2779 .into(),
2780 )
2781 .into()),
2782 _ => match self.try_parse_expr() {
2783 Ok(expr) => {
2784 let optional_semicolon = if self.peek().kind == SyntaxKind::TerminalSemicolon {
2785 self.take::<TerminalSemicolon<'_>>().into()
2786 } else {
2787 OptionTerminalSemicolonEmpty::new_green(self.db).into()
2788 };
2789 Ok(StatementExpr::new_green(self.db, attributes, expr, optional_semicolon)
2790 .into())
2791 }
2792 Err(_) if has_attrs => Ok(self
2793 .skip_taken_node_and_return_missing::<Statement<'_>>(
2794 attributes,
2795 ParserDiagnosticKind::AttributesWithoutStatement,
2796 )),
2797 Err(err) => Err(err),
2798 },
2799 }
2800 }
2801
2802 fn parse_option_type_clause(&mut self) -> OptionTypeClauseGreen<'a> {
2805 match self.try_parse_type_clause() {
2806 Some(green) => green.into(),
2807 None => OptionTypeClauseEmpty::new_green(self.db).into(),
2808 }
2809 }
2810
2811 fn parse_type_clause(&mut self, error_recovery: ErrorRecovery) -> TypeClauseGreen<'a> {
2813 match self.try_parse_type_clause() {
2814 Some(green) => green,
2815 None => {
2816 let res = self.create_and_report_missing::<TypeClause<'_>>(
2817 ParserDiagnosticKind::MissingTypeClause,
2818 );
2819 self.skip_until(error_recovery.should_stop).ok();
2820 res
2821 }
2822 }
2823 }
2824 fn try_parse_type_clause(&mut self) -> Option<TypeClauseGreen<'a>> {
2825 if self.peek().kind == SyntaxKind::TerminalColon {
2826 let colon = self.take::<TerminalColon<'_>>();
2827 let ty = self.parse_type_expr();
2828 Some(TypeClause::new_green(self.db, colon, ty))
2829 } else {
2830 None
2831 }
2832 }
2833
2834 fn parse_option_return_type_clause(&mut self) -> OptionReturnTypeClauseGreen<'a> {
2837 if self.peek().kind == SyntaxKind::TerminalArrow {
2838 let arrow = self.take::<TerminalArrow<'_>>();
2839 let return_type = self.parse_type_expr();
2840 ReturnTypeClause::new_green(self.db, arrow, return_type).into()
2841 } else {
2842 OptionReturnTypeClauseEmpty::new_green(self.db).into()
2843 }
2844 }
2845
2846 fn parse_option_implicits_clause(&mut self) -> OptionImplicitsClauseGreen<'a> {
2849 if self.peek().kind == SyntaxKind::TerminalImplicits {
2850 let implicits_kw = self.take::<TerminalImplicits<'_>>();
2851 let lparen = self.parse_token::<TerminalLParen<'_>>();
2852 let implicits = ImplicitsList::new_green(
2853 self.db,
2854 &self.parse_separated_list::<ExprPath<'_>, TerminalComma<'_>, ImplicitsListElementOrSeparatorGreen<'_>>(
2855 Self::try_parse_path,
2856 is_of_kind!(rparen, lbrace, rbrace),
2858 "implicit type",
2859 ),
2860 );
2861 let rparen = self.parse_token::<TerminalRParen<'_>>();
2862 ImplicitsClause::new_green(self.db, implicits_kw, lparen, implicits, rparen).into()
2863 } else {
2864 OptionImplicitsClauseEmpty::new_green(self.db).into()
2865 }
2866 }
2867
2868 fn parse_param_list(&mut self) -> ParamListGreen<'a> {
2870 ParamList::new_green(
2871 self.db,
2872 &self.parse_separated_list::<Param<'_>, TerminalComma<'_>, ParamListElementOrSeparatorGreen<'_>>(
2873 Self::try_parse_param,
2874 is_of_kind!(rparen, block, lbrace, rbrace, module_item_kw),
2875 "parameter",
2876 ),
2877 )
2878 }
2879
2880 fn parse_closure_param_list(&mut self) -> ParamListGreen<'a> {
2882 ParamList::new_green(
2883 self.db,
2884 &self.parse_separated_list::<Param<'_>, TerminalComma<'_>, ParamListElementOrSeparatorGreen<'_>>(
2885 Self::try_parse_closure_param,
2886 is_of_kind!(or, block, lbrace, rbrace, module_item_kw),
2887 "parameter",
2888 ),
2889 )
2890 }
2891
2892 fn try_parse_modifier(&mut self) -> Option<ModifierGreen<'a>> {
2895 match self.peek().kind {
2896 SyntaxKind::TerminalRef => Some(self.take::<TerminalRef<'_>>().into()),
2897 SyntaxKind::TerminalMut => Some(self.take::<TerminalMut<'_>>().into()),
2898 _ => None,
2899 }
2900 }
2901
2902 fn parse_modifier_list(&mut self) -> Vec<ModifierGreen<'a>> {
2904 let mut modifier_list = vec![];
2905
2906 while let Some(modifier) = self.try_parse_modifier() {
2907 modifier_list.push(modifier);
2908 }
2909 modifier_list
2910 }
2911
2912 fn try_parse_param(&mut self) -> TryParseResult<ParamGreen<'a>> {
2915 let modifier_list = self.parse_modifier_list();
2916 let name = if modifier_list.is_empty() {
2917 self.try_parse_identifier()?
2918 } else {
2919 self.parse_identifier()
2921 };
2922
2923 let type_clause = self
2924 .parse_type_clause(ErrorRecovery {
2925 should_stop: is_of_kind!(comma, rparen, module_item_kw),
2926 })
2927 .into();
2928 Ok(Param::new_green(
2929 self.db,
2930 ModifierList::new_green(self.db, &modifier_list),
2931 name,
2932 type_clause,
2933 ))
2934 }
2935
2936 fn try_parse_closure_param(&mut self) -> TryParseResult<ParamGreen<'a>> {
2939 let modifier_list = self.parse_modifier_list();
2940 let name = if modifier_list.is_empty() {
2941 self.try_parse_identifier()?
2942 } else {
2943 self.parse_identifier()
2945 };
2946
2947 let type_clause = self.parse_option_type_clause();
2948 Ok(Param::new_green(
2949 self.db,
2950 ModifierList::new_green(self.db, &modifier_list),
2951 name,
2952 type_clause,
2953 ))
2954 }
2955
2956 fn parse_member_list(&mut self) -> MemberListGreen<'a> {
2958 MemberList::new_green(
2959 self.db,
2960 &self.parse_separated_list::<
2961 Member<'_>,
2962 TerminalComma<'_>,
2963 MemberListElementOrSeparatorGreen<'_>,
2964 >(
2965 Self::try_parse_member,
2966 is_of_kind!(rparen, block, lbrace, rbrace, module_item_kw),
2967 "member or variant",
2968 ),
2969 )
2970 }
2971
2972 fn try_parse_member(&mut self) -> TryParseResult<MemberGreen<'a>> {
2975 let attributes = self.try_parse_attribute_list("Struct member");
2976 let visibility = self.parse_visibility();
2977 let (name, attributes) = match attributes {
2978 Ok(attributes) => (self.parse_identifier(), attributes),
2979 Err(_) => (self.try_parse_identifier()?, AttributeList::new_green(self.db, &[])),
2980 };
2981 let type_clause = self.parse_type_clause(ErrorRecovery {
2982 should_stop: is_of_kind!(comma, rbrace, module_item_kw),
2983 });
2984 Ok(Member::new_green(self.db, attributes, visibility, name, type_clause))
2985 }
2986
2987 fn parse_variant_list(&mut self) -> VariantListGreen<'a> {
2989 VariantList::new_green(
2990 self.db,
2991 &self
2992 .parse_separated_list::<Variant<'_>, TerminalComma<'_>, VariantListElementOrSeparatorGreen<'_>>(
2993 Self::try_parse_variant,
2994 is_of_kind!(rparen, block, lbrace, rbrace, module_item_kw),
2995 "variant",
2996 ),
2997 )
2998 }
2999
3000 fn try_parse_variant(&mut self) -> TryParseResult<VariantGreen<'a>> {
3003 let attributes = self.try_parse_attribute_list("Enum variant");
3004 let (name, attributes) = match attributes {
3005 Ok(attributes) => (self.parse_identifier(), attributes),
3006 Err(_) => (self.try_parse_identifier()?, AttributeList::new_green(self.db, &[])),
3007 };
3008
3009 let type_clause = self.parse_option_type_clause();
3010 Ok(Variant::new_green(self.db, attributes, name, type_clause))
3011 }
3012
3013 fn parse_path(&mut self) -> ExprPathGreen<'a> {
3016 let dollar = match self.peek().kind {
3017 SyntaxKind::TerminalDollar => self.take::<TerminalDollar<'_>>().into(),
3018 _ => OptionTerminalDollarEmpty::new_green(self.db).into(),
3019 };
3020
3021 let mut children: Vec<ExprPathInnerElementOrSeparatorGreen<'_>> = vec![];
3022 loop {
3023 let (segment, optional_separator) = self.parse_path_segment();
3024 children.push(segment.into());
3025
3026 if let Some(separator) = optional_separator {
3027 children.push(separator.into());
3028 continue;
3029 }
3030 break;
3031 }
3032
3033 ExprPath::new_green(self.db, dollar, ExprPathInner::new_green(self.db, &children))
3034 }
3035 fn try_parse_path(&mut self) -> TryParseResult<ExprPathGreen<'a>> {
3037 if self.is_peek_identifier_like() {
3038 Ok(self.parse_path())
3039 } else {
3040 Err(TryParseFailure::SkipToken)
3041 }
3042 }
3043
3044 fn parse_type_path(&mut self) -> ExprPathGreen<'a> {
3048 let dollar = match self.peek().kind {
3049 SyntaxKind::TerminalDollar => self.take::<TerminalDollar<'_>>().into(),
3050 _ => OptionTerminalDollarEmpty::new_green(self.db).into(),
3051 };
3052
3053 let mut children: Vec<ExprPathInnerElementOrSeparatorGreen<'_>> = vec![];
3054 loop {
3055 let (segment, optional_separator) = self.parse_type_path_segment();
3056 children.push(segment.into());
3057
3058 if let Some(separator) = optional_separator {
3059 children.push(separator.into());
3060 continue;
3061 }
3062 break;
3063 }
3064
3065 ExprPath::new_green(self.db, dollar, ExprPathInner::new_green(self.db, &children))
3066 }
3067
3068 fn parse_path_segment(
3070 &mut self,
3071 ) -> (PathSegmentGreen<'a>, Option<TerminalColonColonGreen<'a>>) {
3072 let identifier = match self.try_parse_identifier() {
3073 Ok(identifier) => identifier,
3074 Err(_) => {
3075 return (
3076 self.create_and_report_missing::<PathSegment<'_>>(
3077 ParserDiagnosticKind::MissingPathSegment,
3078 ),
3079 None,
3080 );
3081 }
3082 };
3083 match self.try_parse_token::<TerminalColonColon<'_>>() {
3084 Ok(separator) if self.peek().kind == SyntaxKind::TerminalLT => (
3085 PathSegmentWithGenericArgs::new_green(
3086 self.db,
3087 identifier,
3088 separator.into(),
3089 self.expect_generic_args(),
3090 )
3091 .into(),
3092 self.try_parse_token::<TerminalColonColon<'_>>().ok(),
3093 ),
3094 optional_separator => {
3095 (PathSegmentSimple::new_green(self.db, identifier).into(), optional_separator.ok())
3096 }
3097 }
3098 }
3099
3100 fn parse_type_path_segment(
3103 &mut self,
3104 ) -> (PathSegmentGreen<'a>, Option<TerminalColonColonGreen<'a>>) {
3105 let identifier = match self.try_parse_identifier() {
3106 Ok(identifier) => identifier,
3107 Err(_) => {
3108 return (
3109 self.create_and_report_missing::<PathSegment<'_>>(
3110 ParserDiagnosticKind::MissingPathSegment,
3111 ),
3112 None,
3113 );
3114 }
3115 };
3116 match self.try_parse_token::<TerminalColonColon<'_>>() {
3117 Err(_) if self.peek().kind == SyntaxKind::TerminalLT => (
3118 PathSegmentWithGenericArgs::new_green(
3119 self.db,
3120 identifier,
3121 OptionTerminalColonColonEmpty::new_green(self.db).into(),
3122 self.expect_generic_args(),
3123 )
3124 .into(),
3125 None,
3126 ),
3127 Ok(separator) if self.peek().kind == SyntaxKind::TerminalLT => (
3130 PathSegmentWithGenericArgs::new_green(
3131 self.db,
3132 identifier,
3133 separator.into(),
3134 self.expect_generic_args(),
3135 )
3136 .into(),
3137 self.try_parse_token::<TerminalColonColon<'_>>().ok(),
3138 ),
3139 optional_separator => {
3140 (PathSegmentSimple::new_green(self.db, identifier).into(), optional_separator.ok())
3141 }
3142 }
3143 }
3144
3145 fn take_terminal_literal_number(&mut self) -> TerminalLiteralNumberGreen<'a> {
3147 let diag = validate_literal_number(self.peek().text.long(self.db));
3148 let green = self.take::<TerminalLiteralNumber<'_>>();
3149 self.add_optional_diagnostic(diag);
3150 green
3151 }
3152
3153 fn take_terminal_short_string(&mut self) -> TerminalShortStringGreen<'a> {
3155 let diag = validate_short_string(self.peek().text.long(self.db));
3156 let green = self.take::<TerminalShortString<'_>>();
3157 self.add_optional_diagnostic(diag);
3158 green
3159 }
3160
3161 fn take_terminal_string(&mut self) -> TerminalStringGreen<'a> {
3163 let diag = validate_string(self.peek().text.long(self.db));
3164 let green = self.take::<TerminalString<'_>>();
3165 self.add_optional_diagnostic(diag);
3166 green
3167 }
3168
3169 fn add_optional_diagnostic(&mut self, err: Option<ValidationError>) {
3171 if let Some(err) = err {
3172 let span = match err.location {
3173 ValidationLocation::Full => {
3174 TextSpan::new_with_width(self.offset, self.current_width)
3175 }
3176 ValidationLocation::After => {
3177 TextSpan::cursor(self.offset.add_width(self.current_width))
3178 }
3179 ValidationLocation::Cursor(offset) => {
3180 TextSpan::cursor(self.offset.add_width(offset))
3181 }
3182 };
3183 self.add_diagnostic(err.kind, span);
3184 }
3185 }
3186
3187 fn try_parse_generic_arg(&mut self) -> TryParseResult<GenericArgGreen<'a>> {
3191 let expr = match self.peek().kind {
3192 SyntaxKind::TerminalLiteralNumber => self.take_terminal_literal_number().into(),
3193 SyntaxKind::TerminalMinus => {
3194 let op = self.take::<TerminalMinus<'_>>().into();
3195 let expr = self.parse_token::<TerminalLiteralNumber<'_>>().into();
3196 ExprUnary::new_green(self.db, op, expr).into()
3197 }
3198 SyntaxKind::TerminalShortString => self.take_terminal_short_string().into(),
3199 SyntaxKind::TerminalTrue => self.take::<TerminalTrue<'_>>().into(),
3200 SyntaxKind::TerminalFalse => self.take::<TerminalFalse<'_>>().into(),
3201 SyntaxKind::TerminalLBrace => self.parse_block().into(),
3202 _ => self.try_parse_type_expr()?,
3203 };
3204
3205 if self.peek().kind == SyntaxKind::TerminalColon
3208 && let Some(argname) = self.try_extract_identifier(expr)
3209 {
3210 let colon = self.take::<TerminalColon<'_>>();
3211 let expr = self.parse_type_expr();
3212 return Ok(GenericArgNamed::new_green(self.db, argname, colon, expr).into());
3213 }
3214 Ok(GenericArgUnnamed::new_green(self.db, expr).into())
3215 }
3216
3217 fn expect_generic_args(&mut self) -> GenericArgsGreen<'a> {
3220 let langle = self.take::<TerminalLT<'_>>();
3221 let generic_args = GenericArgList::new_green(
3222 self.db,
3223 &self.parse_separated_list::<GenericArg<'_>, TerminalComma<'_>, GenericArgListElementOrSeparatorGreen<'_>>(
3224 Self::try_parse_generic_arg,
3225 is_of_kind!(rangle, rparen, block, lbrace, rbrace, module_item_kw),
3226 "generic arg",
3227 ),
3228 );
3229 self.unglue::<TerminalGE<'_>, TerminalGT<'_>, TerminalEq<'_>>(">", "=");
3230 let rangle = self.parse_token::<TerminalGT<'_>>();
3231 GenericArgs::new_green(self.db, langle, generic_args, rangle)
3232 }
3233
3234 fn expect_generic_params(&mut self) -> WrappedGenericParamListGreen<'a> {
3237 let langle = self.take::<TerminalLT<'_>>();
3238 let generic_params = GenericParamList::new_green(
3239 self.db,
3240 &self.parse_separated_list::<GenericParam<'_>, TerminalComma<'_>, GenericParamListElementOrSeparatorGreen<'_>>(
3241 Self::try_parse_generic_param,
3242 is_of_kind!(rangle, rparen, block, lbrace, rbrace, module_item_kw),
3243 "generic param",
3244 ),
3245 );
3246 let rangle = self.parse_token::<TerminalGT<'_>>();
3247 WrappedGenericParamList::new_green(self.db, langle, generic_params, rangle)
3248 }
3249
3250 fn parse_optional_generic_params(&mut self) -> OptionWrappedGenericParamListGreen<'a> {
3251 if self.peek().kind != SyntaxKind::TerminalLT {
3252 return OptionWrappedGenericParamListEmpty::new_green(self.db).into();
3253 }
3254 self.expect_generic_params().into()
3255 }
3256
3257 fn try_parse_generic_param(&mut self) -> TryParseResult<GenericParamGreen<'a>> {
3258 match self.peek().kind {
3259 SyntaxKind::TerminalConst => {
3260 let const_kw = self.take::<TerminalConst<'_>>();
3261 let name = self.parse_identifier();
3262 let colon = self.parse_token::<TerminalColon<'_>>();
3263 let ty = self.parse_type_expr();
3264 Ok(GenericParamConst::new_green(self.db, const_kw, name, colon, ty).into())
3265 }
3266 SyntaxKind::TerminalImpl => {
3267 let impl_kw = self.take::<TerminalImpl<'_>>();
3268 let name = self.parse_identifier();
3269 let colon = self.parse_token::<TerminalColon<'_>>();
3270 let trait_path = self.parse_type_path();
3271 let associated_item_constraints = self.parse_optional_associated_item_constraints();
3272 Ok(GenericParamImplNamed::new_green(
3273 self.db,
3274 impl_kw,
3275 name,
3276 colon,
3277 trait_path,
3278 associated_item_constraints,
3279 )
3280 .into())
3281 }
3282 SyntaxKind::TerminalPlus => {
3283 let plus = self.take::<TerminalPlus<'_>>();
3284 let trait_path = self.parse_type_path();
3285 let associated_item_constraints = self.parse_optional_associated_item_constraints();
3286 Ok(GenericParamImplAnonymous::new_green(
3287 self.db,
3288 plus,
3289 trait_path,
3290 associated_item_constraints,
3291 )
3292 .into())
3293 }
3294 SyntaxKind::TerminalMinus => {
3295 let minus = self.take::<TerminalMinus<'_>>();
3296 let trait_path = self.parse_type_path();
3297 Ok(GenericParamNegativeImpl::new_green(self.db, minus, trait_path).into())
3298 }
3299 _ => Ok(GenericParamType::new_green(self.db, self.try_parse_identifier()?).into()),
3300 }
3301 }
3302
3303 fn expect_associated_item_constraints(&mut self) -> AssociatedItemConstraintsGreen<'a> {
3306 let lbrack = self.take::<TerminalLBrack<'_>>();
3307 let associated_item_constraints_list = AssociatedItemConstraintList::new_green(
3308 self.db,
3309 &self.parse_separated_list::<AssociatedItemConstraint<'_>, TerminalComma<'_>, AssociatedItemConstraintListElementOrSeparatorGreen<'_>>(
3310 Self::try_parse_associated_item_constraint,
3311 is_of_kind!(rbrack,rangle, rparen, block, lbrace, rbrace, module_item_kw),
3312 "associated type argument",
3313 ),
3314 );
3315 let rangle = self.parse_token::<TerminalRBrack<'_>>();
3316 AssociatedItemConstraints::new_green(
3317 self.db,
3318 lbrack,
3319 associated_item_constraints_list,
3320 rangle,
3321 )
3322 }
3323
3324 fn parse_optional_associated_item_constraints(
3325 &mut self,
3326 ) -> OptionAssociatedItemConstraintsGreen<'a> {
3327 if self.peek().kind != SyntaxKind::TerminalLBrack {
3328 return OptionAssociatedItemConstraintsEmpty::new_green(self.db).into();
3329 }
3330 self.expect_associated_item_constraints().into()
3331 }
3332
3333 fn try_parse_associated_item_constraint(
3336 &mut self,
3337 ) -> TryParseResult<AssociatedItemConstraintGreen<'a>> {
3338 let ident = self.try_parse_identifier()?;
3339 let colon = self.parse_token::<TerminalColon<'_>>();
3340 let ty = self.parse_type_expr();
3341 Ok(AssociatedItemConstraint::new_green(self.db, ident, colon, ty))
3342 }
3343
3344 fn parse_list<ElementGreen>(
3356 &mut self,
3357 try_parse_list_element: fn(&mut Self) -> TryParseResult<ElementGreen>,
3358 should_stop: fn(SyntaxKind) -> bool,
3359 expected_element: &str,
3360 ) -> Vec<ElementGreen> {
3361 let mut children: Vec<ElementGreen> = Vec::new();
3362 loop {
3363 let parse_result = try_parse_list_element(self);
3364 match parse_result {
3365 Ok(element_green) => {
3366 children.push(element_green);
3367 }
3368 Err(err) => {
3369 if should_stop(self.peek().kind) {
3370 break;
3371 }
3372 if err == TryParseFailure::SkipToken {
3373 self.skip_token(ParserDiagnosticKind::SkippedElement {
3374 element_name: expected_element.into(),
3375 });
3376 }
3377 }
3378 }
3379 }
3380 children
3381 }
3382
3383 fn parse_attributed_list<ElementGreen>(
3394 &mut self,
3395 try_parse_list_element: fn(&mut Self) -> TryParseResult<ElementGreen>,
3396 should_stop: fn(SyntaxKind) -> bool,
3397 expected_element: &'a str,
3398 ) -> Vec<ElementGreen> {
3399 self.parse_list::<ElementGreen>(
3400 try_parse_list_element,
3401 should_stop,
3402 &or_an_attribute!(expected_element),
3403 )
3404 }
3405
3406 fn parse_separated_list_inner<
3423 Element: TypedSyntaxNode<'a>,
3424 Separator: syntax::node::Terminal<'a>,
3425 ElementOrSeparatorGreen,
3426 >(
3427 &mut self,
3428 try_parse_list_element: fn(&mut Self) -> TryParseResult<Element::Green>,
3429 should_stop: fn(SyntaxKind) -> bool,
3430 expected_element: &'static str,
3431 forbid_trailing_separator: Option<ParserDiagnosticKind>,
3432 ) -> Vec<ElementOrSeparatorGreen>
3433 where
3434 ElementOrSeparatorGreen: From<Separator::Green> + From<Element::Green>,
3435 {
3436 let mut children: Vec<ElementOrSeparatorGreen> = Vec::new();
3437 loop {
3438 match try_parse_list_element(self) {
3439 Err(_) if should_stop(self.peek().kind) => {
3440 if let (Some(diagnostic_kind), true) =
3441 (forbid_trailing_separator, !children.is_empty())
3442 {
3443 self.add_diagnostic(diagnostic_kind, TextSpan::cursor(self.offset));
3444 }
3445 break;
3446 }
3447 Err(_) => {
3448 self.skip_token(ParserDiagnosticKind::SkippedElement {
3449 element_name: expected_element.into(),
3450 });
3451 continue;
3452 }
3453 Ok(element) => {
3454 children.push(element.into());
3455 }
3456 };
3457
3458 let separator = match self.try_parse_token::<Separator>() {
3459 Err(_) if should_stop(self.peek().kind) => {
3460 break;
3461 }
3462 Err(_) => self.create_and_report_missing::<Separator>(
3463 ParserDiagnosticKind::MissingToken(Separator::KIND),
3464 ),
3465 Ok(separator) => separator,
3466 };
3467 children.push(separator.into());
3468 }
3469 children
3470 }
3471 fn parse_separated_list<
3473 Element: TypedSyntaxNode<'a>,
3474 Separator: syntax::node::Terminal<'a>,
3475 ElementOrSeparatorGreen,
3476 >(
3477 &mut self,
3478 try_parse_list_element: fn(&mut Self) -> TryParseResult<Element::Green>,
3479 should_stop: fn(SyntaxKind) -> bool,
3480 expected_element: &'static str,
3481 ) -> Vec<ElementOrSeparatorGreen>
3482 where
3483 ElementOrSeparatorGreen: From<Separator::Green> + From<Element::Green>,
3484 {
3485 self.parse_separated_list_inner::<Element, Separator, ElementOrSeparatorGreen>(
3486 try_parse_list_element,
3487 should_stop,
3488 expected_element,
3489 None,
3490 )
3491 }
3492
3493 pub fn peek(&self) -> &LexerTerminal<'a> {
3495 self.next_terminal()
3496 }
3497
3498 pub fn peek_next_next_kind(&mut self) -> SyntaxKind {
3501 self.next_next_terminal().kind
3502 }
3503
3504 fn unglue_andand_for_unary(&mut self) {
3507 self.unglue::<TerminalAndAnd<'_>, TerminalAnd<'_>, TerminalAnd<'_>>("&", "&");
3508 }
3509
3510 fn unglue<
3514 Original: syntax::node::Terminal<'a>,
3515 First: syntax::node::Terminal<'a>,
3516 Second: syntax::node::Terminal<'a>,
3517 >(
3518 &mut self,
3519 first: &'static str,
3520 second: &'static str,
3521 ) {
3522 if self.peek().kind != Original::KIND {
3523 return;
3524 }
3525 let orig = self.advance();
3527 self.terminals.push_front(LexerTerminal {
3529 text: SmolStrId::from(self.db, second),
3530 kind: Second::KIND,
3531 leading_trivia: vec![],
3532 trailing_trivia: orig.trailing_trivia,
3533 });
3534 self.terminals.push_front(LexerTerminal {
3536 text: SmolStrId::from(self.db, first),
3537 kind: First::KIND,
3538 leading_trivia: orig.leading_trivia,
3539 trailing_trivia: vec![],
3540 });
3541 }
3542
3543 fn take_raw(&mut self) -> LexerTerminal<'a> {
3545 self.offset = self.offset.add_width(self.current_width);
3546 self.current_width = self.next_terminal().width(self.db);
3547 self.last_trivia_length =
3548 trivia_total_width(self.db, &self.next_terminal().trailing_trivia);
3549 self.advance()
3550 }
3551
3552 fn skip_token(&mut self, diagnostic_kind: ParserDiagnosticKind) {
3556 if self.peek().kind == SyntaxKind::TerminalEndOfFile {
3557 self.add_diagnostic(diagnostic_kind, TextSpan::cursor(self.offset));
3558 return;
3559 }
3560 let terminal = self.take_raw();
3561 self.append_skipped_token_to_pending_trivia(terminal, diagnostic_kind);
3562 }
3563
3564 fn append_skipped_token_to_pending_trivia(
3567 &mut self,
3568 terminal: LexerTerminal<'a>,
3569 diagnostic_kind: ParserDiagnosticKind,
3570 ) {
3571 let orig_offset = self.offset;
3572 let diag_start =
3573 self.offset.add_width(trivia_total_width(self.db, &terminal.leading_trivia));
3574 let diag_end = diag_start.add_width(TextWidth::from_str(terminal.text.long(self.db)));
3575
3576 self.pending_trivia.extend(terminal.leading_trivia);
3578 self.pending_trivia.push(TokenSkipped::new_green(self.db, terminal.text).into());
3579 let trailing_trivia_width = trivia_total_width(self.db, &terminal.trailing_trivia);
3580 self.pending_trivia.extend(terminal.trailing_trivia);
3581 self.pending_skipped_token_diagnostics.push(PendingParserDiagnostic {
3582 kind: diagnostic_kind,
3583 span: TextSpan::new(diag_start, diag_end),
3584 leading_trivia_start: orig_offset,
3585 trailing_trivia_end: diag_end.add_width(trailing_trivia_width),
3586 });
3587 }
3588
3589 fn skip_taken_node_from_current_offset(
3592 &mut self,
3593 node_to_skip: impl Into<SkippedNodeGreen<'a>>,
3594 diagnostic_kind: ParserDiagnosticKind,
3595 ) {
3596 self.skip_taken_node_with_offset(
3597 node_to_skip,
3598 diagnostic_kind,
3599 self.offset.add_width(self.current_width),
3600 )
3601 }
3602
3603 fn skip_taken_node_with_offset(
3609 &mut self,
3610 node_to_skip: impl Into<SkippedNodeGreen<'a>>,
3611 diagnostic_kind: ParserDiagnosticKind,
3612 end_of_node_offset: TextOffset,
3613 ) {
3614 let trivium_green = TriviumSkippedNode::new_green(self.db, node_to_skip.into()).into();
3615
3616 self.pending_trivia.push(trivium_green);
3618
3619 let start_of_node_offset = end_of_node_offset.sub_width(trivium_green.0.width(self.db));
3620 let diag_pos = end_of_node_offset
3621 .sub_width(trailing_trivia_width(self.db, trivium_green.0).unwrap_or_default());
3622
3623 self.pending_skipped_token_diagnostics.push(PendingParserDiagnostic {
3624 kind: diagnostic_kind,
3625 span: TextSpan::cursor(diag_pos),
3626 leading_trivia_start: start_of_node_offset,
3627 trailing_trivia_end: end_of_node_offset,
3628 });
3629 }
3630
3631 fn skip_token_and_return_missing<ExpectedTerminal: syntax::node::Terminal<'a>>(
3634 &mut self,
3635 diagnostic: ParserDiagnosticKind,
3636 ) -> ExpectedTerminal::Green {
3637 self.skip_token(diagnostic);
3638 ExpectedTerminal::missing(self.db)
3639 }
3640
3641 fn skip_taken_node_and_return_missing<ExpectedNode: TypedSyntaxNode<'a>>(
3644 &mut self,
3645 node_to_skip: impl Into<SkippedNodeGreen<'a>>,
3646 diagnostic_kind: ParserDiagnosticKind,
3647 ) -> ExpectedNode::Green {
3648 self.skip_taken_node_from_current_offset(node_to_skip, diagnostic_kind);
3649 ExpectedNode::missing(self.db)
3650 }
3651
3652 pub(crate) fn skip_until(
3656 &mut self,
3657 should_stop: fn(SyntaxKind) -> bool,
3658 ) -> Result<(), SkippedError> {
3659 let mut diag_start = None;
3660 let mut diag_end = None;
3661 while !should_stop(self.peek().kind) {
3662 let terminal = self.take_raw();
3663 diag_start.get_or_insert(self.offset);
3664 diag_end =
3665 Some(self.offset.add_width(TextWidth::from_str(terminal.text.long(self.db))));
3666
3667 self.pending_trivia.extend(terminal.leading_trivia);
3668 self.pending_trivia.push(TokenSkipped::new_green(self.db, terminal.text).into());
3669 self.pending_trivia.extend(terminal.trailing_trivia);
3670 }
3671 if let (Some(diag_start), Some(diag_end)) = (diag_start, diag_end) {
3672 Err(SkippedError(TextSpan::new(diag_start, diag_end)))
3673 } else {
3674 Ok(())
3675 }
3676 }
3677
3678 fn add_trivia_to_terminal<Terminal: syntax::node::Terminal<'a>>(
3681 &mut self,
3682 lexer_terminal: LexerTerminal<'a>,
3683 ) -> Terminal::Green {
3684 let LexerTerminal { text, kind: _, leading_trivia, trailing_trivia } = lexer_terminal;
3685 let token = Terminal::TokenType::new_green(self.db, text);
3686 let mut new_leading_trivia = mem::take(&mut self.pending_trivia);
3687
3688 self.consume_pending_skipped_diagnostics();
3689
3690 new_leading_trivia.extend(leading_trivia);
3691 Terminal::new_green(
3692 self.db,
3693 Trivia::new_green(self.db, &new_leading_trivia),
3694 token,
3695 Trivia::new_green(self.db, &trailing_trivia),
3696 )
3697 }
3698
3699 fn consume_pending_skipped_diagnostics(&mut self) {
3702 let mut pending_skipped = self.pending_skipped_token_diagnostics.drain(..);
3703 let Some(first) = pending_skipped.next() else {
3704 return;
3705 };
3706
3707 let mut current_diag = first;
3708
3709 for diag in pending_skipped {
3710 if diag.kind == current_diag.kind
3711 && current_diag.trailing_trivia_end == diag.leading_trivia_start
3712 {
3713 current_diag = PendingParserDiagnostic {
3715 span: TextSpan::new(current_diag.span.start, diag.span.end),
3716 kind: diag.kind,
3717 leading_trivia_start: current_diag.leading_trivia_start,
3718 trailing_trivia_end: diag.trailing_trivia_end,
3719 };
3720 } else {
3721 self.diagnostics.add(ParserDiagnostic {
3724 file_id: self.file_id,
3725 span: current_diag.span,
3726 kind: current_diag.kind,
3727 });
3728 current_diag = diag;
3729 }
3730 }
3731 self.add_diagnostic(current_diag.kind, current_diag.span);
3733 }
3734
3735 pub fn take<Terminal: syntax::node::Terminal<'a>>(&mut self) -> Terminal::Green {
3738 let token = self.take_raw();
3739 assert_eq!(token.kind, Terminal::KIND);
3740 self.add_trivia_to_terminal::<Terminal>(token)
3741 }
3742
3743 fn take_doc(&mut self) -> Option<ItemHeaderDocGreen<'a>> {
3747 let mut has_header_doc = false;
3751 let mut split_index = 0;
3752 for trivium in &self.next_terminal().leading_trivia {
3753 match trivium.0.long(self.db).kind {
3754 SyntaxKind::TokenSingleLineComment | SyntaxKind::TokenSingleLineInnerComment => {
3755 has_header_doc = true;
3756 }
3757 SyntaxKind::TokenSingleLineDocComment => {
3758 break;
3759 }
3760 _ => {}
3761 }
3762 split_index += 1;
3763 }
3764 if !has_header_doc {
3765 return None;
3766 }
3767 let header_doc = {
3769 let next_mut = self.next_terminal_mut();
3770 let leading_trivia = next_mut.leading_trivia.split_off(split_index);
3771 std::mem::replace(&mut next_mut.leading_trivia, leading_trivia)
3772 };
3773 let empty_text_id = SmolStrId::from(self.db, "");
3774 let empty_lexer_terminal = LexerTerminal {
3775 text: empty_text_id,
3776 kind: SyntaxKind::TerminalEmpty,
3777 leading_trivia: header_doc,
3778 trailing_trivia: vec![],
3779 };
3780 self.offset = self.offset.add_width(empty_lexer_terminal.width(self.db));
3781
3782 let empty_terminal = self.add_trivia_to_terminal::<TerminalEmpty<'_>>(empty_lexer_terminal);
3783 Some(ItemHeaderDoc::new_green(self.db, empty_terminal))
3784 }
3785
3786 fn try_parse_token<Terminal: syntax::node::Terminal<'a>>(
3791 &mut self,
3792 ) -> TryParseResult<Terminal::Green> {
3793 if Terminal::KIND == self.peek().kind {
3794 Ok(self.take::<Terminal>())
3795 } else {
3796 Err(TryParseFailure::SkipToken)
3797 }
3798 }
3799
3800 fn parse_token<Terminal: syntax::node::Terminal<'a>>(&mut self) -> Terminal::Green {
3806 self.parse_token_ex::<Terminal>(true)
3807 }
3808
3809 fn parse_token_ex<Terminal: syntax::node::Terminal<'a>>(
3811 &mut self,
3812 report_diagnostic: bool,
3813 ) -> Terminal::Green {
3814 match self.try_parse_token::<Terminal>() {
3815 Ok(green) => green,
3816 Err(_) => {
3817 if report_diagnostic {
3818 self.create_and_report_missing_terminal::<Terminal>()
3819 } else {
3820 Terminal::missing(self.db)
3821 }
3822 }
3823 }
3824 }
3825}
3826
3827#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3836enum LbraceAllowed {
3837 Forbid,
3838 Allow,
3839}
3840
3841#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3843enum AndLetBehavior {
3844 Simple,
3846 Stop,
3848}
3849
3850pub(crate) struct SkippedError(pub(crate) TextSpan);
3852
3853struct ErrorRecovery {
3855 should_stop: fn(SyntaxKind) -> bool,
3858}
3859
3860enum ExternItem<'a> {
3861 Function(ItemExternFunctionGreen<'a>),
3862 Type(ItemExternTypeGreen<'a>),
3863}
3864
3865#[derive(Debug)]
3866enum ImplItemOrAlias<'a> {
3867 Item(ItemImplGreen<'a>),
3868 Alias(ItemImplAliasGreen<'a>),
3869}
3870
3871pub struct PendingParserDiagnostic {
3874 pub span: TextSpan,
3875 pub kind: ParserDiagnosticKind,
3876 pub leading_trivia_start: TextOffset,
3877 pub trailing_trivia_end: TextOffset,
3878}
3879
3880fn trivia_total_width(db: &dyn Database, trivia: &[TriviumGreen<'_>]) -> TextWidth {
3882 trivia.iter().map(|trivium| trivium.0.width(db)).sum::<TextWidth>()
3883}
3884
3885fn trailing_trivia_width(db: &dyn Database, green_id: GreenId<'_>) -> Option<TextWidth> {
3887 let node = green_id.long(db);
3888 if node.kind == SyntaxKind::Trivia {
3889 return Some(node.width(db));
3890 }
3891 match &node.details {
3892 GreenNodeDetails::Token(_) => Some(TextWidth::default()),
3893 GreenNodeDetails::Node { children, .. } => {
3894 for child in children.iter().rev() {
3895 if let Some(width) = trailing_trivia_width(db, *child) {
3896 return Some(width);
3897 }
3898 }
3899 None
3900 }
3901 }
3902}