rust-lang / rust-lang/rust-clippy

`incompatible_msrv` false positive: Trait methods of the same name

Open
#12,280 2 comments 6 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug I-false-positive
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

Summary

The incompatible_msrv lint fires when a method was stabilized more recently than the MSRV, but there is also a trait in scope with a method of the same name. In this case, on toolchains prior to stabilization, the trait's method will be chosen instead, and so compilation will still succeed. This technique is sometimes used to implement polyfills.

To repro, run cargo +nightly-2024-02-12 clippy -p zerocopy-derive at this commit:

$ cargo +nightly-2024-02-12 clippy -p zerocopy-derive
   Compiling proc-macro2 v1.0.76
    Checking unicode-ident v1.0.12
    Checking quote v1.0.35
    Checking syn v2.0.48
    Checking zerocopy-derive v0.8.0-alpha.4 (/Users/josh/workspace/zerocopy/zerocopy-derive)
error: current MSRV (Minimum Supported Rust Version) is `1.56.0` but this item is stable since `1.62.0`
   --> zerocopy-derive/src/lib.rs:943:83
    |
943 |     let padding_check_bound = padding_check.and_then(|check| (!fields.is_empty()).then_some(check)).map(|check| {
    |                                                                                   ^^^^^^^^^^^^^^^^
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#incompatible_msrv
note: the lint level is defined here
   --> zerocopy-derive/src/lib.rs:19:9
    |
19  | #![deny(clippy::all, clippy::missing_safety_doc, clippy::undocumented_unsafe_blocks)]
    |         ^^^^^^^^^^^
    = note: `#[deny(clippy::incompatible_msrv)]` implied by `#[deny(clippy::all)]`

error: could not compile `zerocopy-derive` (lib) due to 1 previous error

The following code also exists in the same module:

// A polyfill for `Option::then_some`, which was added after our MSRV.
//
// The `#[allow(unused)]` is necessary because, on sufficiently recent toolchain
// versions, `b.then_some(...)` resolves to the inherent method rather than to
// this trait, and so this trait is considered unused.
//
// TODO(#67): Remove this once our MSRV is >= 1.62.
#[allow(unused)]
trait BoolExt {
    fn then_some<T>(self, t: T) -> Option<T>;
}

impl BoolExt for bool {
    fn then_some<T>(self, t: T) -> Option<T> {
        if self {
            Some(t)
        } else {
            None
        }
    }
}
Lint Name

incompatible_msrv

Version

nightly-2024-02-12

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the diagnostic with cargo +nightly-2024-02-12 clippy -p zerocopy-derive at the linked commit, focusing on the then_some call in zerocopy-derive/src/lib.rs. Trace how incompatible_msrv handles method resolution when the same method is provided by an in-scope trait; done means the polyfill case no longer produces a false positive while genuinely unavailable methods remain diagnosed.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.