aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_expand/src/builtin_derive.rs
blob: 0a70c63c0040b8c0100185d0558c45e49c33ca04 (plain)
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
53
54
55
56
57
58
59
60
61
62
63
64
//! Builtin derives.
use crate::db::AstDatabase;
use crate::{name, MacroCallId, MacroDefId, MacroDefKind};

use crate::quote;

macro_rules! register_builtin {
    ( $(($name:ident, $kind: ident) => $expand:ident),* ) => {
        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
        pub enum BuiltinDeriveExpander {
            $($kind),*
        }

        impl BuiltinDeriveExpander {
            pub fn expand(
                &self,
                db: &dyn AstDatabase,
                id: MacroCallId,
                tt: &tt::Subtree,
            ) -> Result<tt::Subtree, mbe::ExpandError> {
                let expander = match *self {
                    $( BuiltinDeriveExpander::$kind => $expand, )*
                };
                expander(db, id, tt)
            }
        }

        pub fn find_builtin_derive(ident: &name::Name) -> Option<MacroDefId> {
            let kind = match ident {
                 $( id if id == &name::$name => BuiltinDeriveExpander::$kind, )*
                 _ => return None,
            };

            Some(MacroDefId { krate: None, ast_id: None, kind: MacroDefKind::BuiltInDerive(kind) })
        }
    };
}

register_builtin! {
    (COPY_TRAIT, Copy) => copy_expand,
    (CLONE_TRAIT, Clone) => clone_expand
}

fn copy_expand(
    _db: &dyn AstDatabase,
    _id: MacroCallId,
    _tt: &tt::Subtree,
) -> Result<tt::Subtree, mbe::ExpandError> {
    let expanded = quote! {
        impl Copy for Foo {}
    };
    Ok(expanded)
}

fn clone_expand(
    _db: &dyn AstDatabase,
    _id: MacroCallId,
    _tt: &tt::Subtree,
) -> Result<tt::Subtree, mbe::ExpandError> {
    let expanded = quote! {
        impl Clone for Foo {}
    };
    Ok(expanded)
}