@@ -121,8 +121,8 @@ fn tester(fn_arg: i32) {
121
121
println!("{local_i32:width$.prec$}");
122
122
println!("{width:width$.prec$}");
123
123
println!("{}", format!("{local_i32}"));
124
- my_println!("{}", local_i32 );
125
- my_println_args!("{}", local_i32 );
124
+ my_println!("{local_i32}" );
125
+ my_println_args!("{local_i32}" );
126
126
127
127
// these should NOT be modified by the lint
128
128
println!(concat!("nope ", "{}"), local_i32);
@@ -160,10 +160,6 @@ fn tester(fn_arg: i32) {
160
160
}
161
161
}
162
162
163
- fn main() {
164
- tester(42);
165
- }
166
-
167
163
fn _under_msrv() {
168
164
#![clippy::msrv = "1.57"]
169
165
let local_i32 = 1;
@@ -175,3 +171,94 @@ fn _meets_msrv() {
175
171
let local_i32 = 1;
176
172
println!("expand='{local_i32}'");
177
173
}
174
+
175
+ macro_rules! _internal {
176
+ ($($args:tt)*) => {
177
+ println!("{}", format_args!($($args)*))
178
+ };
179
+ }
180
+
181
+ macro_rules! my_println2 {
182
+ ($target:expr, $($args:tt)+) => {{
183
+ if $target {
184
+ _internal!($($args)+)
185
+ }
186
+ }};
187
+ }
188
+
189
+ macro_rules! my_println2_args {
190
+ ($target:expr, $($args:tt)+) => {{
191
+ if $target {
192
+ _internal!("foo: {}", format_args!($($args)+))
193
+ }
194
+ }};
195
+ }
196
+
197
+ macro_rules! my_concat {
198
+ ($fmt:literal $(, $e:expr)*) => {
199
+ println!(concat!("ERROR: ", $fmt), $($e,)*)
200
+ }
201
+ }
202
+
203
+ macro_rules! my_good_macro {
204
+ ($fmt:literal $(, $e:expr)* $(,)?) => {
205
+ println!($fmt $(, $e)*)
206
+ }
207
+ }
208
+
209
+ macro_rules! my_bad_macro {
210
+ ($fmt:literal, $($e:expr),*) => {
211
+ println!($fmt, $($e,)*)
212
+ }
213
+ }
214
+
215
+ macro_rules! my_bad_macro2 {
216
+ ($fmt:literal) => {
217
+ let s = $fmt.clone();
218
+ println!("{}", s);
219
+ };
220
+ ($fmt:literal, $($e:expr)+) => {
221
+ println!($fmt, $($e,)*)
222
+ };
223
+ }
224
+
225
+ // This abomination was suggested by @Alexendoo, may the Rust gods have mercy on their soul...
226
+ // https://github.com/rust-lang/rust-clippy/pull/9948#issuecomment-1327965962
227
+ macro_rules! used_twice {
228
+ (
229
+ large = $large:literal,
230
+ small = $small:literal,
231
+ $val:expr,
232
+ ) => {
233
+ if $val < 5 {
234
+ println!($small, $val);
235
+ } else {
236
+ println!($large, $val);
237
+ }
238
+ };
239
+ }
240
+
241
+ fn tester2() {
242
+ let local_i32 = 1;
243
+ my_println2_args!(true, "{local_i32}");
244
+ my_println2!(true, "{local_i32}");
245
+ my_concat!("{}", local_i32);
246
+ my_good_macro!("{local_i32}");
247
+ my_good_macro!("{local_i32}",);
248
+
249
+ // FIXME: Broken false positives, currently unhandled
250
+ // my_bad_macro!("{}", local_i32);
251
+ // my_bad_macro2!("{}", local_i32);
252
+ // used_twice! {
253
+ // large = "large value: {}",
254
+ // small = "small value: {}",
255
+ // local_i32,
256
+ // };
257
+ }
258
+
259
+ // Add new tests right above this line to keep existing test line numbers intact.
260
+ // The main function is the only one that be kept at the end.
261
+ fn main() {
262
+ tester(42);
263
+ tester2();
264
+ }
0 commit comments