1 | #[macro_export ] |
2 | #[allow_internal_unstable (stdarch_internal)] |
3 | #[unstable (feature = "stdarch_internal" , issue = "none" )] |
4 | macro_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)] |
15 | macro_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 | |