Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

False positive for what Clippy thinks are return statements, but which aren't. #13526

Closed
TYTheBeast opened this issue Oct 9, 2024 · 1 comment · Fixed by #13464
Closed

False positive for what Clippy thinks are return statements, but which aren't. #13526

TYTheBeast opened this issue Oct 9, 2024 · 1 comment · Fixed by #13464
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have

Comments

@TYTheBeast
Copy link

Summary

Here's the full warning:

cargo clippy --fix                                                                                                                                                                                                         ✔   1.83.022:20:41Checking wynn_build_tools v0.3.1 (/home/thomas/SourcePrograms/WynnBuilderTools-Rekindled)
warning: field assignment outside of initializer for an instance created with Default::default()
   --> src/stat/skill_point.rs:237:9
    |
237 |         weapon.req = Point::new(10, 5, 0, 5, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
note: consider initializing the variable with `items::weapon::Weapon { req: Point::new(10, 5, 0, 5, 0), add: Point::new(0, 0, 5, 5, 0), ..Default::default() }` and removing relevant reassignments
   --> src/stat/skill_point.rs:236:9
    |
236 |         let mut weapon = Weapon::default();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default
    = note: `#[warn(clippy::field_reassign_with_default)]` on by default

warning: `wynn_build_tools` (lib test) generated 1 warning
       Fixed src/search_item.rs (1 fix)
warning: unneeded `return` statement
   --> src/search_item.rs:139:6
    |
139 |     };
    |      ^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return
    = note: `#[warn(clippy::needless_return)]` on by default
help: remove `return`
    |
139 ~     }for apparel_list in &mut apparels {
140 +         if apparel_list.len() > limit {
141 +             apparel_list.truncate(limit);
142 +         }
143 +     }
144 + 
145 +     // Print the results based on the type
146 +     match args.r#type {
147 +         Some(v) => {
148 +             let apparels = match v {
149 +                 Type::Helmets => (&apparels[0], "Helmets"),
150 +                 Type::ChestPlate => (&apparels[1], "Chestplates"),
151 +                 Type::Leggings => (&apparels[2], "Leggings"),
152 +                 Type::Boots => (&apparels[3], "Boots"),
153 +                 Type::Ring => (&apparels[4], "Ring"),
154 +                 Type::Bracelet => (&apparels[5], "Bracelet"),
155 +                 Type::Necklace => (&apparels[6], "Necklace"),
156 +             };
157 +             let apparels_str = apparels
158 +                 .0
159 +                 .iter()
160 +                 .map(|v| format!("\"{}\"", v.name))
161 +                 .join(",");
162 +             println!("{}:\t{}", apparels.1, apparels_str);
163 +         }
164 +         None => {
165 +             let apparels_str: Vec<String> = apparels
166 +                 .iter()
167 +                 .map(|v| v.iter().map(|v| format!("\"{}\"", v.name)).join(","))
168 +                 .collect();
169 +             println!("Helmets:\t{}", apparels_str[0]);
170 +             println!("Chestplates:\t{}", apparels_str[1]);
171 +             println!("Leggings:\t{}", apparels_str[2]);
172 +             println!("Boots:\t\t{}", apparels_str[3]);
173 +             println!("Ring:\t\t{}", apparels_str[4]);
174 +             println!("Bracelet:\t{}", apparels_str[5]);
175 +             println!("Necklace:\t{}", apparels_str[6]);
176 +         }
177 +     }for apparel_list in &mut apparels {
178 +         if apparel_list.len() > limit {
179 +             apparel_list.truncate(limit);
180 +         }
181 +     }
182 + 
183 +     // Print the results based on the type
184 +     match args.r#type {
185 +         Some(v) => {
186 +             let apparels = match v {
187 +                 Type::Helmets => (&apparels[0], "Helmets"),
188 +                 Type::ChestPlate => (&apparels[1], "Chestplates"),
189 +                 Type::Leggings => (&apparels[2], "Leggings"),
190 +                 Type::Boots => (&apparels[3], "Boots"),
191 +                 Type::Ring => (&apparels[4], "Ring"),
192 +                 Type::Bracelet => (&apparels[5], "Bracelet"),
193 +                 Type::Necklace => (&apparels[6], "Necklace"),
194 +             };
195 +             let apparels_str = apparels
196 +                 .0
197 +                 .iter()
198 +                 .map(|v| format!("\"{}\"", v.name))
199 +                 .join(",");
200 +             println!("{}:\t{}", apparels.1, apparels_str);
201 +         }
202 +         None => {
203 +             let apparels_str: Vec<String> = apparels
204 +                 .iter()
205 +                 .map(|v| v.iter().map(|v| format!("\"{}\"", v.name)).join(","))
206 +                 .collect();
207 +             println!("Helmets:\t{}", apparels_str[0]);
208 +             println!("Chestplates:\t{}", apparels_str[1]);
209 +             println!("Leggings:\t{}", apparels_str[2]);
210 +             println!("Boots:\t\t{}", apparels_str[3]);
211 +             println!("Ring:\t\t{}", apparels_str[4]);
212 +             println!("Bracelet:\t{}", apparels_str[5]);
213 +             println!("Necklace:\t{}", apparels_str[6]);
214 +         }
215 +     };
    |

warning: `wynn_build_tools` (bin "search_item" test) generated 1 warning (run `cargo clippy --fix --bin "search_item" --tests` to apply 1 suggestion)
warning: failed to automatically apply fixes suggested by rustc to crate `builder`

after fixes were automatically applied the compiler reported errors within these files:

  * src/builder.rs

This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust-clippy/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

The following errors were reported:
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `println`
   --> src/builder.rs:135:21
    |
135 |     println!("done")println!("done");
    |                     ^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator

error: aborting due to 1 previous error

Original diagnostics will follow.

warning: unneeded `return` statement
   --> src/builder.rs:135:21
    |
135 |     println!("done");
    |                     ^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return
    = note: `#[warn(clippy::needless_return)]` on by default
help: remove `return`
    |
135 |     println!("done")println!("done");
    |                     ~~~~~~~~~~~~~~~~~

warning: `wynn_build_tools` (bin "builder" test) generated 1 warning (run `cargo clippy --fix --bin "builder" --tests` to apply 1 suggestion)
       Fixed src/search_item.rs (1 fix)
warning: unneeded `return` statement
   --> src/search_item.rs:215:6
    |
215 |     };
    |      ^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return
    = note: `#[warn(clippy::needless_return)]` on by default
help: remove `return`
    |
215 ~     }for apparel_list in &mut apparels {
216 +         if apparel_list.len() > limit {
217 +             apparel_list.truncate(limit);
218 +         }
219 +     }
220 + 
221 +     // Print the results based on the type
222 +     match args.r#type {
223 +         Some(v) => {
224 +             let apparels = match v {
225 +                 Type::Helmets => (&apparels[0], "Helmets"),
226 +                 Type::ChestPlate => (&apparels[1], "Chestplates"),
227 +                 Type::Leggings => (&apparels[2], "Leggings"),
228 +                 Type::Boots => (&apparels[3], "Boots"),
229 +                 Type::Ring => (&apparels[4], "Ring"),
230 +                 Type::Bracelet => (&apparels[5], "Bracelet"),
231 +                 Type::Necklace => (&apparels[6], "Necklace"),
232 +             };
233 +             let apparels_str = apparels
234 +                 .0
235 +                 .iter()
236 +                 .map(|v| format!("\"{}\"", v.name))
237 +                 .join(",");
238 +             println!("{}:\t{}", apparels.1, apparels_str);
239 +         }
240 +         None => {
241 +             let apparels_str: Vec<String> = apparels
242 +                 .iter()
243 +                 .map(|v| v.iter().map(|v| format!("\"{}\"", v.name)).join(","))
244 +                 .collect();
245 +             println!("Helmets:\t{}", apparels_str[0]);
246 +             println!("Chestplates:\t{}", apparels_str[1]);
247 +             println!("Leggings:\t{}", apparels_str[2]);
248 +             println!("Boots:\t\t{}", apparels_str[3]);
249 +             println!("Ring:\t\t{}", apparels_str[4]);
250 +             println!("Bracelet:\t{}", apparels_str[5]);
251 +             println!("Necklace:\t{}", apparels_str[6]);
252 +         }
253 +     }for apparel_list in &mut apparels {
254 +         if apparel_list.len() > limit {
255 +             apparel_list.truncate(limit);
256 +         }
257 +     }
258 + 
259 +     // Print the results based on the type
260 +     match args.r#type {
261 +         Some(v) => {
262 +             let apparels = match v {
263 +                 Type::Helmets => (&apparels[0], "Helmets"),
264 +                 Type::ChestPlate => (&apparels[1], "Chestplates"),
265 +                 Type::Leggings => (&apparels[2], "Leggings"),
266 +                 Type::Boots => (&apparels[3], "Boots"),
267 +                 Type::Ring => (&apparels[4], "Ring"),
268 +                 Type::Bracelet => (&apparels[5], "Bracelet"),
269 +                 Type::Necklace => (&apparels[6], "Necklace"),
270 +             };
271 +             let apparels_str = apparels
272 +                 .0
273 +                 .iter()
274 +                 .map(|v| format!("\"{}\"", v.name))
275 +                 .join(",");
276 +             println!("{}:\t{}", apparels.1, apparels_str);
277 +         }
278 +         None => {
279 +             let apparels_str: Vec<String> = apparels
280 +                 .iter()
281 +                 .map(|v| v.iter().map(|v| format!("\"{}\"", v.name)).join(","))
282 +                 .collect();
283 +             println!("Helmets:\t{}", apparels_str[0]);
284 +             println!("Chestplates:\t{}", apparels_str[1]);
285 +             println!("Leggings:\t{}", apparels_str[2]);
286 +             println!("Boots:\t\t{}", apparels_str[3]);
287 +             println!("Ring:\t\t{}", apparels_str[4]);
288 +             println!("Bracelet:\t{}", apparels_str[5]);
289 +             println!("Necklace:\t{}", apparels_str[6]);
290 +         }
291 +     }for apparel_list in &mut apparels {
292 +         if apparel_list.len() > limit {
293 +             apparel_list.truncate(limit);
294 +         }
295 +     }
296 + 
297 +     // Print the results based on the type
298 +     match args.r#type {
299 +         Some(v) => {
300 +             let apparels = match v {
301 +                 Type::Helmets => (&apparels[0], "Helmets"),
302 +                 Type::ChestPlate => (&apparels[1], "Chestplates"),
303 +                 Type::Leggings => (&apparels[2], "Leggings"),
304 +                 Type::Boots => (&apparels[3], "Boots"),
305 +                 Type::Ring => (&apparels[4], "Ring"),
306 +                 Type::Bracelet => (&apparels[5], "Bracelet"),
307 +                 Type::Necklace => (&apparels[6], "Necklace"),
308 +             };
309 +             let apparels_str = apparels
310 +                 .0
311 +                 .iter()
312 +                 .map(|v| format!("\"{}\"", v.name))
313 +                 .join(",");
314 +             println!("{}:\t{}", apparels.1, apparels_str);
315 +         }
316 +         None => {
317 +             let apparels_str: Vec<String> = apparels
318 +                 .iter()
319 +                 .map(|v| v.iter().map(|v| format!("\"{}\"", v.name)).join(","))
320 +                 .collect();
321 +             println!("Helmets:\t{}", apparels_str[0]);
322 +             println!("Chestplates:\t{}", apparels_str[1]);
323 +             println!("Leggings:\t{}", apparels_str[2]);
324 +             println!("Boots:\t\t{}", apparels_str[3]);
325 +             println!("Ring:\t\t{}", apparels_str[4]);
326 +             println!("Bracelet:\t{}", apparels_str[5]);
327 +             println!("Necklace:\t{}", apparels_str[6]);
328 +         }
329 +     }for apparel_list in &mut apparels {
330 +         if apparel_list.len() > limit {
331 +             apparel_list.truncate(limit);
332 +         }
333 +     }
334 + 
335 +     // Print the results based on the type
336 +     match args.r#type {
337 +         Some(v) => {
338 +             let apparels = match v {
339 +                 Type::Helmets => (&apparels[0], "Helmets"),
340 +                 Type::ChestPlate => (&apparels[1], "Chestplates"),
341 +                 Type::Leggings => (&apparels[2], "Leggings"),
342 +                 Type::Boots => (&apparels[3], "Boots"),
343 +                 Type::Ring => (&apparels[4], "Ring"),
344 +                 Type::Bracelet => (&apparels[5], "Bracelet"),
345 +                 Type::Necklace => (&apparels[6], "Necklace"),
346 +             };
347 +             let apparels_str = apparels
348 +                 .0
349 +                 .iter()
350 +                 .map(|v| format!("\"{}\"", v.name))
351 +                 .join(",");
352 +             println!("{}:\t{}", apparels.1, apparels_str);
353 +         }
354 +         None => {
355 +             let apparels_str: Vec<String> = apparels
356 +                 .iter()
357 +                 .map(|v| v.iter().map(|v| format!("\"{}\"", v.name)).join(","))
358 +                 .collect();
359 +             println!("Helmets:\t{}", apparels_str[0]);
360 +             println!("Chestplates:\t{}", apparels_str[1]);
361 +             println!("Leggings:\t{}", apparels_str[2]);
362 +             println!("Boots:\t\t{}", apparels_str[3]);
363 +             println!("Ring:\t\t{}", apparels_str[4]);
364 +             println!("Bracelet:\t{}", apparels_str[5]);
365 +             println!("Necklace:\t{}", apparels_str[6]);
366 +         }
367 +     };
    |

warning: `wynn_build_tools` (bin "search_item") generated 1 warning (run `cargo clippy --fix --bin "search_item"` to apply 1 suggestion)
warning: failed to automatically apply fixes suggested by rustc to crate `builder`

after fixes were automatically applied the compiler reported errors within these files:

  * src/builder.rs

This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust-clippy/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

The following errors were reported:
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `println`
   --> src/builder.rs:135:21
    |
135 |     println!("done")println!("done");
    |                     ^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator

error: aborting due to 1 previous error

Original diagnostics will follow.

warning: `wynn_build_tools` (bin "builder") generated 1 warning (1 duplicate)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 5.04s

The project that generated these warnings is hosted at https://github.com/TYTheBeast/WynnBuilderTools-Rekindled/

Lint Name

unneeded return statement

Reproducer

I tried this code:

let db_pool = db::init(&config).await;
    generate_full_combinations_with_random(
        1000,
        counter,
        &no_ring_apparels,
        |no_rings_combination| {
            //...
        },
        Option::Some(remaining_builds.clone()),
    );

    println!("done");

I saw this happen:

warning: unneeded `return` statement
   --> src/builder.rs:135:21
    |
135 |     println!("done");
    |                     ^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return
    = note: `#[warn(clippy::needless_return)]` on by default
help: remove `return`
    |
135 |     println!("done")println!("done");
    |                     ~~~~~~~~~~~~~~~~~

warning: `wynn_build_tools` (bin "builder" test) generated 1 warning (run `cargo clippy --fix --bin "builder" --tests` to apply 1 suggestion)

I expected nothing to happen.

Version

rustc 1.83.0-nightly (06bb8364a 2024-10-01)
binary: rustc
commit-hash: 06bb8364aaffefb0ce67e5f5445e66ec99c1f66e
commit-date: 2024-10-01
host: x86_64-unknown-linux-gnu
release: 1.83.0-nightly
LLVM version: 19.1.0

Additional Labels

No response

@TYTheBeast TYTheBeast added C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have labels Oct 9, 2024
benma added a commit to BitBoxSwiss/bitbox-api-rs that referenced this issue Oct 10, 2024
Nightly quite often breaks CI by introducing new clippy linters etc,
which disrupts one's work when one wants to land a PR whose CI
suddenly fails for unrelated reasons.

Sometimes, the new linters are also broken and result in false
positives. The one that prompted this commit is a false positive about
needless_return like this:
rust-lang/rust-clippy#13526

```
error: unneeded `return` statement
   --> tests/simulator_tests.rs:212:51
    |
212 |       for simulator_filename in simulator_filenames {
    |  ___________________________________________________^
213 | |         println!("Simulator tests using {}", simulator_filename);
214 | |         let _server = Server::launch(&simulator_filename);
...   |
244 | |         test_btc(&paired_bitbox).await
245 | |     }
```

(there is no return statement)
@y21
Copy link
Member

y21 commented Oct 10, 2024

Most likely a duplicate of #13458 (which will be fixed by #13464)

@bors bors closed this as completed in 8e60f14 Oct 10, 2024
flip1995 pushed a commit to flip1995/rust-clippy that referenced this issue Oct 18, 2024
Don't warn on proc macro generated code in `needless_return`

Fixes rust-lang#13458
Fixes rust-lang#13457
Fixes rust-lang#13467
Fixes rust-lang#13479
Fixes rust-lang#13481
Fixes rust-lang#13526
Fixes rust-lang#13486

The fix is unfortunately a little more convoluted than just simply adding a `is_from_proc_macro`. That check *does*  fix the issue, however it also introduces a bunch of false negatives in the tests, specifically when the returned expression is in a different syntax context, e.g. `return format!(..)`.

The proc macro check builds up a start and end pattern based on the HIR nodes and compares it to a snippet of the span, however that would currently fail for `return format!(..)` because we would have the patterns `("return", <something inside of the format macro>)`, which doesn't compare equal. So we now return an empty string pattern for when it's in a different syntax context.

"Hide whitespace" helps a bit for reviewing the proc macro detection change

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants