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