@@ -121,16 +121,96 @@ macro_rules! s_no_extra_traits {
121
121
) ;
122
122
}
123
123
124
- #[ allow( unused_macros) ]
125
- macro_rules! f {
126
- ( $( pub fn $i: ident( $( $arg: ident: $argty: ty) ,* ) -> $ret: ty {
127
- $( $body: stmt) ;*
128
- } ) * ) => ( $(
129
- #[ inline]
130
- pub unsafe extern fn $i( $( $arg: $argty) ,* ) -> $ret {
131
- $( $body) ;*
124
+ // This is a pretty horrible hack to allow us to conditionally mark
125
+ // some functions as 'const', without requiring users of this macro
126
+ // to care about the "const-extern-fn" feature.
127
+ //
128
+ // When 'const-extern-fn' is enabled, we emit the captured 'const' keyword
129
+ // in the expanded function.
130
+ //
131
+ // When 'const-extern-fn' is disabled, we always emit a plain 'pub unsafe extern fn'.
132
+ // Note that the expression matched by the macro is exactly the same - this allows
133
+ // users of this macro to work whether or not 'const-extern-fn' is enabled
134
+ //
135
+ // Unfortunately, we need to duplicate most of this macro between the 'cfg_if' blocks.
136
+ // This is because 'const unsafe extern fn' won't even parse on older compilers,
137
+ // so we need to avoid emitting it at all of 'const-extern-fn'.
138
+ //
139
+ // Specifically, moving the 'cfg_if' into the macro body will *not* work.
140
+ // Doing so would cause the '#[cfg(feature = "const-extern-fn")]' to be emiited
141
+ // into user code. The 'cfg' gate will not stop Rust from trying to parse the
142
+ // 'pub const unsafe extern fn', so users would get a compiler error even when
143
+ // the 'const-extern-fn' feature is disabled
144
+ //
145
+ // Note that users of this macro need to place 'const' in a weird position
146
+ // (after the closing ')' for the arguments, but before the return type).
147
+ // This was the only way I could satisfy the following two requirements:
148
+ // 1. Avoid ambuguity errors from 'macro_rules!' (which happen when writing '$foo:ident fn'
149
+ // 2. Allow users of this macro to mix 'pub fn foo' and 'pub const fn bar' within the same
150
+ // 'f!' block
151
+ cfg_if ! {
152
+ if #[ cfg( feature = "const-extern-fn" ) ] {
153
+ #[ allow( unused_macros) ]
154
+ macro_rules! f {
155
+ ( $( pub $( { $constness: ident} ) * fn $i: ident(
156
+ $( $arg: ident: $argty: ty) , *
157
+ ) -> $ret: ty {
158
+ $( $body: stmt) ; *
159
+ } ) * ) => ( $(
160
+ #[ inline]
161
+ pub $( $constness) * unsafe extern fn $i( $( $arg: $argty) , *
162
+ ) -> $ret {
163
+ $( $body) ; *
164
+ }
165
+ ) * )
132
166
}
133
- ) * )
167
+
168
+ #[ allow( unused_macros) ]
169
+ macro_rules! const_fn {
170
+ ( $( $( { $constness: ident} ) * fn $i: ident(
171
+ $( $arg: ident: $argty: ty) , *
172
+ ) -> $ret: ty {
173
+ $( $body: stmt) ; *
174
+ } ) * ) => ( $(
175
+ #[ inline]
176
+ $( $constness) * fn $i( $( $arg: $argty) , *
177
+ ) -> $ret {
178
+ $( $body) ; *
179
+ }
180
+ ) * )
181
+ }
182
+
183
+ } else {
184
+ #[ allow( unused_macros) ]
185
+ macro_rules! f {
186
+ ( $( pub $( { $constness: ident} ) * fn $i: ident(
187
+ $( $arg: ident: $argty: ty) , *
188
+ ) -> $ret: ty {
189
+ $( $body: stmt) ; *
190
+ } ) * ) => ( $(
191
+ #[ inline]
192
+ pub unsafe extern fn $i( $( $arg: $argty) , *
193
+ ) -> $ret {
194
+ $( $body) ; *
195
+ }
196
+ ) * )
197
+ }
198
+
199
+ #[ allow( unused_macros) ]
200
+ macro_rules! const_fn {
201
+ ( $( $( { $constness: ident} ) * fn $i: ident(
202
+ $( $arg: ident: $argty: ty) , *
203
+ ) -> $ret: ty {
204
+ $( $body: stmt) ; *
205
+ } ) * ) => ( $(
206
+ #[ inline]
207
+ fn $i( $( $arg: $argty) , *
208
+ ) -> $ret {
209
+ $( $body) ; *
210
+ }
211
+ ) * )
212
+ }
213
+ }
134
214
}
135
215
136
216
#[ allow( unused_macros) ]
0 commit comments