Skip to content

False positive warning on if keyword for unused_qualifications #149873

Closed as not planned

Description

@djc

Code

See here:

https://github.com/hickory-dns/hickory-dns/blob/ac67742d64717cf61299871554590beb7c0c296c/crates/proto/src/multicast/mdns_stream.rs#L456

(After enabling unused_qualifications = "warn" via Cargo.toml.)

Current output

warning: unnecessary qualification
   --> crates/proto/src/multicast/mdns_stream.rs:456:9
    |
456 |         if let Err(error) = result {
    |         ^^
    |
    = note: requested on the command line with `-W unused-qualifications`

warning: `hickory-proto` (lib test) generated 1 warning (run `cargo fix --lib -p hickory-proto --tests` to apply 1 suggestion)

Desired output

No warning.

Rationale and extra context

Image

Clearly the lint should not fire on language keywords.

Other cases

Rust Version

rustc 1.92.0 (ded5c06cf 2025-12-08)
binary: rustc
commit-hash: ded5c06cf21d2b93bffd5d884aa6e96934ee4234
commit-date: 2025-12-08
host: aarch64-apple-darwin
release: 1.92.0
LLVM version: 21.1.3

Anything else?

No response

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Dec 11, 2025
  2. added
    E-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example
    on Dec 11, 2025
  3. mu001999 commented on Dec 11, 2025

    @mu001999
  4. djc commented on Dec 11, 2025

    @djc
    ContributorAuthor

    Can you try against the branch from this PR (after removing the suppression)?

  5. mu001999 commented on Dec 12, 2025

    @mu001999
    Member

    the branch from this PR (after removing the suppression)

    @djc It has been merged, could you provide a specific commit which can reproduce this directly?

  6. djc commented on Dec 12, 2025

    @djc
    ContributorAuthor

    Here's how I can reproduce it:

    djc-2021 main hickory-dns $ git checkout 4897611bcf2d6e6490708986ec66d464b5efe895
    djc-2021 heads/main hickory-dns $ cd crates/proto
    djc-2021 heads/main proto $ git diff
    diff --git a/crates/proto/src/multicast/mdns_stream.rs b/crates/proto/src/multicast/mdns_stream.rs
    index 1cd1d8b09..66d81c616 100644
    --- a/crates/proto/src/multicast/mdns_stream.rs
    +++ b/crates/proto/src/multicast/mdns_stream.rs
    @@ -441,7 +441,7 @@ pub(crate) mod tests {
     
         // one_shot tests are basically clones from the udp tests
         #[tokio::test]
    -    #[allow(unused_qualifications)] // https://github.com/rust-lang/rust/issues/149873
    +    //#[allow(unused_qualifications)] // https://github.com/rust-lang/rust/issues/149873
         async fn test_next_random_socket() {
             subscribe();
     
    djc-2021 heads/main proto $ rustc -V
    rustc 1.92.0 (ded5c06cf 2025-12-08)
    djc-2021 heads/main proto $ cargo c --tests --all-features
    warning: unnecessary qualification
       --> crates/proto/src/multicast/mdns_stream.rs:457:9
        |
    457 |         if let Err(error) = result {
        |         ^^
        |
        = note: requested on the command line with `-W unused-qualifications`
    
    warning: `hickory-proto` (lib test) generated 1 warning (run `cargo fix --lib -p hickory-proto --tests` to apply 1 suggestion)
        Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.32s
    
  7. mu001999 commented on Dec 12, 2025

    @mu001999
    Member

    @djc Thanks! I reproduced it. I will take a look.

    @rustbot claim

  8. mu001999 commented on Dec 12, 2025

    @mu001999
    Member

    MCVE:

    pub use tokio::runtime;
    
    #[tokio::test]
    pub async fn foo() {
        if true {}
    }
    

    And we will get:

    warning: unnecessary qualification
     --> src/lib.rs:5:5
      |
    5 |     if true {}
      |     ^^
      |
      = note: requested on the command line with `-W unused-qualifications`
    
  9. mu001999 commented on Dec 12, 2025

    @mu001999
    Member

    This is related to setting span in proc macros. I think there may be more potential issues, not just related to unused_qualifications. I will provide a brief summary and possible solutions when I am free.

  10. mu001999 commented on Dec 15, 2025

    @mu001999
    Member

    For this issue, it's because #[tokio::test] will expand the input into things like (using the above example in #149873 (comment)):

    pub fn foo() {
        let body = async { if true {} };
        let mut body = body;
        #[allow(unused_mut)]
        let mut body = unsafe { ::tokio::macros::support::Pin::new_unchecked(&mut body) };
        let body: ::core::pin::Pin<&mut dyn ::core::future::Future<Output = ()>> = body;
        #[allow(
            clippy::expect_used,
            clippy::diverging_sub_expression,
            clippy::needless_return,
            clippy::unwrap_in_result
        )]
        {
            return tokio::runtime::Builder::new_current_thread()
                .enable_all()
                .build()
                .expect("Failed building the Runtime")
                .block_on(body);
        }
    }
    

    So when we have use tokio::runtime; outer, we will get the warning for unused_qualifications.

    But #[tokio::test] will use the span of the last stmt for the generated stmt, see see https://github.com/tokio-rs/tokio/blob/master/tokio-macros/src/entry.rs#L395-L422. That's why we will get the warning reported on if.


    SO I think this position is expected in fact. The first we can do to fix this may be using ::tokio::runtime in the implementation of #[tokio::test].

    🤔 And furthermore, considering the flexibility of proc-macro, we can even set empty spans if we want, which may lead to ICEs. And we even cannot tell such spans are from proc-macro or not (IIRC).

  11. djc commented on Dec 15, 2025

    @djc
    ContributorAuthor

    SO I think this position is expected in fact. The first we can do is to fix this may be using ::tokio::runtime in the implementation of #[tokio::test].

    Did you actually try whether that helps? It doesn't seem obvious that it would...

  12. y21 commented on Dec 15, 2025

    @y21
    Member

    This looks like it's basically exactly the same root issue as #122519 (and that also has some of the same discussion around proc macro using input spans in the output making it impossible to tell for the lint that this comes from a macro). #122435 changed the lint to not lint on absolute paths, so changing it to ::tokio::runtime sounds like it should indeed fix that. It also looks like a mistake to me that all paths are absolute except for that one in the return statement.

    And we even cannot tell such spans are from proc-macro or not (IIRC).

    cc #130995, we've had this issue for a long time in Clippy and have some hacks to deal with this, but it would be very nice if there was a general solution to this problem

  13. Darksonn commented on Jan 12, 2026

    @Darksonn
    Member

    Changing the macro to emit ::tokio::runtime is a breaking change.

    IMO this warning should not be emitted on macro generated code in the first place.

  14. mu001999 commented on Jan 12, 2026

    @mu001999
    Member

    IMO this warning should not be emitted on macro generated code in the first place.

    Unfortunately, this span is the first span of the last statement. We cannot know the code is macro generated in current implementation.

    But I think we can check the code at the span is same to the path segment or not, and don't emit if this is not. I can try this later.

  15. Darksonn commented on Jan 12, 2026

    @Darksonn
    Member

    I'm pretty sure many other lints have logic to not trigger on macro generated code. Can't we use the same logic? Or is the issue Tokio is emitting the wrong span to trigger that logic?

  16. mu001999 commented on Jan 12, 2026

    @mu001999
    Member

    Or is the issue Tokio is emitting the wrong span to trigger that logic?

    @Darksonn Yes, we used Span::from_expansion to check normal macro generated code.

    But for proc_macro which calls things like quote_spanned! (for tokio, it's https://github.com/tokio-rs/tokio/blob/master/tokio-macros/src/entry.rs#L395-L422), it will forward users span directly, and Span::from_expansion will return false.

    You can see more analysis in #130995.

  17. Darksonn commented on Jan 12, 2026

    @Darksonn
    Member

    It was changed to use quote_spanned! in tokio-rs/tokio#3766. @taiki-e do you have any input?

  18. taiki-e commented on Jan 12, 2026

    @taiki-e
    Member

    Maybe using Span::call_site().located_at(span) instead of span in quote_spanned (like taiki-e/pin-project@5a1a568) resolves the issue.

  19. mu001999 commented on Jan 22, 2026

    @mu001999
    Member

    Has been fixed in tokio-rs/tokio#7866

  20. Darksonn commented on Jan 22, 2026

    @Darksonn
    Member

    I'm going to close this because there is no action needed in rustc. The lint already does not trigger on macro-generated code when the right span is present.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsE-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable ExampleL-unused_qualificationsLint: unused_qualificationsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions