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

for<'a> Fn(<A as B<'a>>::C) fails incosistently and requires unnecessary type annotations #90875

Closed
aliemjay opened this issue Nov 13, 2021 · 5 comments · Fixed by #96329
Closed
Labels
A-closures Area: Closures (`|…| { … }`) A-inference Area: Type inference A-lifetimes Area: Lifetimes / regions A-trait-system Area: Trait system A-type-system Area: Type system C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@aliemjay
Copy link
Member

aliemjay commented Nov 13, 2021

I tried this code:

trait Variable<'a> {
    type Type;
}

impl Variable<'_> for () {
    type Type = ();
}

fn check<F, T>(_: F)
where
    F: Fn(T), // <- if removed, all fn_* then require type annotations
    F: for<'a> Fn(<T as Variable<'a>>::Type),
    T: for<'a> Variable<'a>,
{
}

fn test(arg: impl Fn(())) {
    fn fn_1(_: ()) {}
    let fn_2 = |_: ()| ();
    let fn_3 = |a| fn_1(a);
    let fn_4 = arg;

    check(fn_1); // Error
    check(fn_2); // Ok
    check(fn_3); // Ok
    check(fn_4); // Error
    check::<_, ()>(fn_1); // Ok
    check::<_, ()>(fn_4); // Ok
}

(playground)

I expected to see this happen: the code compiles fine.

Instead, this happened: check(fn_1) and check(fn_4) fails to type check, and although the error message is not related to type inference, annotating the type parameter T fixes the problem. the same thing happens when removing the bound F: Fn(T), but then for all check(fn_*).

Seems to be related to #79207. cc @jackh726

Error message

   Compiling playground v0.0.1 (/playground)
error[E0631]: type mismatch in function arguments
  --> src/lib.rs:23:11
   |
18 |     fn fn_1(_: ()) {}
   |     -------------- found signature of `fn(()) -> _`
...
23 |     check(fn_1); // Error
   |     ----- ^^^^ expected signature of `for<'a> fn(<() as Variable<'a>>::Type) -> _`
   |     |
   |     required by a bound introduced by this call
   |
note: required by a bound in `check`
  --> src/lib.rs:12:8
   |
9  | fn check<F, T>(_: F)
   |    ----- required by a bound in this
...
12 |     F: for<'a> Fn(<T as Variable<'a>>::Type),
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`

error[E0277]: expected a `Fn<(<() as Variable<'a>>::Type,)>` closure, found `impl Fn(())`
  --> src/lib.rs:26:11
   |
26 |     check(fn_4); // Error
   |     ----- ^^^^ expected an `Fn<(<() as Variable<'a>>::Type,)>` closure, found `impl Fn(())`
   |     |
   |     required by a bound introduced by this call
   |
note: required by a bound in `check`
  --> src/lib.rs:12:8
   |
9  | fn check<F, T>(_: F)
   |    ----- required by a bound in this
...
12 |     F: for<'a> Fn(<T as Variable<'a>>::Type),
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
help: consider further restricting this bound
   |
17 | fn test(arg: impl Fn(()) + for<'a> std::ops::Fn<(<() as Variable<'a>>::Type,)>) {
   |                          +++++++++++++++++++++++++++++++++++++++++++++++++++++

Some errors have detailed explanations: E0277, E0631.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `playground` due to 2 previous errors

Context

Original thread in users forum

Meta

Tested on stable and nightly branches of playground:

  • Stable version: 1.56.1
  • Nightly version: 1.58.0-nightly (2021-11-09 8b09ba6)
@aliemjay aliemjay added the C-bug Category: This is a bug. label Nov 13, 2021
@steffahn
Copy link
Member

@rustbot label T-compiler, A-typesystem, A-lifetimes, A-inference, A-closures, A-traits

@rustbot rustbot added A-closures Area: Closures (`|…| { … }`) A-inference Area: Type inference A-lifetimes Area: Lifetimes / regions A-trait-system Area: Trait system A-type-system Area: Type system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 13, 2021
@aliemjay
Copy link
Member Author

aliemjay commented Nov 14, 2021

Prior to v1.56, closures and functions all fail alike with the same error message and adding type annotations didn't help either. So my guess is that #85499 (edit: and #88441) introduced an (incomplete?) fix, so I think this now needs to:

  • address the inconsistency
  • improve error message to require type annotations

@rustbot label A-diagnostics

@rustbot rustbot added the A-diagnostics Area: Messages for errors, warnings, and lints label Nov 14, 2021
@steffahn
Copy link
Member

While changing the error message could improve the situation, this is clearly not exclusively a diagnostics issue, AFAICT. To avoid potential confusion, let me remove the A-diagnostics label, which is commonly applied to issues that are purely diagnostics issues. @rustbot label -A-diagnostics.

In case it is decided that this is only a diagnostics issue after all, the label can be reapplied. In case the inconsistency is somehow fixed and diagnostics issues remain, a new A-diagnostics issue can be opened.

@rustbot rustbot removed the A-diagnostics Area: Messages for errors, warnings, and lints label Nov 14, 2021
@aliemjay
Copy link
Member Author

aliemjay commented Nov 14, 2021

I've just been aware of the version differences and recent efforts to solve this. So here is a summary:

A duplicate of #89436.

@Manishearth
Copy link
Member

#89436 closed as a dupe, there are additional testcases in that issue that should probably be checked when fixing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-closures Area: Closures (`|…| { … }`) A-inference Area: Type inference A-lifetimes Area: Lifetimes / regions A-trait-system Area: Trait system A-type-system Area: Type system C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants