std_detect/detect/
macros.rs1#[macro_export]
2#[allow_internal_unstable(stdarch_internal)]
3#[unstable(feature = "stdarch_internal", issue = "none")]
4macro_rules! detect_feature {
5 ($feature:tt, $feature_lit:tt) => {
6 $crate::detect_feature!($feature, $feature_lit : $feature_lit)
7 };
8 ($feature:tt, $feature_lit:tt : $($target_feature_lit:tt),*) => {
9 $(cfg!(target_feature = $target_feature_lit) ||)*
10 $crate::detect::__is_feature_detected::$feature()
11 };
12 ($feature:tt, $feature_lit:tt, without cfg check: true) => {
13 $crate::detect::__is_feature_detected::$feature()
14 };
15}
16
17#[allow(unused_macros, reason = "it's used in the features! macro below")]
18macro_rules! check_cfg_feature {
19 ($feature:tt, $feature_lit:tt) => {
20 check_cfg_feature!($feature, $feature_lit : $feature_lit)
21 };
22 ($feature:tt, $feature_lit:tt : $($target_feature_lit:tt),*) => {
23 $(cfg!(target_feature = $target_feature_lit);)*
24 };
25 ($feature:tt, $feature_lit:tt, without cfg check: $feature_cfg_check:literal) => {
26 #[allow(unexpected_cfgs, reason = $feature_lit)]
27 { cfg!(target_feature = $feature_lit) }
28 };
29}
30
31#[allow(unused)]
32macro_rules! features {
33 (
34 @TARGET: $target:ident;
35 @CFG: $cfg:meta;
36 @MACRO_NAME: $macro_name:ident;
37 @MACRO_ATTRS: $(#[$macro_attrs:meta])*
38 $(@BIND_FEATURE_NAME: $bind_feature:tt; $feature_impl:tt; $(#[$deprecate_attr:meta];)?)*
39 $(@NO_RUNTIME_DETECTION: $nort_feature:tt; )*
40 $(@FEATURE: #[$stability_attr:meta] $feature:ident: $feature_lit:tt;
41 $(without cfg check: $feature_cfg_check:tt;)?
42 $(implied by target_features: [$($target_feature_lit:tt),*];)?
43 $(#[$feature_comment:meta])*)*
44 ) => {
45 #[macro_export]
46 $(#[$macro_attrs])*
47 #[allow_internal_unstable(stdarch_internal)]
48 #[cfg($cfg)]
49 #[doc(cfg($cfg))]
50 macro_rules! $macro_name {
51 $(
52 ($feature_lit) => {
53 $crate::detect_feature!($feature, $feature_lit $(, without cfg check: $feature_cfg_check)? $(: $($target_feature_lit),*)?)
54 };
55 )*
56 $(
57 ($bind_feature) => {
58 {
59 $(
60 #[$deprecate_attr] macro_rules! deprecated_feature { {} => {}; }
61 deprecated_feature! {};
62 )?
63 $crate::$macro_name!($feature_impl)
64 }
65 };
66 )*
67 $(
68 ($nort_feature) => {
69 compile_error!(
70 concat!(
71 stringify!($nort_feature),
72 " feature cannot be detected at run-time"
73 )
74 )
75 };
76 )*
77 ($t:tt,) => {
78 $crate::$macro_name!($t);
79 };
80 ($t:tt) => {
81 compile_error!(
82 concat!(
83 concat!("unknown ", stringify!($target)),
84 concat!(" target feature: ", $t)
85 )
86 )
87 };
88 }
89
90 $(#[$macro_attrs])*
91 #[macro_export]
92 #[cfg(not($cfg))]
93 #[doc(cfg($cfg))]
94 macro_rules! $macro_name {
95 $(
96 ($feature_lit) => {
97 compile_error!(
98 concat!(
99 r#"This macro cannot be used on the current target.
100 You can prevent it from being used in other architectures by
101 guarding it behind a cfg("#,
102 stringify!($cfg),
103 ")."
104 )
105 )
106 };
107 )*
108 $(
109 ($bind_feature) => { $crate::$macro_name!($feature_impl) };
110 )*
111 $(
112 ($nort_feature) => {
113 compile_error!(
114 concat!(
115 stringify!($nort_feature),
116 " feature cannot be detected at run-time"
117 )
118 )
119 };
120 )*
121 ($t:tt,) => {
122 $crate::$macro_name!($t);
123 };
124 ($t:tt) => {
125 compile_error!(
126 concat!(
127 concat!("unknown ", stringify!($target)),
128 concat!(" target feature: ", $t)
129 )
130 )
131 };
132 }
133
134 #[test]
135 #[deny(unexpected_cfgs)]
136 #[deny(unfulfilled_lint_expectations)]
137 fn unexpected_cfgs() {
138 $(
139 check_cfg_feature!($feature, $feature_lit $(, without cfg check: $feature_cfg_check)? $(: $($target_feature_lit),*)?);
140 )*
141 }
142
143 #[doc(hidden)]
148 #[allow(non_camel_case_types)]
149 #[derive(Copy, Clone)]
150 #[repr(u8)]
151 #[unstable(feature = "stdarch_internal", issue = "none")]
152 #[cfg($cfg)]
153 pub(crate) enum Feature {
154 $(
155 $(#[$feature_comment])*
156 $feature,
157 )*
158
159 _last
161 }
162
163 #[cfg($cfg)]
164 impl Feature {
165 pub(crate) fn to_str(self) -> &'static str {
166 match self {
167 $(Feature::$feature => $feature_lit,)*
168 Feature::_last => unreachable!(),
169 }
170 }
171 }
172
173 #[doc(hidden)]
180 #[cfg($cfg)]
181 #[unstable(feature = "stdarch_internal", issue = "none")]
182 pub mod __is_feature_detected {
183 $(
184
185 #[inline]
188 #[doc(hidden)]
189 #[$stability_attr]
190 pub fn $feature() -> bool {
191 $crate::detect::check_for($crate::detect::Feature::$feature)
192 }
193 )*
194 }
195 };
196}