Skip to content

Clippy gets confused with different crate versions and recommends breaking change #16788

@gianzellweger

Description

@gianzellweger

Summary

When using a certain combination of closures (as demonstrated in the code below) with the clippy::redundant_closure_for_method_calls lint and different slightly incompatible versions of crates, Clippy recommends a change that breaks the program and stops it from building. I am aware that using different versions of crates should generally be avoided as best as possible.

Reproducer

Cargo.toml:

[package]
name = "example"
version = "0.1.0"
edition = "2024"

[dependencies]
ipnetwork = "0.21"                                                                                                                   
pnet_datalink = "0.35" # depends on ipnetwork 0.20.0

Code:

#![warn(clippy::redundant_closure_for_method_calls)]

fn main() {
    for interface in pnet_datalink::interfaces() {
        // clippy suggests `ipnetwork::IpNetwork::ip` but that resolves to
        // ipnetwork 0.21's type, while interface.ips contains ipnetwork 0.20's type
        let ips: Vec<std::net::IpAddr> = interface.ips.iter().map(|ip| ip.ip()).collect();
        println!("{ips:?}");
    }
}

Current output:

warning: redundant closure
 --> src/main.rs:7:67
  |
7 |         let ips: Vec<std::net::IpAddr> = interface.ips.iter().map(|ip| ip.ip()).collect();
  |                                                                   ^^^^^^^^^^^^ help: replace the closure with the method itself: `ipnetwork::IpNetwork::ip`
  |
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_for_method_calls
note: the lint level is defined here
 --> src/main.rs:1:9
  |
1 | #![warn(clippy::redundant_closure_for_method_calls)]
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: `minimal_repro` (bin "minimal_repro") generated 1 warning (run `cargo clippy --fix --bin "minimal_repro" -p minimal_repro -- ` to apply 1 suggestion)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.06s

Output when the "fix" is applied:

   Compiling minimal_repro v0.1.0 (/Users/gian/Desktop/minimal_repro)
error[E0631]: type mismatch in function arguments
   --> src/main.rs:8:38
    |
  8 |             interface.ips.iter().map(ipnetwork::IpNetwork::ip).collect();
    |                                  --- ^^^^^^^^^^^^^^^^^^^^^^^^
    |                                  |   |
    |                                  |   expected due to this
    |                                  |   found signature defined here
    |                                  required by a bound introduced by this call
    |
    = note: expected function signature `fn(&ipnetwork::IpNetwork) -> _`
               found function signature `fn(&IpNetwork) -> _`
note: required by a bound in `map`
   --> /Users/gian/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:834:12
    |
831 |     fn map<B, F>(self, f: F) -> Map<Self, F>
    |        --- required by a bound in this associated function
...
834 |         F: FnMut(Self::Item) -> B,
    |            ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Iterator::map`
help: consider wrapping the function in a closure
    |
  8 |             interface.ips.iter().map(|arg0: &ipnetwork::IpNetwork| ipnetwork::IpNetwork::ip(/* &IpNetwork */)).collect();
    |                                      +++++++++++++++++++++++++++++                         ++++++++++++++++++

error[E0599]: the method `collect` exists for struct `Map<Iter<'_, IpNetwork>, fn(&IpNetwork) -> IpAddr {IpNetwork::ip}>`, but its trait bounds were not satisfied
  --> src/main.rs:8:64
   |
 8 |             interface.ips.iter().map(ipnetwork::IpNetwork::ip).collect();
   |                                                                ^^^^^^^ method cannot be called due to unsatisfied trait bounds
   |
  ::: /Users/gian/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/map.rs:61:1
   |
61 | pub struct Map<I, F> {
   | -------------------- doesn't satisfy `_: Iterator`
   |
   = note: the following trait bounds were not satisfied:
           `<for<'a> fn(&'a IpNetwork) -> IpAddr {IpNetwork::ip} as FnOnce<(&ipnetwork::IpNetwork,)>>::Output = _`
           which is required by `Map<std::slice::Iter<'_, ipnetwork::IpNetwork>, for<'a> fn(&'a IpNetwork) -> IpAddr {IpNetwork::ip}>: Iterator`
           `for<'a> fn(&'a IpNetwork) -> IpAddr {IpNetwork::ip}: FnMut<(&ipnetwork::IpNetwork,)>`
           which is required by `Map<std::slice::Iter<'_, ipnetwork::IpNetwork>, for<'a> fn(&'a IpNetwork) -> IpAddr {IpNetwork::ip}>: Iterator`
           `Map<std::slice::Iter<'_, ipnetwork::IpNetwork>, for<'a> fn(&'a IpNetwork) -> IpAddr {IpNetwork::ip}>: Iterator`
           which is required by `&mut Map<std::slice::Iter<'_, ipnetwork::IpNetwork>, for<'a> fn(&'a IpNetwork) -> IpAddr {IpNetwork::ip}>: Iterator`
   = note: the full name for the type has been written to '/Users/gian/Desktop/minimal_repro/target/debug/deps/minimal_repro-c6880882e8def2a4.long-type-18010014175793987343.txt'
   = note: consider using `--verbose` to print the full type name to the console

Some errors have detailed explanations: E0599, E0631.
For more information about an error, try `rustc --explain E0599`.
error: could not compile `minimal_repro` (bin "minimal_repro") due to 2 previous errors

Version

rustc 1.96.0-nightly (cf7da0b72 2026-03-30)
binary: rustc
commit-hash: cf7da0b7277cad05b79f91b60c290aa08a17a6f0
commit-date: 2026-03-30
host: aarch64-apple-darwin
release: 1.96.0-nightly
LLVM version: 22.1.2

Additional Labels

No response

Metadata

Metadata

Labels

C-bugCategory: Clippy is not doing the correct thing

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions