1#[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}
13
14#[allow(unused)]
15macro_rules! features {
16 (
17 @TARGET: $target:ident;
18 @CFG: $cfg:meta;
19 @MACRO_NAME: $macro_name:ident;
20 @MACRO_ATTRS: $(#[$macro_attrs:meta])*
21 $(@BIND_FEATURE_NAME: $bind_feature:tt; $feature_impl:tt; $(#[$deprecate_attr:meta];)?)*
22 $(@NO_RUNTIME_DETECTION: $nort_feature:tt; )*
23 $(@FEATURE: #[$stability_attr:meta] $feature:ident: $feature_lit:tt;
24 $(implied by target_features: [$($target_feature_lit:tt),*];)?
25 $(#[$feature_comment:meta])*)*
26 ) => {
27 #[macro_export]
28 $(#[$macro_attrs])*
29 #[allow_internal_unstable(stdarch_internal)]
30 #[cfg($cfg)]
31 #[doc(cfg($cfg))]
32 macro_rules! $macro_name {
33 $(
34 ($feature_lit) => {
35 $crate::detect_feature!($feature, $feature_lit $(: $($target_feature_lit),*)?)
36 };
37 )*
38 $(
39 ($bind_feature) => {
40 {
41 $(
42 #[$deprecate_attr] macro_rules! deprecated_feature { {} => {}; }
43 deprecated_feature! {};
44 )?
45 $crate::$macro_name!($feature_impl)
46 }
47 };
48 )*
49 $(
50 ($nort_feature) => {
51 compile_error!(
52 concat!(
53 stringify!($nort_feature),
54 " feature cannot be detected at run-time"
55 )
56 )
57 };
58 )*
59 ($t:tt,) => {
60 $crate::$macro_name!($t);
61 };
62 ($t:tt) => {
63 compile_error!(
64 concat!(
65 concat!("unknown ", stringify!($target)),
66 concat!(" target feature: ", $t)
67 )
68 )
69 };
70 }
71
72 $(#[$macro_attrs])*
73 #[macro_export]
74 #[cfg(not($cfg))]
75 #[doc(cfg($cfg))]
76 macro_rules! $macro_name {
77 $(
78 ($feature_lit) => {
79 compile_error!(
80 concat!(
81 r#"This macro cannot be used on the current target.
82 You can prevent it from being used in other architectures by
83 guarding it behind a cfg("#,
84 stringify!($cfg),
85 ")."
86 )
87 )
88 };
89 )*
90 $(
91 ($bind_feature) => { $crate::$macro_name!($feature_impl) };
92 )*
93 $(
94 ($nort_feature) => {
95 compile_error!(
96 concat!(
97 stringify!($nort_feature),
98 " feature cannot be detected at run-time"
99 )
100 )
101 };
102 )*
103 ($t:tt,) => {
104 $crate::$macro_name!($t);
105 };
106 ($t:tt) => {
107 compile_error!(
108 concat!(
109 concat!("unknown ", stringify!($target)),
110 concat!(" target feature: ", $t)
111 )
112 )
113 };
114 }
115
116 /// Each variant denotes a position in a bitset for a particular feature.
117 ///
118 /// PLEASE: do not use this, it is an implementation detail subject
119 /// to change.
120 #[doc(hidden)]
121 #[allow(non_camel_case_types)]
122 #[derive(Copy, Clone)]
123 #[repr(u8)]
124 #[unstable(feature = "stdarch_internal", issue = "none")]
125 #[cfg($cfg)]
126 pub(crate) enum Feature {
127 $(
128 $(#[$feature_comment])*
129 $feature,
130 )*
131
132 // Do not add variants after last:
133 _last
134 }
135
136 #[cfg($cfg)]
137 impl Feature {
138 pub(crate) fn to_str(self) -> &'static str {
139 match self {
140 $(Feature::$feature => $feature_lit,)*
141 Feature::_last => unreachable!(),
142 }
143 }
144 #[cfg(feature = "std_detect_env_override")]
145 pub(crate) fn from_str(s: &str) -> Result<Feature, ()> {
146 match s {
147 $($feature_lit => Ok(Feature::$feature),)*
148 _ => Err(())
149 }
150 }
151 }
152
153 /// Each function performs run-time feature detection for a single
154 /// feature. This allow us to use stability attributes on a per feature
155 /// basis.
156 ///
157 /// PLEASE: do not use this, it is an implementation detail subject
158 /// to change.
159 #[doc(hidden)]
160 #[cfg($cfg)]
161 #[unstable(feature = "stdarch_internal", issue = "none")]
162 pub mod __is_feature_detected {
163 $(
164
165 /// PLEASE: do not use this, it is an implementation detail
166 /// subject to change.
167 #[inline]
168 #[doc(hidden)]
169 #[$stability_attr]
170 pub fn $feature() -> bool {
171 $crate::detect::check_for($crate::detect::Feature::$feature)
172 }
173 )*
174 }
175 };
176}
177