]> git.lizzy.rs Git - rust.git/blob - crates/hir_expand/src/builtin_attr_macro.rs
internal: Split unresolve proc-macro error out of mbe
[rust.git] / crates / hir_expand / src / builtin_attr_macro.rs
1 //! Builtin attributes.
2
3 use syntax::ast;
4
5 use crate::{
6     db::AstDatabase, name, AstId, CrateId, ExpandResult, MacroCallId, MacroDefId, MacroDefKind,
7 };
8
9 macro_rules! register_builtin {
10     ( $(($name:ident, $variant:ident) => $expand:ident),* ) => {
11         #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12         pub enum BuiltinAttrExpander {
13             $($variant),*
14         }
15
16         impl BuiltinAttrExpander {
17             pub fn expand(
18                 &self,
19                 db: &dyn AstDatabase,
20                 id: MacroCallId,
21                 tt: &tt::Subtree,
22             ) -> ExpandResult<tt::Subtree> {
23                 let expander = match *self {
24                     $( BuiltinAttrExpander::$variant => $expand, )*
25                 };
26                 expander(db, id, tt)
27             }
28
29             fn find_by_name(name: &name::Name) -> Option<Self> {
30                 match name {
31                     $( id if id == &name::name![$name] => Some(BuiltinAttrExpander::$variant), )*
32                      _ => None,
33                 }
34             }
35         }
36
37     };
38 }
39
40 impl BuiltinAttrExpander {
41     pub fn is_derive(self) -> bool {
42         matches!(self, BuiltinAttrExpander::Derive)
43     }
44     pub fn is_test(self) -> bool {
45         matches!(self, BuiltinAttrExpander::Test)
46     }
47     pub fn is_bench(self) -> bool {
48         matches!(self, BuiltinAttrExpander::Bench)
49     }
50 }
51
52 register_builtin! {
53     (bench, Bench) => dummy_attr_expand,
54     (cfg_accessible, CfgAccessible) => dummy_attr_expand,
55     (cfg_eval, CfgEval) => dummy_attr_expand,
56     (derive, Derive) => dummy_attr_expand,
57     (global_allocator, GlobalAllocator) => dummy_attr_expand,
58     (test, Test) => dummy_attr_expand,
59     (test_case, TestCase) => dummy_attr_expand
60 }
61
62 pub fn find_builtin_attr(
63     ident: &name::Name,
64     krate: CrateId,
65     ast_id: AstId<ast::Macro>,
66 ) -> Option<MacroDefId> {
67     let expander = BuiltinAttrExpander::find_by_name(ident)?;
68     Some(MacroDefId {
69         krate,
70         kind: MacroDefKind::BuiltInAttr(expander, ast_id),
71         local_inner: false,
72     })
73 }
74
75 fn dummy_attr_expand(
76     _db: &dyn AstDatabase,
77     _id: MacroCallId,
78     tt: &tt::Subtree,
79 ) -> ExpandResult<tt::Subtree> {
80     ExpandResult::ok(tt.clone())
81 }