aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_expand/src/builtin_derive.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_expand/src/builtin_derive.rs')
-rw-r--r--crates/ra_hir_expand/src/builtin_derive.rs64
1 files changed, 64 insertions, 0 deletions
diff --git a/crates/ra_hir_expand/src/builtin_derive.rs b/crates/ra_hir_expand/src/builtin_derive.rs
new file mode 100644
index 000000000..0a70c63c0
--- /dev/null
+++ b/crates/ra_hir_expand/src/builtin_derive.rs
@@ -0,0 +1,64 @@
1//! Builtin derives.
2use crate::db::AstDatabase;
3use crate::{name, MacroCallId, MacroDefId, MacroDefKind};
4
5use crate::quote;
6
7macro_rules! register_builtin {
8 ( $(($name:ident, $kind: ident) => $expand:ident),* ) => {
9 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10 pub enum BuiltinDeriveExpander {
11 $($kind),*
12 }
13
14 impl BuiltinDeriveExpander {
15 pub fn expand(
16 &self,
17 db: &dyn AstDatabase,
18 id: MacroCallId,
19 tt: &tt::Subtree,
20 ) -> Result<tt::Subtree, mbe::ExpandError> {
21 let expander = match *self {
22 $( BuiltinDeriveExpander::$kind => $expand, )*
23 };
24 expander(db, id, tt)
25 }
26 }
27
28 pub fn find_builtin_derive(ident: &name::Name) -> Option<MacroDefId> {
29 let kind = match ident {
30 $( id if id == &name::$name => BuiltinDeriveExpander::$kind, )*
31 _ => return None,
32 };
33
34 Some(MacroDefId { krate: None, ast_id: None, kind: MacroDefKind::BuiltInDerive(kind) })
35 }
36 };
37}
38
39register_builtin! {
40 (COPY_TRAIT, Copy) => copy_expand,
41 (CLONE_TRAIT, Clone) => clone_expand
42}
43
44fn copy_expand(
45 _db: &dyn AstDatabase,
46 _id: MacroCallId,
47 _tt: &tt::Subtree,
48) -> Result<tt::Subtree, mbe::ExpandError> {
49 let expanded = quote! {
50 impl Copy for Foo {}
51 };
52 Ok(expanded)
53}
54
55fn clone_expand(
56 _db: &dyn AstDatabase,
57 _id: MacroCallId,
58 _tt: &tt::Subtree,
59) -> Result<tt::Subtree, mbe::ExpandError> {
60 let expanded = quote! {
61 impl Clone for Foo {}
62 };
63 Ok(expanded)
64}