1 | // tidy-alphabetical-start |
2 | #![allow (rustc::default_hash_types)] |
3 | #![feature (if_let_guard)] |
4 | #![feature (let_chains)] |
5 | #![feature (never_type)] |
6 | #![feature (proc_macro_diagnostic)] |
7 | #![feature (proc_macro_span)] |
8 | #![feature (proc_macro_tracked_env)] |
9 | // tidy-alphabetical-end |
10 | |
11 | use proc_macro::TokenStream; |
12 | use synstructure::decl_derive; |
13 | |
14 | mod current_version; |
15 | mod diagnostics; |
16 | mod extension; |
17 | mod hash_stable; |
18 | mod lift; |
19 | mod print_attribute; |
20 | mod query; |
21 | mod serialize; |
22 | mod symbols; |
23 | mod try_from; |
24 | mod type_foldable; |
25 | mod type_visitable; |
26 | |
27 | // Reads the rust version (e.g. "1.75.0") from the CFG_RELEASE env var and |
28 | // produces a `RustcVersion` literal containing that version (e.g. |
29 | // `RustcVersion { major: 1, minor: 75, patch: 0 }`). |
30 | #[proc_macro ] |
31 | pub fn current_rustc_version(input: TokenStream) -> TokenStream { |
32 | current_version::current_version(input) |
33 | } |
34 | |
35 | #[proc_macro ] |
36 | pub fn rustc_queries(input: TokenStream) -> TokenStream { |
37 | query::rustc_queries(input) |
38 | } |
39 | |
40 | #[proc_macro ] |
41 | pub fn symbols(input: TokenStream) -> TokenStream { |
42 | symbols::symbols(input.into()).into() |
43 | } |
44 | |
45 | /// Derive an extension trait for a given impl block. The trait name |
46 | /// goes into the parenthesized args of the macro, for greppability. |
47 | /// For example: |
48 | /// ``` |
49 | /// use rustc_macros::extension; |
50 | /// #[extension(pub trait Foo)] |
51 | /// impl i32 { fn hello() {} } |
52 | /// ``` |
53 | /// |
54 | /// expands to: |
55 | /// ``` |
56 | /// pub trait Foo { fn hello(); } |
57 | /// impl Foo for i32 { fn hello() {} } |
58 | /// ``` |
59 | #[proc_macro_attribute ] |
60 | pub fn extension (attr: TokenStream, input: TokenStream) -> TokenStream { |
61 | extension::extension(attr, input) |
62 | } |
63 | |
64 | decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive); |
65 | decl_derive!( |
66 | [HashStable_Generic, attributes(stable_hasher)] => |
67 | hash_stable::hash_stable_generic_derive |
68 | ); |
69 | decl_derive!( |
70 | [HashStable_NoContext] => |
71 | /// `HashStable` implementation that has no `HashStableContext` bound and |
72 | /// which adds `where` bounds for `HashStable` based off of fields and not |
73 | /// generics. This is suitable for use in crates like `rustc_type_ir`. |
74 | hash_stable::hash_stable_no_context_derive |
75 | ); |
76 | |
77 | decl_derive!([Decodable_NoContext] => serialize::decodable_nocontext_derive); |
78 | decl_derive!([Encodable_NoContext] => serialize::encodable_nocontext_derive); |
79 | decl_derive!([Decodable] => serialize::decodable_derive); |
80 | decl_derive!([Encodable] => serialize::encodable_derive); |
81 | decl_derive!([TyDecodable] => serialize::type_decodable_derive); |
82 | decl_derive!([TyEncodable] => serialize::type_encodable_derive); |
83 | decl_derive!([MetadataDecodable] => serialize::meta_decodable_derive); |
84 | decl_derive!([MetadataEncodable] => serialize::meta_encodable_derive); |
85 | decl_derive!( |
86 | [TypeFoldable, attributes(type_foldable)] => |
87 | /// Derives `TypeFoldable` for the annotated `struct` or `enum` (`union` is not supported). |
88 | /// |
89 | /// The fold will produce a value of the same struct or enum variant as the input, with |
90 | /// each field respectively folded using the `TypeFoldable` implementation for its type. |
91 | /// However, if a field of a struct or an enum variant is annotated with |
92 | /// `#[type_foldable(identity)]` then that field will retain its incumbent value (and its |
93 | /// type is not required to implement `TypeFoldable`). |
94 | type_foldable::type_foldable_derive |
95 | ); |
96 | decl_derive!( |
97 | [TypeVisitable, attributes(type_visitable)] => |
98 | /// Derives `TypeVisitable` for the annotated `struct` or `enum` (`union` is not supported). |
99 | /// |
100 | /// Each field of the struct or enum variant will be visited in definition order, using the |
101 | /// `TypeVisitable` implementation for its type. However, if a field of a struct or an enum |
102 | /// variant is annotated with `#[type_visitable(ignore)]` then that field will not be |
103 | /// visited (and its type is not required to implement `TypeVisitable`). |
104 | type_visitable::type_visitable_derive |
105 | ); |
106 | decl_derive!([Lift, attributes(lift)] => lift::lift_derive); |
107 | decl_derive!( |
108 | [Diagnostic, attributes( |
109 | // struct attributes |
110 | diag, |
111 | help, |
112 | help_once, |
113 | note, |
114 | note_once, |
115 | warning, |
116 | // field attributes |
117 | skip_arg, |
118 | primary_span, |
119 | label, |
120 | subdiagnostic, |
121 | suggestion, |
122 | suggestion_short, |
123 | suggestion_hidden, |
124 | suggestion_verbose)] => diagnostics::diagnostic_derive |
125 | ); |
126 | decl_derive!( |
127 | [LintDiagnostic, attributes( |
128 | // struct attributes |
129 | diag, |
130 | help, |
131 | help_once, |
132 | note, |
133 | note_once, |
134 | warning, |
135 | // field attributes |
136 | skip_arg, |
137 | primary_span, |
138 | label, |
139 | subdiagnostic, |
140 | suggestion, |
141 | suggestion_short, |
142 | suggestion_hidden, |
143 | suggestion_verbose)] => diagnostics::lint_diagnostic_derive |
144 | ); |
145 | decl_derive!( |
146 | [Subdiagnostic, attributes( |
147 | // struct/variant attributes |
148 | label, |
149 | help, |
150 | help_once, |
151 | note, |
152 | note_once, |
153 | warning, |
154 | subdiagnostic, |
155 | suggestion, |
156 | suggestion_short, |
157 | suggestion_hidden, |
158 | suggestion_verbose, |
159 | multipart_suggestion, |
160 | multipart_suggestion_short, |
161 | multipart_suggestion_hidden, |
162 | multipart_suggestion_verbose, |
163 | // field attributes |
164 | skip_arg, |
165 | primary_span, |
166 | suggestion_part, |
167 | applicability)] => diagnostics::subdiagnostic_derive |
168 | ); |
169 | |
170 | decl_derive! { |
171 | [TryFromU32] => |
172 | /// Derives `TryFrom<u32>` for the annotated `enum`, which must have no fields. |
173 | /// Each variant maps to the value it would produce under an `as u32` cast. |
174 | /// |
175 | /// The error type is `u32`. |
176 | try_from::try_from_u32 |
177 | } |
178 | decl_derive! { |
179 | [PrintAttribute] => |
180 | /// Derives `PrintAttribute` for `AttributeKind`. |
181 | /// This macro is pretty specific to `rustc_attr_data_structures` and likely not that useful in |
182 | /// other places. It's deriving something close to `Debug` without printing some extraenous |
183 | /// things like spans. |
184 | print_attribute::print_attribute |
185 | } |
186 | |