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