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

Macro-generated code triggers suspicious-else-formatting #6249

Closed
jplatte opened this issue Oct 27, 2020 · 11 comments
Closed

Macro-generated code triggers suspicious-else-formatting #6249

jplatte opened this issue Oct 27, 2020 · 11 comments
Assignees
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 S-blocked Status: marked as blocked ❌ on something else such as an RFC or other implementation work T-macros Type: Issues with macros and macro expansion

Comments

@jplatte
Copy link
Contributor

jplatte commented Oct 27, 2020

I tried this code:

impl Device {
    pub async fn set_status(id: Uuid, status: &str, db: impl PgExecutor<'_>) -> sqlx::Result<u64> {
        Ok(
            sqlx::query!("UPDATE devices SET status = $1 WHERE id = $2", status, id)
                .execute(db)
                .await?
                .rows_affected(),
        )
    }
}

(added some context because indentation level might matter? or maybe it's just entirely unformatted macro output)

I expected to see this happen: No warnings

Instead, this happened:

error: this looks like an `else if` but the `else` is missing
   --> src/db/models/device.rs:109:80
    |
109 |             sqlx::query!("UPDATE devices SET status = $1 WHERE id = $2", status, id)
    |                                                                                ^^
    |
    = note: `-D clippy::suspicious-else-formatting` implied by `-D warnings`
    = note: to remove this lint, add the missing `else` or add a new line before the second `if`
    = help: for further information visit rust-lang.github.io/rust-clippy/master/index.html#suspicious_else_formatting

Meta

(will fill this in once I can reproduce on a local computer again, right now fails on CI, probably clippy 0.0.212 (ffa2e7a 2020-10-24))

@jplatte jplatte added the C-bug Category: Clippy is not doing the correct thing label Oct 27, 2020
@phansch phansch added T-macros Type: Issues with macros and macro expansion I-false-positive Issue: The lint was triggered on code it shouldn't have labels Dec 18, 2020
@xFrednet
Copy link
Member

I can sadly not reproduce that currently by using the simple macro_rules! macro for defining my own macro (Playground). I guess that it has to do something with the use of quote_spanned! as this is used in the code that caused the lint. The documentation of that macro is sadly not clear enough for me to write my own minimal version.

The lint it self comes from /clippy_lints/src/formatting.rs. I would look further into this if someone could maybe provide a simple example 😅

@ebroto
Copy link
Member

ebroto commented Dec 19, 2020

If I'm not mistaken quote is already a dependency in our test suite so you should be able to use quote_spanned there.

@xFrednet
Copy link
Member

@rustbot claim

@xFrednet
Copy link
Member

This issue originates from the use of quote_spanned! and is sadly unfixable for us. It is also not specific to this lint but can happen with any macro that uses the quote_spanned! macro.

The quote_spanned! sets the span of the produced tokens to a user defined span. (See docs for more information). sqlx set the token span to the actual input parameters. Our lint therefore determines that:

  1. The code span is not the result of a macro (first.span.from_expansion() is false as the token uses the span of the input)
  2. The formatting is wrong because there is no empty line between the if blocks

The first point is also the reason why this could happen with every lint as it bypasses our check if the code was generated via a macro. I would therefor think that this and potential other false positives from the quote_spanned! macro are currently unfixable for us. I've created a minimal example with quote_spanned! in case you want to test for your self: 31c287e

@Nugine
Copy link

Nugine commented Oct 3, 2021

I came into this bug and reproduced it by the code below.
I don't know whether it is a problem from tracing.

#![deny(clippy::suspicious_else_formatting)]

#[tracing::instrument]
async fn get(key: &str) -> String {
    if key.is_empty() {
        panic!()
    } else {
        todo!()
    }
}
error: this is an `else {..}` but the formatting might hide it
  --> src/lib.rs:4:35
   |
4  |   async fn get(key: &str) -> String {
   |  ___________________________________^
5  | |     if key.is_empty() {
6  | |         panic!()
7  | |     } else {
8  | |         todo!()
9  | |     }
10 | | }
   | |_^
   |
note: the lint level is defined here
  --> src/lib.rs:1:9
   |
1  | #![deny(clippy::suspicious_else_formatting)]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_else_formatting

Versions:

tracing = "0.1.28"
rustc 1.57.0-nightly (f03eb6bef 2021-10-02)
clippy 0.1.57 (f03eb6b 2021-10-02)

@extrawurst
Copy link

@Nugine I have the same issue due to instruments, the weird part is, that it fails on our CI but not locally: https://github.com/gameroasters/atlasserver/runs/3779641152?check_suite_focus=true

@Nugine
Copy link

Nugine commented Oct 3, 2021

@Nugine I have the same issue due to instruments, the weird part is, that it fails on our CI but not locally: https://github.com/gameroasters/atlasserver/runs/3779641152?check_suite_focus=true

Our CI 166 also failed today. But CI 164 succeeded.

There is no commit during this week. The CI toolchain is locked to 1.55.0. tracing-attributes 0.1.17 released yesterday. So I'm sure that the change of tracing-attributes triggers this bug.

Try to update your lockfile and toolchain.

@extrawurst
Copy link

@Nugine right on, I did not have the tracing-attributes update locally yet, thanks for the hint!

hawkw added a commit to tokio-rs/tracing that referenced this issue Oct 5, 2021
## Motivation

Apparently, using `quote_spanned!` can trigger a Clippy bug where the
text `else`, even inside a comment, _may_ cause the
`suspicious_else_formatting` lint to be triggered incorrectly (see
rust-lang/rust-clippy#7760 and rust-lang/rust-clippy#6249). This causes
the lint to fire in some cases when the `#[instrument]` attribute is
used on `async fn`s. See issue #1613 for details.

## Solution

It turns out that some of the uses of `quote_spanned!` in the
`tracing-attributes` code generation are not needed. We really only need
`quote_spanned!` when actually interpolating the user provided code into
a block, not in the `tracing-attributes` code that inserts the generated
code for producing the span etc. Replacing some of these
`quote_spanned!` uses with the normal `quote!` macro still generates
correct location diagnostics for errors in the user code, but fixes the
incorrect clippy lint.

I've added a few test cases that should reproduce the bug.

Fixes #1613
hawkw added a commit to tokio-rs/tracing that referenced this issue Oct 5, 2021
## Motivation

Apparently, using `quote_spanned!` can trigger a Clippy bug where the
text `else`, even inside a comment, _may_ cause the
`suspicious_else_formatting` lint to be triggered incorrectly (see
rust-lang/rust-clippy#7760 and rust-lang/rust-clippy#6249). This causes
the lint to fire in some cases when the `#[instrument]` attribute is
used on `async fn`s. See issue #1613 for details.

## Solution

It turns out that some of the uses of `quote_spanned!` in the
`tracing-attributes` code generation are not needed. We really only need
`quote_spanned!` when actually interpolating the user provided code into
a block, not in the `tracing-attributes` code that inserts the generated
code for producing the span etc. Replacing some of these
`quote_spanned!` uses with the normal `quote!` macro still generates
correct location diagnostics for errors in the user code, but fixes the
incorrect clippy lint.

I've added a few test cases that should reproduce the bug.

Fixes #1613

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
hawkw added a commit to tokio-rs/tracing that referenced this issue Oct 5, 2021
## Motivation

Apparently, using `quote_spanned!` can trigger a Clippy bug where the
text `else`, even inside a comment, _may_ cause the
`suspicious_else_formatting` lint to be triggered incorrectly (see
rust-lang/rust-clippy#7760 and rust-lang/rust-clippy#6249). This causes
the lint to fire in some cases when the `#[instrument]` attribute is
used on `async fn`s. See issue #1613 for details.

## Solution

It turns out that some of the uses of `quote_spanned!` in the
`tracing-attributes` code generation are not needed. We really only need
`quote_spanned!` when actually interpolating the user provided code into
a block, not in the `tracing-attributes` code that inserts the generated
code for producing the span etc. Replacing some of these
`quote_spanned!` uses with the normal `quote!` macro still generates
correct location diagnostics for errors in the user code, but fixes the
incorrect clippy lint.

I've added a few test cases that should reproduce the bug.

Fixes #1613

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
hawkw added a commit to tokio-rs/tracing that referenced this issue Oct 5, 2021
## Motivation

Apparently, using `quote_spanned!` can trigger a Clippy bug where the
text `else`, even inside a comment, _may_ cause the
`suspicious_else_formatting` lint to be triggered incorrectly (see
rust-lang/rust-clippy#7760 and rust-lang/rust-clippy#6249). This causes
the lint to fire in some cases when the `#[instrument]` attribute is
used on `async fn`s. See issue #1613 for details.

## Solution

It turns out that some of the uses of `quote_spanned!` in the
`tracing-attributes` code generation are not needed. We really only need
`quote_spanned!` when actually interpolating the user provided code into
a block, not in the `tracing-attributes` code that inserts the generated
code for producing the span etc. Replacing some of these
`quote_spanned!` uses with the normal `quote!` macro still generates
correct location diagnostics for errors in the user code, but fixes the
incorrect clippy lint.

I've added a few test cases that should reproduce the bug.

Fixes #1613

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
hawkw added a commit to tokio-rs/tracing that referenced this issue Oct 5, 2021
# 0.1.17 (October 1, 2021)

This release fixes issues introduced in v0.1.17.

### Fixed

- fixed mismatched types compiler error that may occur when using
  `#[instrument]` on an `async fn` that returns an `impl Trait` value
  that includes a closure ([#1616])
- fixed false positives for `clippy::suspicious_else_formatting`
  warnings due to rust-lang/rust-clippy#7760 and
  rust-lang/rust-clippy#6249 ([#1617])
- fixed `clippy::let_unit_value` lints when using `#[instrument]`
  ([#1614])

[#1617]: #1617
[#1616]: #1616
[#1614]: #1614
hawkw added a commit to tokio-rs/tracing that referenced this issue Oct 5, 2021
# 0.1.17 (October 1, 2021)

This release fixes issues introduced in v0.1.17.

### Fixed

- fixed mismatched types compiler error that may occur when using
  `#[instrument]` on an `async fn` that returns an `impl Trait` value
  that includes a closure ([#1616])
- fixed false positives for `clippy::suspicious_else_formatting`
  warnings due to rust-lang/rust-clippy#7760 and
  rust-lang/rust-clippy#6249 ([#1617])
- fixed `clippy::let_unit_value` lints when using `#[instrument]`
  ([#1614])

[#1617]: #1617
[#1616]: #1616
[#1614]: #1614
hawkw added a commit to tokio-rs/tracing that referenced this issue Oct 5, 2021
# 0.1.18 (October 5, 2021)

This release fixes issues introduced in v0.1.17.

### Fixed

- fixed mismatched types compiler error that may occur when using
  `#[instrument]` on an `async fn` that returns an `impl Trait` value
  that includes a closure ([#1616])
- fixed false positives for `clippy::suspicious_else_formatting`
  warnings due to rust-lang/rust-clippy#7760 and
  rust-lang/rust-clippy#6249 ([#1617])
- fixed `clippy::let_unit_value` lints when using `#[instrument]`
  ([#1614])

[#1617]: #1617
[#1616]: #1616
[#1614]: #1614
@xFrednet
Copy link
Member

xFrednet commented Oct 6, 2021

I might have an idea how to avoid FPs like these in exchange for some false negatives. 🙃

@rustbot claim

once again ^^

@rustbot

This comment has been minimized.

@xFrednet
Copy link
Member

My idea sadly didn't work out. #7707 also did some work with another approach, that seems promising. I'm closing this in the hopes that it's fixed 🙃

kaffarell pushed a commit to kaffarell/tracing that referenced this issue May 22, 2024
# 0.1.18 (October 5, 2021)

This release fixes issues introduced in v0.1.17.

### Fixed

- fixed mismatched types compiler error that may occur when using
  `#[instrument]` on an `async fn` that returns an `impl Trait` value
  that includes a closure ([tokio-rs#1616])
- fixed false positives for `clippy::suspicious_else_formatting`
  warnings due to rust-lang/rust-clippy#7760 and
  rust-lang/rust-clippy#6249 ([tokio-rs#1617])
- fixed `clippy::let_unit_value` lints when using `#[instrument]`
  ([tokio-rs#1614])

[tokio-rs#1617]: tokio-rs#1617
[tokio-rs#1616]: tokio-rs#1616
[tokio-rs#1614]: tokio-rs#1614
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 S-blocked Status: marked as blocked ❌ on something else such as an RFC or other implementation work T-macros Type: Issues with macros and macro expansion
Projects
None yet
Development

No branches or pull requests

7 participants