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