1#[macro_export]
4#[doc(hidden)]
5macro_rules! __ctor_parse {
6 ( $($input:tt)* ) => {
7 $crate::__perform!(
8 ($($input)*),
9 $crate::__chain[
10 $crate::__parse_item[$crate::__ctor_features],
11 $crate::__extract_unsafe,
12 $crate::__ctor_parse_impl,
13 ]
14 );
15 };
16}
17
18#[macro_export]
19#[doc(hidden)]
20macro_rules! __ctor_parse_internal {
21 ( $features:path, $($input:tt)* ) => {
22 $crate::__perform!(
23 ($($input)*),
24 $crate::__chain[
25 $crate::__parse_item[$features],
26 $crate::__extract_unsafe,
27 $crate::__ctor_parse_impl,
28 ]
29 );
30 };
31}
32
33#[macro_export]
36#[doc(hidden)]
37macro_rules! __ctor_parse_impl {
38 ( @entry next=$next:path[$next_args:tt], input=(
40 features = (
41 anonymous = $anonymous:tt,
42 crate_path = $crate_path:tt,
43 dtor = $dtor:tt,
44 export_name_prefix = $export_name_prefix:tt,
45 link_section = $link_section:tt,
46 no_warn_on_missing_unsafe = $no_warn_on_missing_unsafe:tt,
47 priority = $priority:tt,
48 priority_enabled = $priority_enabled:tt,
49 proc_macro = $proc_macro:tt,
50 std = $std:tt,
51 used_linker = $used_linker:tt,
52 ),
53 meta = $meta:tt,
54 unsafe = $unsafe:tt,
55 item = $item:tt
56 )) => {
57 $crate::__ctor_parse_impl!(@checkfail priority=$priority priority_enabled=priority_enabled);
58
59 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
60 features = (
61 anonymous = $anonymous,
62 export_name_prefix = $export_name_prefix,
63 link_section = $link_section,
64 no_warn_on_missing_unsafe = $no_warn_on_missing_unsafe,
65 priority = $priority,
66 used_linker = $used_linker,
67 ),
68 meta = $meta,
69 unsafe = $unsafe,
70 item = $item
71 ));
72 };
73
74 ( @checkfail priority=() priority_enabled=$any:tt ) => {};
75 ( @checkfail priority=$any:tt priority_enabled=priority_enabled ) => {};
76 ( @checkfail priority=$any1:tt priority_enabled=$any2:tt ) => {
77 compile_error!("The priority feature is not enabled, so `priority = N` is not supported.");
78 };
79
80 ( @checkfail $($rest:tt)* ) => {};
81
82 ( @entry next=$next:path[$next_args:tt], input=(
84 features = (
85 anonymous = $anonymous:tt,
86 export_name_prefix = $export_name_prefix:tt,
87 link_section = $link_section:tt,
88 no_warn_on_missing_unsafe = $no_warn_on_missing_unsafe:tt,
89 priority = $priority:tt,
90 used_linker = $used_linker:tt,
91 ),
92 meta = $meta:tt,
93 unsafe = ($($unsafe:tt)?),
94 item = ($vis:vis $(unsafe)? $( extern $abi:literal )? fn $name:ident () $( -> () )? {
95 $($body:tt)*
96 })
97 ) ) => {
98 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
99 features = (
100 anonymous = $anonymous,
101 link_name = $name,
102 export_name_prefix = $export_name_prefix,
103 link_section = $link_section,
104 no_warn_on_missing_unsafe = $no_warn_on_missing_unsafe,
105 priority = $priority,
106 used_linker = $used_linker,
107 ),
108 meta = $meta,
109 unsafe = ($($unsafe)?),
110 item = ($vis $($unsafe)? $( extern $abi )? fn $name () {
111 $($body)*
112 })
113 ));
114 };
115
116 ( @entry next=$next:path[$next_args:tt], input=(
117 features = (
118 anonymous = $anonymous:tt,
119 export_name_prefix = $export_name_prefix:tt,
120 link_section = $link_section:tt,
121 no_warn_on_missing_unsafe = $no_warn_on_missing_unsafe:tt,
122 priority = $priority:tt,
123 used_linker = $used_linker:tt,
124 ),
125 meta = $meta:tt,
126 unsafe = $unsafe:tt,
127 item = ($vis:vis static $ident:ident : $ty:ty = $(unsafe)? { $literal:literal };)
128 ) ) => {
129 compile_error!("Trivial const expressions are not supported. Remove the #[ctor] and use a regular `static`.");
130 };
131
132 ( @entry next=$next:path[$next_args:tt], input=(
133 features = (
134 anonymous = $anonymous:tt,
135 export_name_prefix = $export_name_prefix:tt,
136 link_section = $link_section:tt,
137 no_warn_on_missing_unsafe = $no_warn_on_missing_unsafe:tt,
138 priority = $priority:tt,
139 used_linker = $used_linker:tt,
140 ),
141 meta = $meta:tt,
142 unsafe = $unsafe:tt,
143 item = ($vis:vis static $ident:ident : $ty:ty = $(unsafe)? const $body:block;)
144 ) ) => {
145 compile_error!("Trivial const expressions are not supported. Remove the #[ctor] and use a regular `static`.");
146 };
147
148 ( @entry next=$next:path[$next_args:tt], input=(
149 features = (
150 anonymous = $anonymous:tt,
151 export_name_prefix = $export_name_prefix:tt,
152 link_section = $link_section:tt,
153 no_warn_on_missing_unsafe = $no_warn_on_missing_unsafe:tt,
154 priority = $priority:tt,
155 used_linker = $used_linker:tt,
156 ),
157 meta = $meta:tt,
158 unsafe = $unsafe:tt,
159 item = ($vis:vis static $ident:ident : $ty:ty = $(unsafe)? $literal:literal;)
160 ) ) => {
161 compile_error!("Trivial const expressions are not supported. Remove the #[ctor] and use a regular `static`.");
162 };
163
164 ( @entry next=$next:path[$next_args:tt], input=(
165 features = (
166 anonymous = $anonymous:tt,
167 export_name_prefix = $export_name_prefix:tt,
168 link_section = $link_section:tt,
169 no_warn_on_missing_unsafe = $no_warn_on_missing_unsafe:tt,
170 priority = $priority:tt,
171 used_linker = $used_linker:tt,
172 ),
173 meta = $meta:tt,
174 unsafe = ($($unsafe:tt)?),
175 item = ($vis:vis static $ident:ident : $ty:ty = $(unsafe)? { $($body:tt)* };)
176 ) ) => {
177 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
178 features = (
179 anonymous = $anonymous,
180 link_name = $ident,
181 export_name_prefix = $export_name_prefix,
182 link_section = $link_section,
183 no_warn_on_missing_unsafe = $no_warn_on_missing_unsafe,
184 priority = $priority,
185 used_linker = $used_linker,
186 ),
187 meta = $meta,
188 unsafe = ($($unsafe)?),
189 item = ($vis static $ident : $ty = $($unsafe)? { $($body)* };)
190 ));
191 };
192
193 ( @entry next=$next:path[$next_args:tt], input=(
194 features = (
195 anonymous = $anonymous:tt,
196 export_name_prefix = $export_name_prefix:tt,
197 link_section = $link_section:tt,
198 no_warn_on_missing_unsafe = $no_warn_on_missing_unsafe:tt,
199 priority = $priority:tt,
200 used_linker = $used_linker:tt,
201 ),
202 meta = $meta:tt,
203 unsafe = $unsafe:tt,
204 item = ($item:item)
205 ) ) => {
206 compile_error!("Invalid ctor item. \
207 Expected a function with no args, \
208 return value, or type parameters or a static variable.\n\
209 Valid forms are:\n\
210 - [pub] [unsafe] [extern $abi] fn $name() { ... }\n\
211 - static $name : $ty = [unsafe] { ... };");
212 };
213
214 ( @entry next=$next:path[$next_args:tt], input=(
218 features = (
219 anonymous = $anonymous:tt,
220 link_name = $link_name:tt,
221 export_name_prefix = $export_name_prefix:tt,
222 link_section = $link_section:tt,
223 no_warn_on_missing_unsafe = (),
224 priority = $priority:tt,
225 used_linker = $used_linker:tt,
226 ),
227 meta = $meta:tt,
228 unsafe = (),
229 item = $item:tt
230 ) ) => {
231 const _: () = {
232 #[deprecated="ctor deprecation note:\n\n\
233 Use of #[ctor] without `#[ctor(unsafe)]` or `unsafe fn` is deprecated. As code execution\n\
234 before main is unsupported by most Rust runtime functions, these functions must be marked\n\
235 `unsafe`."]
236 const fn ctor_without_unsafe_is_deprecated() {}
237 #[allow(unused)]
238 static UNSAFE_WARNING: () = {
239 ctor_without_unsafe_is_deprecated()
240 };
241 };
242
243 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
244 features = (
245 anonymous = $anonymous,
246 link_name = $link_name,
247 export_name_prefix = $export_name_prefix,
248 link_section = $link_section,
249 priority = $priority,
250 used_linker = $used_linker,
251 ),
252 meta = $meta,
253 unsafe = (),
254 item = $item
255 ));
256 };
257
258 ( @entry next=$next:path[$next_args:tt], input=(
259 features = (
260 anonymous = $anonymous:tt,
261 link_name = $link_name:tt,
262 export_name_prefix = $export_name_prefix:tt,
263 link_section = $link_section:tt,
264 no_warn_on_missing_unsafe = $no_warn_on_missing_unsafe:tt,
265 priority = $priority:tt,
266 used_linker = $used_linker:tt,
267 ),
268 meta = $meta:tt,
269 unsafe = $unsafe:tt,
270 item = $item:tt
271 ) ) => {
272 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
273 features = (
274 anonymous = $anonymous,
275 link_name = $link_name,
276 export_name_prefix = $export_name_prefix,
277 link_section = $link_section,
278 priority = $priority,
279 used_linker = $used_linker,
280 ),
281 meta = $meta,
282 unsafe = $unsafe,
283 item = $item
284 ));
285 };
286
287 ( @entry next=$next:path[$next_args:tt], input=(
289 features = (
290 anonymous = (),
291 link_name = $link_name:tt,
292 export_name_prefix = $export_name_prefix:tt,
293 link_section = $link_section:tt,
294 priority = $priority:tt,
295 used_linker = $used_linker:tt,
296 ),
297 meta = $meta:tt,
298 unsafe = $unsafe:tt,
299 item = $item:tt
300 ) ) => {
301 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
302 features = (
303 link_name = $link_name,
304 export_name_prefix = $export_name_prefix,
305 link_section = $link_section,
306 priority = $priority,
307 used_linker = $used_linker,
308 ),
309 meta = $meta,
310 unsafe = $unsafe,
311 item = $item
312 ));
313 };
314 ( @entry next=$next:path[$next_args:tt], input=(
315 features = (
316 anonymous = anonymous,
317 link_name = $link_name:tt,
318 export_name_prefix = $export_name_prefix:tt,
319 link_section = $link_section:tt,
320 priority = $priority:tt,
321 used_linker = $used_linker:tt,
322 ),
323 meta = $meta:tt,
324 unsafe = $unsafe:tt,
325 item = $item:tt
326 ) ) => {
327 const _: () = {
328 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
329 features = (
330 link_name = $link_name,
331 export_name_prefix = $export_name_prefix,
332 link_section = $link_section,
333 priority = $priority,
334 used_linker = $used_linker,
335 ),
336 meta = $meta,
337 unsafe = $unsafe,
338 item = $item
339 ));
340 };
341 };
342
343 ( @entry next=$next:path[$next_args:tt], input=(
345 features = (
346 link_name = $link_name:tt,
347 export_name_prefix = $export_name_prefix:tt,
348 link_section = $link_section:tt,
349 priority = $priority:tt,
350 used_linker = (),
351 ),
352 meta = $meta:tt,
353 unsafe = $unsafe:tt,
354 item = $item:tt
355 ) ) => {
356 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
357 features = (
358 link_name = $link_name,
359 export_name_prefix = $export_name_prefix,
360 link_section = $link_section,
361 priority = $priority,
362 used_linker_meta = (#[used]),
363 ),
364 meta = $meta,
365 unsafe = $unsafe,
366 item = $item
367 ));
368 };
369
370 ( @entry next=$next:path[$next_args:tt], input=(
371 features = (
372 link_name = $link_name:tt,
373 export_name_prefix = $export_name_prefix:tt,
374 link_section = $link_section:tt,
375 priority = $priority:tt,
376 used_linker = used_linker,
377 ),
378 meta = $meta:tt,
379 unsafe = $unsafe:tt,
380 item = $item:tt
381 ) ) => {
382 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
383 features = (
384 link_name = $link_name,
385 export_name_prefix = $export_name_prefix,
386 link_section = $link_section,
387 priority = $priority,
388 used_linker_meta = (#[used(linker)]),
389 ),
390 meta = $meta,
391 unsafe = $unsafe,
392 item = $item
393 ));
394 };
395
396 ( @entry next=$next:path[$next_args:tt], input=(
400 features = (
401 link_name = $link_name:tt,
402 export_name_prefix = (),
403 link_section = $link_section:tt,
404 priority = $priority:tt,
405 used_linker_meta = $used_linker_meta:tt,
406 ),
407 meta = $meta:tt,
408 unsafe = $unsafe:tt,
409 item = $item:tt
410 ) ) => {
411 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
412 features = (
413 link_name = (),
414 link_section = $link_section,
415 priority = $priority,
416 used_linker_meta = $used_linker_meta,
417 ),
418 meta = $meta,
419 unsafe = $unsafe,
420 item = $item
421 ));
422 };
423
424 ( @entry next=$next:path[$next_args:tt], input=(
425 features = (
426 link_name = $link_name:tt,
427 export_name_prefix = $export_name_prefix:tt,
428 link_section = $link_section:tt,
429 priority = (),
430 used_linker_meta = $used_linker_meta:tt,
431 ),
432 meta = $meta:tt,
433 unsafe = $unsafe:tt,
434 item = $item:tt
435 ) ) => {
436 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
437 features = (
438 link_name = (concat!($export_name_prefix,
439 "0_",
440 env!("CARGO_PKG_NAME"), "_",
441 ::core::module_path!(), "_",
442 stringify!($link_name),
443 "_L", line!(), "C", column!())),
444 link_section = $link_section,
445 priority = (),
446 used_linker_meta = $used_linker_meta,
447 ),
448 meta = $meta,
449 unsafe = $unsafe,
450 item = $item
451 ));
452 };
453
454 ( @entry next=$next:path[$next_args:tt], input=(
455 features = (
456 link_name = $link_name:tt,
457 export_name_prefix = $export_name_prefix:tt,
458 link_section = $link_section:tt,
459 priority = $priority:tt,
460 used_linker_meta = $used_linker_meta:tt,
461 ),
462 meta = $meta:tt,
463 unsafe = $unsafe:tt,
464 item = $item:tt
465 ) ) => {
466 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
467 features = (
468 link_name = (concat!($export_name_prefix,
469 $priority, "_",
470 env!("CARGO_PKG_NAME"), "_",
471 ::core::module_path!(), "_",
472 stringify!($link_name),
473 "_L", line!(), "C", column!())),
474 link_section = $link_section,
475 priority = $priority,
476 used_linker_meta = $used_linker_meta,
477 ),
478 meta = $meta,
479 unsafe = $unsafe,
480 item = $item
481 ));
482 };
483
484 ( @entry next=$next:path[$next_args:tt], input=(
488 features = (
489 link_name = $link_name:tt,
490 link_section = $link_section:tt,
491 priority = (),
492 used_linker_meta = $used_linker_meta:tt,
493 ),
494 meta = $meta:tt,
495 unsafe = $unsafe:tt,
496 item = $item:tt
497 ) ) => {
498 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
499 link_args = (
500 link_name = $link_name,
501 link_section = ($link_section),
502 used = $used_linker_meta,
503 ),
504 meta = $meta,
505 unsafe = $unsafe,
506 item = $item
507 ));
508 };
509
510 ( @entry next=$next:path[$next_args:tt], input=(
511 features = (
512 link_name = $link_name:tt,
513 link_section = $link_section:tt,
514 priority = $priority:tt,
515 used_linker_meta = $used_linker_meta:tt,
516 ),
517 meta = $meta:tt,
518 unsafe = $unsafe:tt,
519 item = $item:tt
520 ) ) => {
521 #[cfg(target_vendor = "apple")]
522 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
523 link_args = (
524 link_name = $link_name,
525 priority = $priority,
526 used = $used_linker_meta,
527 ),
528 meta = $meta,
529 unsafe = $unsafe,
530 item = $item
531 ));
532
533 #[cfg(not(target_vendor = "apple"))]
535 $crate::__priority_to_literal!($crate::__ctor_parse_impl,[
536 @priority next=$next[$next_args],
537 features = (
538 link_name = $link_name,
539 link_section = $link_section,
540 used_linker_meta = $used_linker_meta,
541 ),
542 meta = $meta,
543 unsafe = $unsafe,
544 item = $item
545 ] = $priority);
546 };
547
548 ( [@priority next=$next:path[$next_args:tt],
549 features = (
550 link_name = $link_name:tt,
551 link_section = $link_section:tt,
552 used_linker_meta = $used_linker_meta:tt,
553 ),
554 meta = $meta:tt,
555 unsafe = $unsafe:tt,
556 item = $item:tt
557 ], ($($priority:tt)*)) => {
558 $crate::__ctor_parse_impl!(@entry next=$next[$next_args], input=(
559 link_args = (
560 link_name = $link_name,
561 link_section = (concat!($link_section, ".", $($priority)*)),
562 used = $used_linker_meta,
563 ),
564 meta = $meta,
565 unsafe = $unsafe,
566 item = $item
567 ));
568 };
569
570 ( @entry next=$next:path[$next_args:tt], input=(
572 link_args = $link_args:tt,
573 meta = ($($meta:tt)*),
574 unsafe = ($($unsafe:tt)*),
575 item = ($vis:vis $(unsafe)? $( extern $abi:literal )? fn $name:ident () $( -> () )? {
576 $($body:tt)*
577 })
578 ) ) => {
579 $($meta)*
580 $vis $($unsafe)* $( extern $abi )? fn $name () {
581 $crate::__ctor_parse_impl!(@ctor $link_args body={ $($unsafe)* { $name() } });
582 $($body)*
583 }
584 };
585
586 ( @entry next=$next:path[$next_args:tt], input=(
587 link_args = $link_args:tt,
588 meta = ($($meta:tt)*),
589 unsafe = ($($unsafe:tt)*),
590 item = ($vis:vis static $ident:ident : $ty:ty = $(unsafe)? { $($body:tt)* };)
591 ) ) => {
592 $($meta)*
593 $vis static $ident: $crate::statics::Static<$ty> = {
594 fn init() -> $ty {
595 $($unsafe)* {$($body)*}
596 }
597 unsafe { $crate::statics::Static::<$ty>::new(init) }
598 };
599 $crate::__ctor_parse_impl!(@ctor $link_args body={ _ = &*$ident } );
600 };
601
602 ( @ctor (
603 link_name=(),
604 link_section=($($link_section:tt)*),
605 used=(#$used_linker_meta:tt),
606 ) body=$body:tt ) => {
607 const _: () = {
608 #[allow(unsafe_code)]
609 #[cfg_attr(clippy, allow(unknown_lints, unsafe_attr_outside_unsafe))]
610 #[link_section = $($link_section)*]
611 #$used_linker_meta
612 static __CTOR_PRIVATE_REF: unsafe extern "C" fn() = {
613 #[allow(unused_unsafe)]
614 extern "C" fn __ctor_private() {
615 $body
616 }
617 __ctor_private
618 };
619 };
620 };
621
622 ( @ctor (
623 link_name=(),
624 priority=$priority:tt,
625 used=(#$used_linker_meta:tt),
626 ) body=$body:tt ) => {
627 const _: () = {
628 #[allow(unused_unsafe)]
629 fn __ctor_private() {
630 $body
631 }
632
633 $crate::__support::in_section!(
634 #[in_section(unsafe, type = (fn(), u16), name = CTOR)]
635 static __CTOR_ENTRY: (fn(), u16) = (__ctor_private, $priority);
636 );
637 };
638 };
639
640 ( @ctor (
641 link_name=($($link_name:tt)*),
642 link_section=$link_section:tt,
643 used=(#$used_linker_meta:tt),
644 ) body=$body:tt ) => {
645 const _: () = {
646 #[allow(unsafe_code)]
647 #[cfg_attr(clippy, allow(unknown_lints, unsafe_attr_outside_unsafe))]
648 const _: () = {
649 #[allow(unused_unsafe)]
650 #[no_mangle]
651 #[export_name = $($link_name)*]
652 extern "C" fn __ctor_private() {
653 $body
654 }
655 __ctor_private
656 };
657 };
658 };
659}