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

impl Fn(T) argument type is not infered from return type #138530

Open
LHolten opened this issue Mar 15, 2025 · 2 comments
Open

impl Fn(T) argument type is not infered from return type #138530

LHolten opened this issue Mar 15, 2025 · 2 comments
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. A-inference Area: Type inference C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@LHolten
Copy link
Contributor

LHolten commented Mar 15, 2025

I tried this code:

struct Acceptor<T>(Box<dyn Fn(T)>);

impl<T: 'static> Acceptor<T> {
    fn new(f: impl 'static + Fn(T)) -> Self {
        Self(Box::new(f))
    }

    fn new_fn(f: fn(T)) -> Self {
        Self(Box::new(f))
    }
}

fn test_ok1() -> Acceptor<String> {
    Acceptor(Box::new(|x| {
        println!("{}", x.len());
    }))
}

fn test_ok2() -> Acceptor<String> {
    Acceptor::new_fn(|x| {
        println!("{}", x.len());
    })
}

fn test_ok3() -> Acceptor<String> {
    Acceptor::new(|x| {
        println!("{}", x);
    })
}

fn test_ok4() -> Acceptor<String> {
    Acceptor::<String>::new(|x| {
        println!("{}", x.len());
    })
}

// This is the only one that fails
fn test_fail() -> Acceptor<String> {
    Acceptor::new(|x| {
        println!("{}", x.len());
    })
}

I expected all of the test functions to compile, but the last one fails to infer the type of the variable x.

Error message:

error[E0282]: type annotations needed
  --> src/lib.rs:39:20
   |
39 |     Acceptor::new(|x| {
   |                    ^
40 |         println!("{}", x.len());
   |                        - type must be known at this point
   |
help: consider giving this closure parameter an explicit type
   |
39 |     Acceptor::new(|x: /* Type */| {
   |                     ++++++++++++

Meta

Reproduces on nightly too.

rustc --version --verbose:

rustc 1.85.0 (4d91de4e4 2025-02-17)
binary: rustc
commit-hash: 4d91de4e48198da2e33413efdcd9cd2cc0c46688
commit-date: 2025-02-17
host: x86_64-unknown-linux-gnu
release: 1.85.0
LLVM version: 19.1.7

@LHolten LHolten added the C-bug Category: This is a bug. label Mar 15, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Mar 15, 2025
@bjorn3
Copy link
Member

bjorn3 commented Mar 15, 2025

When a method call is typechecked, the receiver type must already be known by that point to know which method to resolve the method call to in the first place. In the case of test_fail this type only gets backpropagated from the return type through Acceptor::new after typechecking the method call was attempted. And as such you get an error. Rustc doesn't go back and try to resolve the method again after it failed to resolve it the first time.

@LHolten
Copy link
Contributor Author

LHolten commented Mar 15, 2025

@bjorn3 Do you maybe know why Acceptor::new_fn typechecks, while Acceptor::new fails, with the exact same calling code?
(respective examples test_ok2 and test_fail)

@lolbinarycat lolbinarycat added A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-inference Area: Type inference labels Mar 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. A-inference Area: Type inference C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants