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

Asssociated type declared in where clause is not enforced in type parameter #116864

Closed
c410-f3r opened this issue Oct 17, 2023 · 5 comments
Closed
Labels
A-associated-items Area: Associated items (types, constants & functions) A-lifetimes Area: Lifetimes / regions A-trait-system Area: Trait 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

@c410-f3r
Copy link
Contributor

c410-f3r commented Oct 17, 2023

For some reason FnMutFut<&'any BAZ::Param, ()> is not being inferred as FnMutFut<&'any i32, ()>, which results in an unsatisfied trait bound error.

use std::future::Future;

pub trait Baz {
    type Param;
}

pub trait FnMutFut<P, R>: FnMut(P) -> Self::Future {
    type Future: Future<Output = R>;
}

impl<P, F, FUT, R> FnMutFut<P, R> for F
where
    F: FnMut(P) -> FUT,
    FUT: Future<Output = R>,
{
    type Future = FUT;
}

pub async fn does_not_work<BAZ>(_: BAZ, mut cb: impl for<'any> FnMutFut<&'any BAZ::Param, ()>)
where
    BAZ: Baz<Param = i32>,
{
    cb(&1i32).await;
}

Perhaps something involving the generic implementation of FnMutFut? Perhaps something involving impl trait?

@c410-f3r c410-f3r added the C-bug Category: This is a bug. label Oct 17, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Oct 17, 2023
@fmease
Copy link
Member

fmease commented Oct 17, 2023

With -Ztrait-solver=classic:

error[E0277]: expected a `FnMut<(&'any i32,)>` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>`
  --> qq.rs:30:1
   |
30 | / pub async fn does_not_work<BAZ>(_: BAZ, mut cb: impl for<'any> FnMutFut<&'any BAZ::Param, ()>)
31 | | where
32 | |     BAZ: Baz<Param = i32>,
   | |__________________________^ expected an `FnMut<(&'any i32,)>` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>`
   |
   = note: expected a closure with arguments `(&<BAZ as Baz>::Param,)`
              found a closure with arguments `(&'any i32,)`
note: required for `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` to implement `for<'any> FnMutFut<&'any i32, ()>`
  --> qq.rs:22:20
   |
22 | impl<P, F, FUT, R> FnMutFut<P, R> for F
   |                    ^^^^^^^^^^^^^^     ^
23 | where
24 |     F: FnMut(P) -> FUT,
   |        --------------- unsatisfied trait bound introduced here

With -Ztrait-solver=next:

error[E0282]: type annotations needed
  --> qq.rs:34:13
   |
34 |     let _ = cb(&1i32).await;
   |             ^^^^^^^^^^^^^^^ cannot infer type

error[E0275]: overflow evaluating the requirement `<impl for<'any> FnMutFut<&'any BAZ::Param, ()> as FnMutFut<&<BAZ as Baz>::Param, ()>>::Future`
  |
  = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`qq`)

@fmease fmease added A-trait-system Area: Trait system A-associated-items Area: Associated items (types, constants & functions) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-lifetimes Area: Lifetimes / regions and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Oct 17, 2023
@c410-f3r
Copy link
Contributor Author

Thank you @fmease!

Since you are here, would you mind taking a look at #116749? :)

@lcnr
Copy link
Contributor

lcnr commented Nov 13, 2023

minimized

use std::future::Future;

pub trait Baz {
    type Param;
}

pub trait FnMutFut<P, R>: FnMut(P) -> Self::Future {
    type Future: Future<Output = R>;
}

impl<P, F, FUT, R> FnMutFut<P, R> for F
where
    F: FnMut(P) -> FUT,
    FUT: Future<Output = R>,
{
    type Future = FUT;
}

pub fn does_not_work<T, F>(mut cb: F)
where
    T: Baz<Param = i32>,
    F: FnMutFut<T::Param, ()>,
{}

which is a duplicate of #41118, the overflow error with -Ztrait-solver=next in the original example is interesting however. See the next comment

@lcnr
Copy link
Contributor

lcnr commented Nov 13, 2023

use std::future::Future;

pub trait Baz {
    type Param;
}

pub trait FnMutFut<P, R>: FnMut(P) -> Self::Future {
    type Future: Future<Output = R>;
}

impl<P, F, FUT, R> FnMutFut<P, R> for F
where
    F: FnMut(P) -> FUT,
    FUT: Future<Output = R>,
{
    type Future = FUT;
}

pub fn does_not_work<T, F>(mut cb: F)
where
    T: Baz<Param = i32>,
    F: FnMutFut<T::Param, ()>,
{
    cb(1)
}

this results in overflow in the new solver during typeck https://rust.godbolt.org/z/GGWeh597M

further minimized this issue in rust-lang/trait-system-refactor-initiative#76. Therefore closing this issue as a duplicate. Thank you for discovering a new issue in the new solver 🎉 we've been unsure about rust-lang/trait-system-refactor-initiative#12 for quite a while and this is really useful

@lcnr lcnr closed this as completed Nov 13, 2023
@c410-f3r
Copy link
Contributor Author

c410-f3r commented Nov 13, 2023

@lcnr Thank you very much for investigating this use-case!

For further context, the code was based on a suggestion provided by @danielhenrymantilla to simulate fn fun(_: for<'a> impl Fn(&'a Foo) -> impl Bar + 'a).

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Feb 12, 2024
…dtwco

Add test for recently fixed issue

Adds a test for issue rust-lang#116864.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Feb 12, 2024
…dtwco

Add test for recently fixed issue

Adds a test for issue rust-lang#116864.
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Feb 12, 2024
Rollup merge of rust-lang#120928 - c410-f3r:tests-tests-tests, r=davidtwco

Add test for recently fixed issue

Adds a test for issue rust-lang#116864.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items (types, constants & functions) A-lifetimes Area: Lifetimes / regions A-trait-system Area: Trait 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

No branches or pull requests

4 participants