@@ -121,8 +121,8 @@ fn tester(fn_arg: i32) {
121121 println!("{local_i32:width$.prec$}");
122122 println!("{width:width$.prec$}");
123123 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}" );
126126
127127 // these should NOT be modified by the lint
128128 println!(concat!("nope ", "{}"), local_i32);
@@ -160,10 +160,6 @@ fn tester(fn_arg: i32) {
160160 }
161161}
162162
163- fn main() {
164- tester(42);
165- }
166-
167163fn _under_msrv() {
168164 #![clippy::msrv = "1.57"]
169165 let local_i32 = 1;
@@ -175,3 +171,94 @@ fn _meets_msrv() {
175171 let local_i32 = 1;
176172 println!("expand='{local_i32}'");
177173}
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