salsa_macros/
lib.rs

1//! This crate provides salsa's macros and attributes.
2
3#![recursion_limit = "256"]
4
5#[macro_use]
6extern crate quote;
7
8use proc_macro::TokenStream;
9
10macro_rules! parse_quote {
11    ($($inp:tt)*) => {
12        {
13            let tt = quote!{$($inp)*};
14            syn::parse2(tt.clone()).unwrap_or_else(|err| {
15                panic!("failed to parse `{}` at {}:{}:{}: {}", tt, file!(), line!(), column!(), err)
16            })
17        }
18    }
19}
20
21/// Similar to `syn::parse_macro_input`, however, when a parse error is encountered, it will return
22/// the input token stream in addition to the error. This will make it so that rust-analyzer can work
23/// with incomplete code.
24macro_rules! parse_macro_input {
25    ($tokenstream:ident as $ty:ty) => {
26        match syn::parse::<$ty>($tokenstream.clone()) {
27            Ok(data) => data,
28            Err(err) => {
29                return $crate::token_stream_with_error($tokenstream, err);
30            }
31        }
32    };
33}
34
35mod accumulator;
36mod db;
37mod db_lifetime;
38mod debug;
39mod fn_util;
40mod hygiene;
41mod input;
42mod interned;
43mod options;
44mod salsa_struct;
45mod supertype;
46mod tracked;
47mod tracked_fn;
48mod tracked_impl;
49mod tracked_struct;
50mod update;
51mod xform;
52
53#[proc_macro_attribute]
54pub fn accumulator(args: TokenStream, input: TokenStream) -> TokenStream {
55    accumulator::accumulator(args, input)
56}
57
58#[proc_macro_attribute]
59pub fn db(args: TokenStream, input: TokenStream) -> TokenStream {
60    db::db(args, input)
61}
62
63#[proc_macro_attribute]
64pub fn interned(args: TokenStream, input: TokenStream) -> TokenStream {
65    interned::interned(args, input)
66}
67
68#[proc_macro_derive(Supertype)]
69pub fn supertype(input: TokenStream) -> TokenStream {
70    supertype::supertype(input)
71}
72
73#[proc_macro_attribute]
74pub fn input(args: TokenStream, input: TokenStream) -> TokenStream {
75    input::input(args, input)
76}
77
78#[proc_macro_attribute]
79pub fn tracked(args: TokenStream, input: TokenStream) -> TokenStream {
80    tracked::tracked(args, input)
81}
82
83#[proc_macro_derive(Update)]
84pub fn update(input: TokenStream) -> TokenStream {
85    let item = parse_macro_input!(input as syn::DeriveInput);
86    match update::update_derive(item) {
87        Ok(tokens) => tokens.into(),
88        Err(error) => token_stream_with_error(input, error),
89    }
90}
91
92pub(crate) fn token_stream_with_error(mut tokens: TokenStream, error: syn::Error) -> TokenStream {
93    tokens.extend(TokenStream::from(error.into_compile_error()));
94    tokens
95}