1+ /// Forward a literal to the relevant `__is_feature_detected` function.
12#[ macro_export]
23#[ allow_internal_unstable( stdarch_internal) ]
34#[ unstable( feature = "stdarch_internal" , issue = "none" ) ]
@@ -6,6 +7,7 @@ macro_rules! detect_feature {
67 $crate:: detect_feature!( $feature, $feature_lit : $feature_lit)
78 } ;
89 ( $feature: tt, $feature_lit: tt : $( $target_feature_lit: tt) ,* ) => {
10+ // Emit `true` if enabled at compile time
911 $( cfg!( target_feature = $target_feature_lit) ||) *
1012 $crate:: detect:: __is_feature_detected:: $feature( )
1113 } ;
@@ -14,6 +16,7 @@ macro_rules! detect_feature {
1416 } ;
1517}
1618
19+ /// Verify that all features are known by `cfg!`.
1720#[ allow( unused_macros, reason = "it's used in the features! macro below" ) ]
1821macro_rules! check_cfg_feature {
1922 ( $feature: tt, $feature_lit: tt) => {
@@ -28,21 +31,34 @@ macro_rules! check_cfg_feature {
2831 } ;
2932}
3033
34+ /// Create the `is_*_feature_detected` macro for an architecture.
3135// Make sure any additions to this macro are tested in
3236// `tests/ui/std/is_arch_feature_detected.AARCH64.stderr`.
3337#[ allow( unused) ]
3438macro_rules! features {
3539 (
36- @TARGET : $target: ident;
37- @CFG : $cfg: meta;
38- @MACRO_NAME : $macro_name: ident;
39- @MACRO_ATTRS : $( #[ $macro_attrs: meta] ) *
40- $( @BIND_FEATURE_NAME : $bind_feature: tt; $feature_impl: tt; $( #[ $deprecate_attr: meta] ; ) ?) *
41- $( @NO_RUNTIME_DETECTION : $nort_feature: tt; ) *
42- $( @FEATURE : #[ $stability_attr: meta] $feature: ident: $feature_lit: tt;
43- $( without cfg check: $feature_cfg_check: tt; ) ?
44- $( implied by target_features: [ $( $target_feature_lit: tt) ,* ] ; ) ?
45- $( #[ $feature_comment: meta] ) * ) *
40+ // Target or target family name, for use in diagnostic messages
41+ @TARGET : $target: ident;
42+ // Cfg for which this macro should be allowed
43+ @CFG : $cfg: meta;
44+ // Name like `is_*_feature_detected`
45+ @MACRO_NAME : $macro_name: ident;
46+ // Docs and stability attributes
47+ @MACRO_ATTRS : $( #[ $macro_attrs: meta] ) *
48+ // Synonyms, with possible deprecation
49+ $( @BIND_FEATURE_NAME : $bind_feature: tt; $feature_impl: tt; $( #[ $deprecate_attr: meta] ; ) ?) *
50+ // Features that exist but can't be detected at runtime, so emit an error.
51+ $( @NO_RUNTIME_DETECTION : $nort_feature: tt; ) *
52+ // List of features
53+ $( @FEATURE : #[ $stability_attr: meta] $feature: ident: $feature_lit: tt;
54+ // Skip verifying that the feature is known by `cfg!`, which also skips emitting `true`
55+ // if the feature is enabled at compile time.
56+ $( without cfg check: $feature_cfg_check: tt; ) ?
57+ // If this feature is always enabled by some other feature, we can avoid the cost of
58+ // checking them separately by instead only checking the root features.
59+ $( implied by target_features: [ $( $target_feature_lit: tt) ,* ] ; ) ?
60+ // Doc comment for the feature.
61+ $( #[ $feature_comment: meta] ) * ) *
4662 ) => {
4763 // The current arch's version actually does the feature detection.
4864 #[ macro_export]
@@ -51,11 +67,18 @@ macro_rules! features {
5167 #[ cfg( $cfg) ]
5268 #[ doc( cfg( $cfg) ) ]
5369 macro_rules! $macro_name {
70+ // Emit all known features
5471 $(
5572 ( $feature_lit) => {
56- $crate:: detect_feature!( $feature, $feature_lit $( , without cfg check: $feature_cfg_check) ? $( : $( $target_feature_lit) ,* ) ?)
73+ $crate:: detect_feature!(
74+ $feature,
75+ $feature_lit
76+ $( , without cfg check: $feature_cfg_check) ?
77+ $( : $( $target_feature_lit) ,* ) ?
78+ )
5779 } ;
5880 ) *
81+ // Emit all aliases, with a deprecation notice if applicable
5982 $(
6083 ( $bind_feature) => {
6184 {
@@ -67,6 +90,7 @@ macro_rules! features {
6790 }
6891 } ;
6992 ) *
93+ // Emit an error for features that can't be detected at runtime
7094 $(
7195 ( $nort_feature) => {
7296 compile_error!(
@@ -77,9 +101,11 @@ macro_rules! features {
77101 )
78102 } ;
79103 ) *
104+ // Allow a trailing comma
80105 ( $t: tt, ) => {
81- $crate:: $macro_name!( $t)
106+ $crate:: $macro_name!( $t)
82107 } ;
108+ // Fallback, error for unknown target features
83109 ( $t: tt) => {
84110 compile_error!(
85111 concat!( "unknown " , stringify!( $target) , " target feature: " , $t)
@@ -93,6 +119,7 @@ macro_rules! features {
93119 #[ cfg( not( $cfg) ) ]
94120 #[ doc( cfg( $cfg) ) ]
95121 macro_rules! $macro_name {
122+ // All known features get an error
96123 $(
97124 ( $feature_lit) => {
98125 compile_error!(
@@ -104,9 +131,11 @@ macro_rules! features {
104131 )
105132 } ;
106133 ) *
134+ // Forward deprecated features
107135 $(
108136 ( $bind_feature) => { $crate:: $macro_name!( $feature_impl) } ;
109137 ) *
138+ // Emit an error for features that can't be detected at runtime
110139 $(
111140 ( $nort_feature) => {
112141 compile_error!(
@@ -117,9 +146,11 @@ macro_rules! features {
117146 )
118147 } ;
119148 ) *
149+ // Allow a trailing comma
120150 ( $t: tt, ) => {
121151 $crate:: $macro_name!( $t) ;
122152 } ;
153+ // Fallback, error for unknown target features
123154 ( $t: tt) => {
124155 compile_error!(
125156 concat!( "unknown " , stringify!( $target) , " target feature: " , $t)
@@ -131,7 +162,12 @@ macro_rules! features {
131162 #[ deny( unfulfilled_lint_expectations) ]
132163 const _: ( ) = {
133164 $(
134- check_cfg_feature!( $feature, $feature_lit $( , without cfg check: $feature_cfg_check) ? $( : $( $target_feature_lit) ,* ) ?) ;
165+ check_cfg_feature!(
166+ $feature,
167+ $feature_lit
168+ $( , without cfg check: $feature_cfg_check) ?
169+ $( : $( $target_feature_lit) ,* ) ?)
170+ ;
135171 ) *
136172 } ;
137173
0 commit comments