]>
git.proxmox.com Git - rustc.git/blob - src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs
16 pub(crate) const LITERAL_FIRST
: TokenSet
= TokenSet
::new(&[
27 pub(crate) fn literal(p
: &mut Parser
<'_
>) -> Option
<CompletedMarker
> {
28 if !p
.at_ts(LITERAL_FIRST
) {
33 Some(m
.complete(p
, LITERAL
))
36 // E.g. for after the break in `if break {}`, this should not match
37 pub(super) const ATOM_EXPR_FIRST
: TokenSet
=
38 LITERAL_FIRST
.union(paths
::PATH_FIRST
).union(TokenSet
::new(&[
62 const EXPR_RECOVERY_SET
: TokenSet
= TokenSet
::new(&[T
![let]]);
64 pub(super) fn atom_expr(
67 ) -> Option
<(CompletedMarker
, BlockLike
)> {
68 if let Some(m
) = literal(p
) {
69 return Some((m
, BlockLike
::NotBlock
));
71 if paths
::is_path_start(p
) {
72 return Some(path_expr(p
, r
));
75 let done
= match p
.current() {
76 T
!['
('
] => tuple_expr(p
),
77 T
!['
['
] => array_expr(p
),
79 T
![let] => let_expr(p
),
81 // test destructuring_assignment_wildcard_pat
88 m
.complete(p
, UNDERSCORE_EXPR
)
90 T
![loop] => loop_expr(p
, None
),
91 T
![box] => box_expr(p
, None
),
92 T
![while] => while_expr(p
, None
),
93 T
![try
] => try_block_expr(p
, None
),
94 T
![match] => match_expr(p
),
95 T
![return] => return_expr(p
),
96 T
![yield] => yield_expr(p
),
97 T
![do] if p
.nth_at_contextual_kw(1, T
![yeet
]) => yeet_expr(p
),
98 T
![continue] => continue_expr(p
),
99 T
![break] => break_expr(p
, r
),
101 LIFETIME_IDENT
if la
== T
![:] => {
105 T
![loop] => loop_expr(p
, Some(m
)),
106 T
![for] => for_expr(p
, Some(m
)),
107 T
![while] => while_expr(p
, Some(m
)),
108 // test labeled_block
109 // fn f() { 'label: {}; }
112 m
.complete(p
, BLOCK_EXPR
)
115 // test_err misplaced_label_err
119 p
.error("expected a loop");
120 m
.complete(p
, ERROR
);
125 // test effect_blocks
126 // fn f() { unsafe { } }
127 // fn f() { const { } }
128 // fn f() { async { } }
129 // fn f() { async move { } }
130 T
![const] | T
![unsafe] | T
![async
] if la
== T
!['
{'
] => {
134 m
.complete(p
, BLOCK_EXPR
)
136 T
![async
] if la
== T
![move] && p
.nth(2) == T
!['
{'
] => {
141 m
.complete(p
, BLOCK_EXPR
)
144 // test for_range_from
152 m
.complete(p
, BLOCK_EXPR
)
155 T
![static] | T
![async
] | T
![move] | T
![|] => closure_expr(p
),
156 T
![for] if la
== T
![<] => closure_expr(p
),
157 T
![for] => for_expr(p
, None
),
160 p
.err_recover("expected expression", EXPR_RECOVERY_SET
);
164 let blocklike
= match done
.kind() {
165 IF_EXPR
| WHILE_EXPR
| FOR_EXPR
| LOOP_EXPR
| MATCH_EXPR
| BLOCK_EXPR
=> BlockLike
::Block
,
166 _
=> BlockLike
::NotBlock
,
168 Some((done
, blocklike
))
177 fn tuple_expr(p
: &mut Parser
<'_
>) -> CompletedMarker
{
178 assert
!(p
.at(T
!['
('
]));
182 let mut saw_comma
= false;
183 let mut saw_expr
= false;
184 while !p
.at(EOF
) && !p
.at(T
!['
)'
]) {
188 // const A: (i64, i64) = (1, #[cfg(test)] 2);
199 m
.complete(p
, if saw_expr
&& !saw_comma { PAREN_EXPR }
else { TUPLE_EXPR }
)
209 fn array_expr(p
: &mut Parser
<'_
>) -> CompletedMarker
{
210 assert
!(p
.at(T
!['
['
]));
213 let mut n_exprs
= 0u32;
214 let mut has_semi
= false;
217 while !p
.at(EOF
) && !p
.at(T
!['
]'
]) {
221 // const A: &[i64] = &[1, #[cfg(test)] 2];
226 if n_exprs
== 1 && p
.eat(T
![;]) {
231 if has_semi
|| !p
.at(T
!['
]'
]) && !p
.expect(T
![,]) {
237 m
.complete(p
, ARRAY_EXPR
)
250 // static move || {};
251 // static async || {};
252 // static async move || {};
254 // for<'a> move || {};
256 fn closure_expr(p
: &mut Parser
<'_
>) -> CompletedMarker
{
257 assert
!(match p
.current() {
258 T
![static] | T
![async
] | T
![move] | T
![|] => true,
259 T
![for] => p
.nth(1) == T
![<],
266 types
::for_binder(p
);
274 p
.error("expected `|`");
275 return m
.complete(p
, CLOSURE_EXPR
);
277 params
::param_list_closure(p
);
279 // test lambda_ret_block
280 // fn main() { || -> i32 { 92 }(); }
282 } else if p
.at_ts(EXPR_FIRST
) {
283 // test closure_body_underscore_assignment
284 // fn main() { || _ = 0; }
287 p
.error("expected expression");
289 m
.complete(p
, CLOSURE_EXPR
)
295 // if true {} else {};
296 // if true {} else if false {} else {};
298 // if { true } { } else { };
300 fn if_expr(p
: &mut Parser
<'_
>) -> CompletedMarker
{
301 assert
!(p
.at(T
![if]));
314 m
.complete(p
, IF_EXPR
)
321 // 'c: for x in () {}
323 fn label(p
: &mut Parser
<'_
>) {
324 assert
!(p
.at(LIFETIME_IDENT
) && p
.nth(1) == T
![:]);
328 m
.complete(p
, LABEL
);
335 fn loop_expr(p
: &mut Parser
<'_
>, m
: Option
<Marker
>) -> CompletedMarker
{
336 assert
!(p
.at(T
![loop]));
337 let m
= m
.unwrap_or_else(|| p
.start());
340 m
.complete(p
, LOOP_EXPR
)
346 // while let Some(x) = it.next() {};
347 // while { true } {};
349 fn while_expr(p
: &mut Parser
<'_
>, m
: Option
<Marker
>) -> CompletedMarker
{
350 assert
!(p
.at(T
![while]));
351 let m
= m
.unwrap_or_else(|| p
.start());
355 m
.complete(p
, WHILE_EXPR
)
362 fn for_expr(p
: &mut Parser
<'_
>, m
: Option
<Marker
>) -> CompletedMarker
{
363 assert
!(p
.at(T
![for]));
364 let m
= m
.unwrap_or_else(|| p
.start());
366 patterns
::pattern(p
);
370 m
.complete(p
, FOR_EXPR
)
375 // if let Some(_) = None && true {}
376 // while 1 == 5 && (let None = None) {}
378 fn let_expr(p
: &mut Parser
<'_
>) -> CompletedMarker
{
381 patterns
::pattern_top(p
);
384 m
.complete(p
, LET_EXPR
)
391 // match { } { _ => () };
392 // match { S {} } {};
394 fn match_expr(p
: &mut Parser
<'_
>) -> CompletedMarker
{
395 assert
!(p
.at(T
![match]));
402 p
.error("expected `{`");
404 m
.complete(p
, MATCH_EXPR
)
407 pub(crate) fn match_arm_list(p
: &mut Parser
<'_
>) {
408 assert
!(p
.at(T
!['
{'
]));
412 // test match_arms_inner_attribute
415 // #![doc("Inner attribute")]
417 // #![doc("Stacked")]
421 attributes
::inner_attrs(p
);
423 while !p
.at(EOF
) && !p
.at(T
!['
}'
]) {
425 error_block(p
, "expected match arm");
431 m
.complete(p
, MATCH_ARM_LIST
);
438 // _ if Test > Test{field: 0} => (),
440 // | X | Y if Z => (),
444 fn match_arm(p
: &mut Parser
<'_
>) {
446 // test match_arms_outer_attributes
449 // #[cfg(feature = "some")]
451 // #[cfg(feature = "other")]
453 // #[cfg(feature = "many")]
454 // #[cfg(feature = "attributes")]
455 // #[cfg(feature = "before")]
459 attributes
::outer_attrs(p
);
461 patterns
::pattern_top_r(p
, TokenSet
::EMPTY
);
466 let blocklike
= match expr_stmt(p
, None
) {
467 Some((_
, blocklike
)) => blocklike
,
468 None
=> BlockLike
::NotBlock
,
471 // test match_arms_commas
479 if !p
.eat(T
![,]) && !blocklike
.is_block() && !p
.at(T
!['
}'
]) {
480 p
.error("expected `,`");
482 m
.complete(p
, MATCH_ARM
);
489 // _ if let foo = bar => (),
492 fn match_guard(p
: &mut Parser
<'_
>) -> CompletedMarker
{
493 assert
!(p
.at(T
![if]));
497 m
.complete(p
, MATCH_GUARD
)
502 // fn b() { let _ = 1; }
505 pub(crate) fn block_expr(p
: &mut Parser
<'_
>) {
507 p
.error("expected a block");
512 m
.complete(p
, BLOCK_EXPR
);
515 fn stmt_list(p
: &mut Parser
<'_
>) -> CompletedMarker
{
516 assert
!(p
.at(T
!['
{'
]));
519 expr_block_contents(p
);
521 m
.complete(p
, STMT_LIST
)
529 fn return_expr(p
: &mut Parser
<'_
>) -> CompletedMarker
{
530 assert
!(p
.at(T
![return]));
533 if p
.at_ts(EXPR_FIRST
) {
536 m
.complete(p
, RETURN_EXPR
)
544 fn yield_expr(p
: &mut Parser
<'_
>) -> CompletedMarker
{
545 assert
!(p
.at(T
![yield]));
548 if p
.at_ts(EXPR_FIRST
) {
551 m
.complete(p
, YIELD_EXPR
)
559 fn yeet_expr(p
: &mut Parser
<'_
>) -> CompletedMarker
{
560 assert
!(p
.at(T
![do]));
561 assert
!(p
.nth_at_contextual_kw(1, T
![yeet
]));
564 p
.bump_remap(T
![yeet
]);
565 if p
.at_ts(EXPR_FIRST
) {
568 m
.complete(p
, YEET_EXPR
)
571 // test continue_expr
578 fn continue_expr(p
: &mut Parser
<'_
>) -> CompletedMarker
{
579 assert
!(p
.at(T
![continue]));
581 p
.bump(T
![continue]);
582 if p
.at(LIFETIME_IDENT
) {
585 m
.complete(p
, CONTINUE_EXPR
)
597 fn break_expr(p
: &mut Parser
<'_
>, r
: Restrictions
) -> CompletedMarker
{
598 assert
!(p
.at(T
![break]));
601 if p
.at(LIFETIME_IDENT
) {
604 // test break_ambiguity
611 if p
.at_ts(EXPR_FIRST
) && !(r
.forbid_structs
&& p
.at(T
!['
{'
])) {
614 m
.complete(p
, BREAK_EXPR
)
617 // test try_block_expr
621 fn try_block_expr(p
: &mut Parser
<'_
>, m
: Option
<Marker
>) -> CompletedMarker
{
622 assert
!(p
.at(T
![try
]));
623 let m
= m
.unwrap_or_else(|| p
.start());
624 // Special-case `try!` as macro.
625 // This is a hack until we do proper edition support
626 if p
.nth_at(1, T
![!]) {
627 // test try_macro_fallback
628 // fn foo() { try!(Ok(())); }
629 let macro_call
= p
.start();
630 let path
= p
.start();
631 let path_segment
= p
.start();
632 let name_ref
= p
.start();
634 name_ref
.complete(p
, NAME_REF
);
635 path_segment
.complete(p
, PATH_SEGMENT
);
636 path
.complete(p
, PATH
);
637 let _block_like
= items
::macro_call_after_excl(p
);
638 macro_call
.complete(p
, MACRO_CALL
);
639 return m
.complete(p
, MACRO_EXPR
);
646 p
.error("expected a block");
648 m
.complete(p
, BLOCK_EXPR
)
654 // let y = (box 1i32, box 2i32);
655 // let z = Foo(box 1i32, box 2i32);
657 fn box_expr(p
: &mut Parser
<'_
>, m
: Option
<Marker
>) -> CompletedMarker
{
658 assert
!(p
.at(T
![box]));
659 let m
= m
.unwrap_or_else(|| p
.start());
661 if p
.at_ts(EXPR_FIRST
) {
664 m
.complete(p
, BOX_EXPR
)