parser/
grammar.rs

1//! This is the actual "grammar" of the Rust language.
2//!
3//! Each function in this module and its children corresponds
4//! to a production of the formal grammar. Submodules roughly
5//! correspond to different *areas* of the grammar. By convention,
6//! each submodule starts with `use super::*` import and exports
7//! "public" productions via `pub(super)`.
8//!
9//! See docs for [`Parser`](super::parser::Parser) to learn about API,
10//! available to the grammar, and see docs for [`Event`](super::event::Event)
11//! to learn how this actually manages to produce parse trees.
12//!
13//! Code in this module also contains inline tests, which start with
14//! `// test name-of-the-test` comment and look like this:
15//!
16//! ```text
17//! // test function_with_zero_parameters
18//! // fn foo() {}
19//! ```
20//!
21//! After adding a new inline-test, run `cargo test -p xtask` to
22//! extract it as a standalone text-fixture into
23//! `crates/syntax/test_data/parser/`, and run `cargo test` once to
24//! create the "gold" value.
25//!
26//! Coding convention: rules like `where_clause` always produce either a
27//! node or an error, rules like `opt_where_clause` may produce nothing.
28//! Non-opt rules typically start with `assert!(p.at(FIRST_TOKEN))`, the
29//! caller is responsible for branching on the first token.
30
31mod attributes;
32mod expressions;
33mod generic_args;
34mod generic_params;
35mod items;
36mod params;
37mod paths;
38mod patterns;
39mod types;
40
41use crate::{
42    SyntaxKind::{self, *},
43    T, TokenSet,
44    parser::{CompletedMarker, Marker, Parser},
45};
46
47pub(crate) mod entry {
48    use super::*;
49
50    pub(crate) mod prefix {
51        use super::*;
52
53        pub(crate) fn vis(p: &mut Parser<'_>) {
54            opt_visibility(p, false);
55        }
56
57        pub(crate) fn block(p: &mut Parser<'_>) {
58            expressions::block_expr(p);
59        }
60
61        pub(crate) fn stmt(p: &mut Parser<'_>) {
62            expressions::stmt(p, expressions::Semicolon::Forbidden);
63        }
64
65        pub(crate) fn pat(p: &mut Parser<'_>) {
66            patterns::pattern_single(p);
67        }
68
69        pub(crate) fn pat_top(p: &mut Parser<'_>) {
70            patterns::pattern(p);
71        }
72
73        pub(crate) fn ty(p: &mut Parser<'_>) {
74            types::type_(p);
75        }
76        pub(crate) fn expr(p: &mut Parser<'_>) {
77            expressions::expr(p);
78        }
79        pub(crate) fn path(p: &mut Parser<'_>) {
80            paths::type_path(p);
81        }
82        pub(crate) fn item(p: &mut Parser<'_>) {
83            // We can set `is_in_extern=true`, because it only allows `safe fn`, and there is no ambiguity here.
84            items::item_or_macro(p, true, true);
85        }
86        // Parse a meta item , which excluded [], e.g : #[ MetaItem ]
87        pub(crate) fn meta_item(p: &mut Parser<'_>) {
88            attributes::meta(p);
89        }
90    }
91
92    pub(crate) mod top {
93        use super::*;
94
95        pub(crate) fn source_file(p: &mut Parser<'_>) {
96            let m = p.start();
97            // test frontmatter
98            // #!/usr/bin/env cargo
99            //
100            // ---
101            // [dependencies]
102            // clap = { version = "4.2", features = ["derive"] }
103            // ---
104            //
105            // fn main() {}
106            p.eat(SHEBANG);
107            p.eat(FRONTMATTER);
108            items::mod_contents(p, false);
109            m.complete(p, SOURCE_FILE);
110        }
111
112        pub(crate) fn macro_stmts(p: &mut Parser<'_>) {
113            let m = p.start();
114
115            while !p.at(EOF) {
116                expressions::stmt(p, expressions::Semicolon::Optional);
117            }
118
119            m.complete(p, MACRO_STMTS);
120        }
121
122        pub(crate) fn macro_items(p: &mut Parser<'_>) {
123            let m = p.start();
124            items::mod_contents(p, false);
125            m.complete(p, MACRO_ITEMS);
126        }
127
128        pub(crate) fn pattern(p: &mut Parser<'_>) {
129            let m = p.start();
130            patterns::pattern(p);
131            if p.at(EOF) {
132                m.abandon(p);
133                return;
134            }
135            while !p.at(EOF) {
136                p.bump_any();
137            }
138            m.complete(p, ERROR);
139        }
140
141        pub(crate) fn type_(p: &mut Parser<'_>) {
142            let m = p.start();
143            types::type_(p);
144            if p.at(EOF) {
145                m.abandon(p);
146                return;
147            }
148            while !p.at(EOF) {
149                p.bump_any();
150            }
151            m.complete(p, ERROR);
152        }
153
154        pub(crate) fn expr(p: &mut Parser<'_>) {
155            let m = p.start();
156            expressions::expr(p);
157            if p.at(EOF) {
158                m.abandon(p);
159                return;
160            }
161            while !p.at(EOF) {
162                p.bump_any();
163            }
164            m.complete(p, ERROR);
165        }
166
167        pub(crate) fn meta_item(p: &mut Parser<'_>) {
168            let m = p.start();
169            attributes::meta(p);
170            if p.at(EOF) {
171                m.abandon(p);
172                return;
173            }
174            while !p.at(EOF) {
175                p.bump_any();
176            }
177            m.complete(p, ERROR);
178        }
179    }
180}
181
182pub(crate) fn reparser(
183    node: SyntaxKind,
184    first_child: Option<SyntaxKind>,
185    parent: Option<SyntaxKind>,
186) -> Option<fn(&mut Parser<'_>)> {
187    let res = match node {
188        BLOCK_EXPR => expressions::block_expr,
189        RECORD_FIELD_LIST => items::record_field_list,
190        RECORD_EXPR_FIELD_LIST => items::record_expr_field_list,
191        VARIANT_LIST => items::variant_list,
192        MATCH_ARM_LIST => items::match_arm_list,
193        USE_TREE_LIST => items::use_tree_list,
194        EXTERN_ITEM_LIST => items::extern_item_list,
195        TOKEN_TREE if first_child? == T!['{'] => items::token_tree,
196        ASSOC_ITEM_LIST => match parent? {
197            IMPL | TRAIT => items::assoc_item_list,
198            _ => return None,
199        },
200        ITEM_LIST => items::item_list,
201        _ => return None,
202    };
203    Some(res)
204}
205
206#[derive(Clone, Copy, PartialEq, Eq)]
207enum BlockLike {
208    Block,
209    NotBlock,
210}
211
212impl BlockLike {
213    fn is_block(self) -> bool {
214        self == BlockLike::Block
215    }
216
217    fn is_blocklike(kind: SyntaxKind) -> bool {
218        matches!(kind, BLOCK_EXPR | IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR)
219    }
220}
221
222const VISIBILITY_FIRST: TokenSet = TokenSet::new(&[T![pub]]);
223
224fn opt_visibility(p: &mut Parser<'_>, in_tuple_field: bool) -> bool {
225    if !p.at(T![pub]) {
226        return false;
227    }
228
229    let m = p.start();
230    p.bump(T![pub]);
231    if p.at(T!['(']) {
232        match p.nth(1) {
233            // test crate_visibility
234            // pub(crate) struct S;
235            // pub(self) struct S;
236            // pub(super) struct S;
237
238            // test_err crate_visibility_empty_recover
239            // pub() struct S;
240
241            // test pub_parens_typepath
242            // struct B(pub (super::A));
243            // struct B(pub (crate::A,));
244            T![crate] | T![self] | T![super] | T![ident] | T![')'] if p.nth(2) != T![:] => {
245                // If we are in a tuple struct, then the parens following `pub`
246                // might be an tuple field, not part of the visibility. So in that
247                // case we don't want to consume an identifier.
248
249                // test pub_tuple_field
250                // struct MyStruct(pub (u32, u32));
251                // struct MyStruct(pub (u32));
252                // struct MyStruct(pub ());
253                if !(in_tuple_field && matches!(p.nth(1), T![ident] | T![')'])) {
254                    p.bump(T!['(']);
255                    paths::vis_path(p);
256                    p.expect(T![')']);
257                }
258            }
259            // test crate_visibility_in
260            // pub(in super::A) struct S;
261            // pub(in crate) struct S;
262            T![in] => {
263                p.bump(T!['(']);
264                p.bump(T![in]);
265                paths::vis_path(p);
266                p.expect(T![')']);
267            }
268            _ => {}
269        }
270    }
271    m.complete(p, VISIBILITY);
272    true
273}
274
275fn opt_rename(p: &mut Parser<'_>) {
276    if p.at(T![as]) {
277        let m = p.start();
278        p.bump(T![as]);
279        if !p.eat(T![_]) {
280            name(p);
281        }
282        m.complete(p, RENAME);
283    }
284}
285
286fn abi(p: &mut Parser<'_>) {
287    assert!(p.at(T![extern]));
288    let abi = p.start();
289    p.bump(T![extern]);
290    p.eat(STRING);
291    abi.complete(p, ABI);
292}
293
294fn opt_ret_type(p: &mut Parser<'_>) -> bool {
295    if p.at(T![->]) {
296        let m = p.start();
297        p.bump(T![->]);
298        types::type_no_bounds(p);
299        m.complete(p, RET_TYPE);
300        true
301    } else {
302        false
303    }
304}
305
306fn name_r(p: &mut Parser<'_>, recovery: TokenSet) {
307    if p.at(IDENT) {
308        let m = p.start();
309        p.bump(IDENT);
310        m.complete(p, NAME);
311    } else {
312        p.err_recover("expected a name", recovery);
313    }
314}
315
316fn name(p: &mut Parser<'_>) {
317    name_r(p, TokenSet::EMPTY);
318}
319
320fn name_ref_or_self(p: &mut Parser<'_>) {
321    if matches!(p.current(), T![ident] | T![self]) {
322        let m = p.start();
323        p.bump_any();
324        m.complete(p, NAME_REF);
325    } else {
326        p.err_and_bump("expected identifier or `self`");
327    }
328}
329
330fn name_ref_or_upper_self(p: &mut Parser<'_>) {
331    if matches!(p.current(), T![ident] | T![Self]) {
332        let m = p.start();
333        p.bump_any();
334        m.complete(p, NAME_REF);
335    } else {
336        p.err_and_bump("expected identifier or `Self`");
337    }
338}
339
340const PATH_NAME_REF_KINDS: TokenSet =
341    TokenSet::new(&[IDENT, T![self], T![super], T![crate], T![Self]]);
342
343fn name_ref_mod_path(p: &mut Parser<'_>) {
344    if p.at_ts(PATH_NAME_REF_KINDS) {
345        let m = p.start();
346        p.bump_any();
347        m.complete(p, NAME_REF);
348    } else {
349        p.err_and_bump("expected identifier, `self`, `super`, `crate`, or `Self`");
350    }
351}
352
353const PATH_NAME_REF_OR_INDEX_KINDS: TokenSet =
354    PATH_NAME_REF_KINDS.union(TokenSet::new(&[INT_NUMBER]));
355
356fn name_ref_mod_path_or_index(p: &mut Parser<'_>) {
357    if p.at_ts(PATH_NAME_REF_OR_INDEX_KINDS) {
358        let m = p.start();
359        p.bump_any();
360        m.complete(p, NAME_REF);
361    } else {
362        p.err_and_bump("expected integer, identifier, `self`, `super`, `crate`, or `Self`");
363    }
364}
365
366fn name_ref_or_index(p: &mut Parser<'_>) {
367    assert!(p.at(IDENT) || p.at(INT_NUMBER));
368    let m = p.start();
369    p.bump_any();
370    m.complete(p, NAME_REF);
371}
372
373fn lifetime(p: &mut Parser<'_>) {
374    assert!(p.at(LIFETIME_IDENT));
375    let m = p.start();
376    p.bump(LIFETIME_IDENT);
377    m.complete(p, LIFETIME);
378}
379
380fn error_block(p: &mut Parser<'_>, message: &str) {
381    assert!(p.at(T!['{']));
382    let m = p.start();
383    p.error(message);
384    p.bump(T!['{']);
385    expressions::expr_block_contents(p);
386    p.eat(T!['}']);
387    m.complete(p, ERROR);
388}
389
390// test_err top_level_let
391// let ref foo: fn() = 1 + 3;
392fn error_let_stmt(p: &mut Parser<'_>, message: &str) {
393    assert!(p.at(T![let]));
394    let m = p.start();
395    p.error(message);
396    expressions::let_stmt(p, expressions::Semicolon::Optional);
397    m.complete(p, ERROR);
398}
399
400/// The `parser` passed this is required to at least consume one token if it returns `true`.
401/// If the `parser` returns false, parsing will stop.
402fn delimited(
403    p: &mut Parser<'_>,
404    bra: SyntaxKind,
405    ket: SyntaxKind,
406    delim: SyntaxKind,
407    unexpected_delim_message: impl Fn() -> String,
408    first_set: TokenSet,
409    mut parser: impl FnMut(&mut Parser<'_>) -> bool,
410) {
411    p.bump(bra);
412    while !p.at(ket) && !p.at(EOF) {
413        if p.at(delim) {
414            // Recover if an argument is missing and only got a delimiter,
415            // e.g. `(a, , b)`.
416
417            // Wrap the erroneous delimiter in an error node so that fixup logic gets rid of it.
418            // FIXME: Ideally this should be handled in fixup in a structured way, but our list
419            // nodes currently have no concept of a missing node between two delimiters.
420            // So doing it this way is easier.
421            let m = p.start();
422            p.error(unexpected_delim_message());
423            p.bump(delim);
424            m.complete(p, ERROR);
425            continue;
426        }
427        if !parser(p) {
428            break;
429        }
430        if !p.eat(delim) {
431            if p.at_ts(first_set) {
432                p.error(format!("expected {delim:?}"));
433            } else {
434                break;
435            }
436        }
437    }
438    p.expect(ket);
439}