1#![doc = include_str!("../doc.md")]
2
3extern crate proc_macro;
12
13#[doc(hidden)]
14pub mod __private;
15
16mod err_syn;
17mod fmt;
18
19#[macro_export]
21macro_rules! proc_macro_api {
22 ($($tt:tt)+) => {
23 $crate::proc_macro_api_parse_seg! {
24 [] [ { $($tt)+ } ] []
25 [
26 [] [] []
27 [ [] [] ]
28 ]
29 }
30 };
31 () => {};
32}
33
34#[doc(hidden)]
35#[macro_export]
36macro_rules! proc_macro_api_err_attr_mul {
37 ($msg:expr , [ $($note:expr),* $(,)? ] , $plural_s:expr =>
39 [ $first_0:tt $($first:tt)* ] [ $second_0:tt $($second:tt)* ]
40 $path:tt
41 ) => {
42 $crate::__private::compile_error!($crate::__private::concat!(
43 $msg,
44 "\n/ #", $crate::__private::stringify!($first_0),
45 $("\n| #", $crate::__private::stringify!($first),)*
46 "\n|_^ the first attribute", $plural_s,
47 "\n...",
48 "\n/ #", $crate::__private::stringify!($second_0),
49 $("\n| #", $crate::__private::stringify!($second),)*
50 "\n|_^ the second attribute", $plural_s,
51 "\n\n ", $crate::proc_macro_api_fmt_path!($path),
52 "\n ^\n",
53 $("\n= note: ", $note,)*
54 ));
55 };
56}
57
58#[cfg(not(feature = "deny_shadow"))]
59#[doc(hidden)]
60#[macro_export]
61macro_rules! proc_macro_api_err_attr_shadow {
62 ($($tt:tt)*) => {};
63}
64
65#[cfg(feature = "deny_shadow")]
66#[doc(hidden)]
67#[macro_export]
68macro_rules! proc_macro_api_err_attr_shadow {
69 ([] $_0:tt $_1:tt) => {};
70
71 ($proc:tt $cover:tt $path:tt) => {
73 $crate::proc_macro_api_err_attr_mul! {
74 "multiple proc-macro attributes are applied together",
75 [
76 "feature `deny_shadow` is enabled",
77 "disabling the feature to \
78leave the possible error to the compiler",
79 ],
80 "" =>
81 $proc [ $cover ] $path
82 }
83 };
84}
85
86#[cfg(not(feature = "deny_override"))]
87#[doc(hidden)]
88#[macro_export]
89macro_rules! proc_macro_api_err_attr_override {
90 ($($tt:tt)*) => {};
91}
92
93#[cfg(feature = "deny_override")]
94#[doc(hidden)]
95#[macro_export]
96macro_rules! proc_macro_api_err_attr_override {
97 ($_0:tt $($_1:tt)?) => {};
98
99 ($old:tt $new:tt $path:tt) => {
101 $crate::proc_macro_api_err_attr_mul! {
102 "attributes are overridden inside one path",
103 [ "feature `deny_override` is enabled" ],
104 "(s)" =>
105 $old $new $path
106 }
107 };
108}
109
110#[doc(hidden)]
111#[macro_export]
112macro_rules! proc_macro_api_parse_attr {
113 (
115 [ [ doc $($arg_doc:tt)* ] $(, $at:tt)* ]
116 [ $($doc:tt)* ] $other:tt $proc:tt
117 [ $($seg:tt $($rest:tt)*)? ]
118 [ $($prv:tt)* ] [ $last:tt $($to_prv:tt)? ]
119 $bag:tt
120 ) => {
121 $crate::proc_macro_api_parse_attr! {
122 [ $($at),* ] [ $($doc)* [ doc $($arg_doc)* ] ] $other $proc
123 [ $($($rest)*)? ] [ $($prv)* $($to_prv)? ] [ $($seg)? $last ]
124 $bag
125 }
126 };
127
128 (
130 [] [ $($doc:tt)* ] [ $($($other:tt)+)? ] [
131 $([ proc_macro $($arg_fn_0:tt)* ])?
132 $([ fn $($arg_fn:tt)* ])?
133 $([ proc_macro_attribute $($arg_at_0:tt)* ])?
134 $([ at $($arg_at:tt)* ])?
135 $([ proc_macro_derive $($arg_dr_0:tt)* ])?
136 $([ dr $($arg_dr:tt)* ])?
137 ]
138 [ $($seg:tt)* ]
139 [ $($prv:tt)* ] [ $last:tt $($to_prv:tt)? ]
140 [
141 [ $($bg_proc:tt)? ] [ $($bg_doc:tt)* ] [ $($bg_oth:tt)? ]
142 [ $($bg_prv:tt)* ] $path:tt
143 ]
144 ) => {
145 $crate::proc_macro_api_err_attr_override! {
146 $($bg_oth)? $([ $($other)+ ])?
147 [ $($prv)* $($to_prv)? $last $($seg)* ]
148 }
149 $crate::proc_macro_api_parse_seg! {
150 [ $($seg)* ] [ $last ] [ $($bg_prv)* $($prv)* $($to_prv)? ]
151 [
152 [
153 $([ proc_macro $($arg_fn_0)* ] ;)?
154 $([ proc_macro $($arg_fn)* ] ;)?
155 $([ proc_macro_attribute $($arg_at_0)* ] ;)?
156 $([ proc_macro_attribute $($arg_at)* ] ;)?
157 $([ proc_macro_derive $($arg_dr_0)* ] ;)?
158 $([ proc_macro_derive $($arg_dr)* ] ;)?
159 $($bg_proc)?
160 ] [
161 $($bg_doc)*
162 $($doc)*
163 ] [
164 $([ $($other)+ ] ;)?
165 $($bg_oth)?
166 ] $path
167 ]
168 }
169 };
170
171 (
175 [
176 $([ proc_macro $($arg_fn_0:tt)* ])?
177 $([ fn $($arg_fn:tt)* ])?
178 $([ proc_macro_attribute $($arg_at_0:tt)* ])?
179 $([ at $($arg_at:tt)* ])?
180 $([ proc_macro_derive $($arg_dr_0:tt)* ])?
181 $([ dr $($arg_dr:tt)* ])?
182 $(, $at:tt)*
183 ]
184 $doc:tt [ $($other:tt)* ] [ $($proc:tt)? ]
185 [ $($seg:tt $($rest:tt)*)? ]
186 [ $($prv:tt)* ] [ $last:tt $($to_prv:tt)? ]
187 $bag:tt
188 ) => {
189 $crate::proc_macro_api_err_attr_shadow! {
190 [ $($proc)? ]
191 $([proc_macro$($arg_fn_0)*])?
192 $([fn$($arg_fn)*])?
193 $([proc_macro_attribute$($arg_at_0)*])?
194 $([at$($arg_at)*])?
195 $([proc_macro_derive$($arg_dr_0)*])?
196 $([dr$($arg_dr)*])?
197 [ $($prv)* $($to_prv)? $last $($seg $($rest)*)? ]
198 }
199 $crate::proc_macro_api_parse_attr! {
200 [ $($at),* ] $doc
201 [ $($other)*
202 $([ proc_macro $($arg_fn_0)* ])?
203 $([ proc_macro $($arg_fn)* ])?
204 $([ proc_macro_attribute $($arg_at_0)* ])?
205 $([ proc_macro_attribute $($arg_at)* ])?
206 $([ proc_macro_derive $($arg_dr_0)* ])?
207 $([ proc_macro_derive $($arg_dr)* ])?
208 ] [
209 $([proc_macro$($arg_fn_0)*])?
210 $([fn$($arg_fn)*])?
211 $([proc_macro_attribute$($arg_at_0)*])?
212 $([at$($arg_at)*])?
213 $([proc_macro_derive$($arg_dr_0)*])?
214 $([dr$($arg_dr)*])?
215 ]
216 [ $($($rest)*)? ] [ $($prv)* $($to_prv)? ] [ $($seg)? $last ]
217 $bag
218 }
219 };
220
221 (
223 [ $any:tt $(, $at:tt)* ]
224 [ $($doc:tt)* ] $other:tt $proc:tt
225 [ $($seg:tt $($rest:tt)*)? ]
226 [ $($prv:tt)* ] [ $last:tt $($to_prv:tt)? ]
227 $bag:tt
228 ) => {
229 $crate::proc_macro_api_parse_attr! {
230 [ $($at),* ] [ $($doc)* $any ] $other $proc
231 [ $($($rest)*)? ] [ $($prv)* $($to_prv)? ] [ $($seg)? $last ]
232 $bag
233 }
234 };
235}
236
237#[doc(hidden)]
238#[macro_export]
239macro_rules! proc_macro_api_parse_seg {
240 (
241 [ $seg:tt $($rest:tt)* ] [ $last:tt ] [ $($prv:tt)* ] $bag:tt
242 ) => {
243 $crate::proc_macro_api_parse_seg! {
244 [ $($rest)* ] [ $seg ] [ $($prv)* $last ] $bag
245 }
246 };
247
248 (
249 [] [
250 $($api:ident)?
251 $({
252 $(# $at_0:tt)*
253 $($seg_0:ident)?
254 $(:: $seg_cc_0:ident $(:: $rest_0:ident)*)?
255 $(:: { $($seg_blk_cc_0:tt)* })?
256 $({ $($seg_blk_0:tt)* })?
257 $(as $al_0:tt)?
258 $(,
259 $(# $at:tt)*
260 $($seg:ident)?
261 $(:: $seg_cc:ident $(:: $rest:ident)*)?
262 $(:: { $($seg_blk_cc:tt)* })?
263 $({ $($seg_blk:tt)* })?
264 $(as $al:tt)?
265 )*
266 })?
267 ] $prv:tt
268 [ $bg_proc:tt $bg_doc:tt $bg_oth:tt [ $bg_cc:tt $bg_al:tt ] ]
269 ) => {
270 $(
271 $crate::proc_macro_api_parse_fn! {
272 $bg_al $bg_proc [ $bg_doc $bg_oth $bg_cc $prv ] $api
273 }
274 )?
275 $(
276 $crate::proc_macro_api_err_seg_blk_al! {
277 $bg_al
278 }
279 $crate::proc_macro_api_parse_seg_call_attr! {
280 [
281 $(0 $bg_cc [] $seg_0)?
282 $(1 [ :: ] [ :: ] $seg_cc_0 2 [ $($rest_0)* ])?
283 $(3 [ :: ] [ :: ] { $($seg_blk_cc_0)* })?
284 $(4 $bg_cc [] { $($seg_blk_0)* })?
285 ]
286 [ $($at_0),* ] [ $($al_0)? ]
287 [ $prv $bg_cc $bg_proc $bg_doc $bg_oth ]
288 }
289 $(
290 $crate::proc_macro_api_parse_seg_call_attr! {
291 [
292 $(0 $bg_cc [] $seg)?
293 $(1 [ :: ] [ :: ] $seg_cc 2 [ $($rest)* ])?
294 $(3 [ :: ] [ :: ] { $($seg_blk_cc)* })?
295 $(4 $bg_cc [] { $($seg_blk)* })?
296 ]
297 [ $($at),* ] [ $($al)? ]
298 [ $prv $bg_cc $bg_proc $bg_doc $bg_oth ]
299 }
300 )*
301 )?
302 };
303}
304
305#[doc(hidden)]
306#[macro_export]
307macro_rules! proc_macro_api_err_seg_blk_al {
308 ([]) => {};
309
310 ([ $al:tt ]) => {
311 $crate::__private::compile_error!($crate::__private::concat!(
312 "no rules expected `as`",
313 "\n {...} as ",
314 $crate::__private::stringify!($al),
315 "\n ^^",
316 ));
317 };
318}
319
320#[doc(hidden)]
321#[macro_export]
322macro_rules! proc_macro_api_parse_seg_call_attr {
323 (
324 [
325 $_i:tt $cc:tt $cc_tag:tt $seg:tt
326 $(1 [ :: ] [ :: ] $seg_cc:tt)?
327 $(2 [ $($rest:tt)* ])?
328 $(3 [ :: ] [ :: ] $seg_blk_cc:tt)?
329 ]
330 $at:tt $al:tt
331 [
332 $prv:tt $bg_cc:tt
333 [ $($bg_proc:tt)? $(; $_0:tt)? $(;)? ] $bg_doc:tt
334 [ $($bg_oth:tt)? $(; $_1:tt)? $(;)? ]
335 ]
336 ) => {
337 $crate::proc_macro_api_err_seg_inner_cc! {
338 $cc_tag $bg_cc $prv [ $seg ]
339 }
340 $crate::proc_macro_api_err_seg_gp_attr! {
341 $at [ $_i $($seg_blk_cc)? ] [
342 $cc_tag $_i $seg $(1 $seg_cc)? $(2 [ $($rest)* ])?
343 ]
344 }
345 $crate::proc_macro_api_parse_attr! {
346 $at [] [] []
347 [ $($seg_cc)? $($($rest)*)? $($seg_blk_cc)? ] [] [ $seg ]
348 [
349 [ $($bg_proc)? ] $bg_doc [ $($bg_oth)? ]
350 $prv [ $cc $al ]
351 ]
352 }
353 };
354
355 ([] [] [] $_:tt) => { };
356
357 ([] $at:tt $al:tt $_:tt) => {
359 $crate::proc_macro_api_err_seg_no_seg! {
360 $at $al
361 }
362 };
363
364 (
366 [
367 $(0 $cc_0:tt [] $seg:tt)?
368 $(1 [ :: ] [ :: ] $seg_cc:tt)?
369 $(2 [ $($rest:tt)* ])?
370 $(3 [ :: ] [ :: ] $seg_blk_cc:tt)?
371 4 $cc_1:tt [] $seg_blk:tt
372 ]
373 $at:tt $al:tt $_:tt
374 ) => {
375 $crate::proc_macro_api_err_syn_gt_one! {
376 "" =>
377 [
378 $($seg)? $(:: $seg_cc)? $($(:: $rest)*)?
379 $(:: $seg_blk_cc)?
380 ]
381 [ $seg_blk ]
382 }
383 };
384}
385
386#[doc(hidden)]
387#[macro_export]
388macro_rules! proc_macro_api_err_seg_inner_cc {
389 ([] $_0:tt $_1:tt $_:tt) => {};
390 ([ :: ] [] [] $_:tt) => {};
391
392 ([ :: ] $_0:tt $_1:tt $path:tt) => {
394 $crate::__private::compile_error!($crate::__private::concat!(
395 "leading `::` is in the middle of a path",
396 "\n :: ",
397 $crate::proc_macro_api_fmt_path!($path),
398 "\n ^^",
399 ));
400 };
401}
402
403#[doc(hidden)]
404#[macro_export]
405macro_rules! proc_macro_api_err_seg_no_seg {
406 ([ $($at:tt)* ] [ $($al:tt)? ]) => {
408 $crate::__private::compile_error!($crate::__private::concat!(
409 "expected path segments",
410 "\n/",
411 $("\n| #", $crate::__private::stringify!($at),)*
412 $("\n| as ", $crate::__private::stringify!($al),)?
413 "\n|\n|_^ expected path segments",
414 ));
415 };
416}
417
418#[cfg(not(feature = "deny_group_attr"))]
419#[doc(hidden)]
420#[macro_export]
421macro_rules! proc_macro_api_err_seg_gp_attr {
422 ($($tt:tt)*) => {};
423}
424
425#[cfg(feature = "deny_group_attr")]
426#[doc(hidden)]
427#[macro_export]
428macro_rules! proc_macro_api_err_seg_gp_attr {
429 ([] $_:tt $path:tt) => {};
430 ($at:tt [ $(0)? $(1)? ] $path:tt) => {};
431
432 (
433 [ $at_0:tt $(, $at:tt)* ] $_:tt
434 [
435 [ $($cc:tt)? ]
436 $(0 $seg:tt)?
437 $(1 $seg_cc:tt)?
438 $(2 [ $($rest:tt)* ])?
439 $(3 $seg_blk_cc:tt)?
440 $(4 $seg_blk:tt)?
441 ]
442 ) => {
443 $crate::__private::compile_error!($crate::__private::concat!(
444 "attributes are applied to a path group",
445 "\n/ #", $crate::__private::stringify!($at_0),
446 $("\n| #", $crate::__private::stringify!($at),)*
447 "\n| ",
448 $crate::proc_macro_api_fmt_str_tt! {
449 $($cc)? $($seg ::)? $($seg_cc ::)? $($($rest ::)*)? { ... }
450 },
451 "\n|_^",
452 "\n= note: feature `deny_group_attr` is enabled",
453 ));
454 };
455}
456
457#[doc(hidden)]
458#[macro_export]
459macro_rules! proc_macro_api_err_fn_no_proc {
460 ([ $($cc:tt)? ] [ $($prv:tt)* ] [ $($al:tt)? ] $api:tt) => {
461 $crate::__private::compile_error!($crate::__private::concat!(
462 "expected a proc-macro attribute",
463 "\n/ ", $($crate::__private::stringify!($cc),)?
464 $($crate::__private::stringify!($prv), "::",)*
465 $crate::__private::stringify!($api),
466 $("\n| as ", $crate::__private::stringify!($al),)?
467 "\n|_^",
468 ));
469 };
470}
471
472#[doc(hidden)]
473#[macro_export]
474macro_rules! proc_macro_api_parse_fn {
475 ([ _ ] $proc:tt $bag:tt $api:tt) => { };
476
477 ($al:tt [] [ $_0:tt $_1:tt $cc:tt $prv:tt ] $api:tt) => {
478 $crate::proc_macro_api_err_fn_no_proc!($cc $prv $al $api);
479 };
480
481 (
483 [ $($al:tt)? ]
484 [
485 $([ proc_macro $($arg_fn:tt)* ])?
486 $([ proc_macro_attribute $($arg_at:tt)* ])?
487 $([ proc_macro_derive $($arg_dr:tt)* ])?
488 $(; $_0:tt)? $(;)?
489 ]
490 [ $doc:tt [ $other:tt $(; $_1:tt)? $(;)? ] $cc:tt $prv:tt ]
491 $api:tt
492 ) => {
493 $crate::proc_macro_api_fn! {
494 $doc $other $cc $prv $api [ $($al)? $api ]
495 $((input) [ $($arg_fn)* ])?
496 $((args, item) [ $($arg_at)* ])?
497 $((item) [ $($arg_dr)* ])?
498 }
499 };
500}
501
502#[doc(hidden)]
503#[macro_export]
504macro_rules! proc_macro_api_fn {
505 (
506 [ $($doc:tt)* ] [ $($other:tt)* ]
507 [ $($cc:tt)? ] [ $($prv:tt)* ] $api:tt [ $name:tt $($_0:tt)? ]
508 ( $($args:tt),* $(,)? ) $_1:tt
509 ) => {
510 $(# $doc)*
511 $(# $other)*
512 pub fn $name (
513 $($args : $crate::__private::TokenStream),*
514 ) -> $crate::__private::TokenStream {
515 $crate::proc_macro_api_call! {
516 ( $($args),* ) $($cc)? $($prv ::)* $api
517 }
518 }
519 };
520}
521
522#[cfg(not(feature = "auto_transform"))]
523#[doc(hidden)]
524#[macro_export]
525macro_rules! proc_macro_api_call {
526 ($args:tt $($path:tt)*) => {
527 $($path)* $args
528 };
529}
530
531#[cfg(feature = "auto_transform")]
532#[doc(hidden)]
533#[macro_export]
534macro_rules! proc_macro_api_call {
535 (( $($args:tt),* ) $($path:tt)*) => {
536 $crate::__private::From::from(
537 $($path)* (
538 $($crate::__private::From::from($args),)*
539 ),
540 )
541 };
542}