rust-lang / rust-lang/rust

unhelpful error when giving an instance method to a generic function requiring a function

Open
#162,033 1 comment 0 reactions 1 assignee View on GitHub

@Yogeshwaran-Projects is already working on this.

Since Sep 2, 2026.

A-diagnostics T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code
fn call<C>(f: C)
where
    C: Fn(),
{
    f()
}

struct FooPrinter {}

impl FooPrinter {
    fn print(&self) {
        println!("foo");
    }
    fn new() -> Self {
        FooPrinter {}
    }
}

fn print_foo() {
    println!("foo");
}

fn main() {
    // passing a normal function
    call(print_foo);

    // clippy lints this
    call(|| print_foo());

    // doesn't work
    call(FooPrinter::new().print);

    // fixed looks like clippy would lint this
    call(|| FooPrinter::new().print());
}
Current output
error[E0615]: attempted to take value of method `print` on type `FooPrinter`
  --> src/main.rs:21:28
   |
21 |     call(FooPrinter::new().print);
   |                            ^^^^^ method, not a field
   |
help: use parentheses to call the method
   |
21 |     call(FooPrinter::new().print());
   |                                 ++

For more information about this error, try `rustc --explain E0615`.
Desired output
error[E0615]: cannot use `print` on instance of type `FooPrinter` for generic
  --> src/main.rs:21:28
   |
21 |     call(FooPrinter::new().print);
   |                            ^^^^^ method on instance
   |
help: wrap it into a closure
   |
21 |     call(|| FooPrinter::new().print());
   |          +++                       ++
Rationale and extra context

As pointed out in the code example this kinda stems from the clippy lint redundant closure lint.
I had a case where I was very confused why clippy wouldn't lint this and when I removed the lamda, it gave me this error.
It also stems from a desire to have neat code and especially when the called function has many arguments, copying all the argument types into the lamda is kinda ugly. But I get why it is required for instance methods.

Other cases

a case where adding the closure actually makes the code more ugly

mod my_external_crate {
    pub type AVeryVeryVeryVeryVeryVeryVeryLongType = ();

    pub fn call<C>(f: C)
    where
        C: Fn(AVeryVeryVeryVeryVeryVeryVeryLongType, AVeryVeryVeryVeryVeryVeryVeryLongType),
    {
        f((), ())
    }

    pub struct FooPrinter {}

    impl FooPrinter {
        pub fn print(
            &self,
            _: AVeryVeryVeryVeryVeryVeryVeryLongType,
            _: AVeryVeryVeryVeryVeryVeryVeryLongType,
        ) {
            println!("foo");
        }
        pub fn new() -> Self {
            FooPrinter {}
        }
    }

    pub fn print_foo(
        _: AVeryVeryVeryVeryVeryVeryVeryLongType,
        _: AVeryVeryVeryVeryVeryVeryVeryLongType,
    ) {
        println!("foo");
    }
}

use my_external_crate::*;

fn main() {
    // passing a normal function
    call(print_foo);

    // clippy actually does not lint this, but i think it should
    call(
        |x: AVeryVeryVeryVeryVeryVeryVeryLongType, y: AVeryVeryVeryVeryVeryVeryVeryLongType| {
            print_foo(x, y)
        },
    );

    // doesn't work
    call(FooPrinter::new().print);

    // fixed looks like clippy would lint this
    call(
        |x: AVeryVeryVeryVeryVeryVeryVeryLongType, y: AVeryVeryVeryVeryVeryVeryVeryLongType| {
            FooPrinter::new().print(x, y)
        },
    );
}
Rust Version
rustc 1.97.1 (8bab26f4f 2026-07-14) (built from a source tarball) // from nixpkgs
binary: rustc
commit-hash: 8bab26f4f68e0e26f0bb7960be334d5b520ea452
commit-date: 2026-07-14
host: x86_64-unknown-linux-gnu
release: 1.97.1
LLVM version: 21.1.8
Anything else?

Sorry if my rust lingo is not on point, i still consider myself a beginner or at most intermediate in rust.

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.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.