rustfmt_nightly/parse/macros/
lazy_static.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use rustc_ast::ast;
use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_parse::exp;
use rustc_span::symbol;

use crate::rewrite::RewriteContext;

pub(crate) fn parse_lazy_static(
    context: &RewriteContext<'_>,
    ts: TokenStream,
) -> Option<Vec<(ast::Visibility, symbol::Ident, P<ast::Ty>, P<ast::Expr>)>> {
    let mut result = vec![];
    let mut parser = super::build_parser(context, ts);
    macro_rules! parse_or {
        ($method:ident $(,)* $($arg:expr),* $(,)*) => {
            match parser.$method($($arg,)*) {
                Ok(val) => {
                    if parser.psess.dcx().has_errors().is_some() {
                        parser.psess.dcx().reset_err_count();
                        return None;
                    } else {
                        val
                    }
                }
                Err(err) => {
                    err.cancel();
                    parser.psess.dcx().reset_err_count();
                    return None;
                }
            }
        }
    }
    while parser.token.kind != token::Eof {
        // Parse a `lazy_static!` item.
        // FIXME: These `eat_*` calls should be converted to `parse_or` to avoid
        // silently formatting malformed lazy-statics.
        let vis = parse_or!(parse_visibility, rustc_parse::parser::FollowedByType::No);
        let _ = parser.eat_keyword(exp!(Static));
        let _ = parser.eat_keyword(exp!(Ref));
        let id = parse_or!(parse_ident);
        let _ = parser.eat(exp!(Colon));
        let ty = parse_or!(parse_ty);
        let _ = parser.eat(exp!(Eq));
        let expr = parse_or!(parse_expr);
        let _ = parser.eat(exp!(Semi));
        result.push((vis, id, ty, expr));
    }

    Some(result)
}