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

clippy::let_and_return false positive #4555

Closed
CreepySkeleton opened this issue Sep 19, 2019 · 6 comments · Fixed by #4561
Closed

clippy::let_and_return false positive #4555

CreepySkeleton opened this issue Sep 19, 2019 · 6 comments · Fixed by #4561
Labels
C-bug Category: Clippy is not doing the correct thing T-macros Type: Issues with macros and macro expansion

Comments

@CreepySkeleton
Copy link

Summary

The clippy::let_and_return lint triggers from code generated by a macro-derive.

Reproducer

use structopt::StructOpt;

#[derive(StructOpt)]
pub struct A {
    #[structopt(flatten)]
    pub b: B,
}

#[derive(StructOpt)]
pub struct B {}

fn main() {}

structopt v0.3.2 does generate let_and_return in this case but I don't think this lint makes much sense when originated from a macro expansion.

cargo clippy -V
clippy 0.0.212 (e3cb40e4 2019-06-25)
@CreepySkeleton CreepySkeleton changed the title clippy::let_and_return false clippy::let_and_return false positive Sep 19, 2019
@llogiq
Copy link
Contributor

llogiq commented Sep 19, 2019

That's strange. Gotta look into the code that structopt generates. Sometimes the expr spans aren't the same as their stmt spans.

@phansch phansch added C-bug Category: Clippy is not doing the correct thing T-macros Type: Issues with macros and macro expansion labels Sep 19, 2019
@CreepySkeleton
Copy link
Author

Sometimes the expr spans aren't the same as their stmt spans.

Yes, structopt propagates source span info to the generated code. This particular piece of generated code has a span that points to #[structopt(flatten)] in source code.

@CreepySkeleton
Copy link
Author

CreepySkeleton commented Sep 19, 2019

Relevant piece of expansion:

let app = <B>::augment_clap(app);
let app = if <B>::is_subcommand() {
    app.setting(::structopt::clap::AppSettings::SubcommandRequiredElseHelp)
} else {
    app
};
app

These let statements get a span pointing to flatten in source code.

The warning:

warning: returning the result of a let binding from a block
 --> src\main.rs:3:10
  |
3 | #[derive(StructOpt)]
  |          ^^^^^^^^^
4 | pub struct A {
5 |     #[structopt(flatten)]
  |                 ------- unnecessary let binding
  |
  = note: #[warn(clippy::let_and_return)] on by default
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return

@CreepySkeleton
Copy link
Author

Full expansion

@llogiq
Copy link
Contributor

llogiq commented Sep 19, 2019

I think checking if !in_external_macro(cx.sess(), retexpr.span); in returns.rs:210 should suffice. The return expression gets its own span from structopt, as far as I can see.

@CreepySkeleton
Copy link
Author

CreepySkeleton commented Sep 20, 2019

@llogiq Yes, you're right.

Perhaps this will be more appropriate:

if !in_external_macro(cx.sess(), retexpr.span);
if !in_external_macro(cx.sess(), local.span);

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 T-macros Type: Issues with macros and macro expansion
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants