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