-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Closed as not planned
Labels
A-inferenceArea: Type inferenceArea: Type inferenceA-trait-systemArea: Trait systemArea: Trait systemC-bugCategory: This is a bug.Category: This is a bug.T-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.
Description
I tried this code:
pub trait Callable<A> {
type Output;
}
pub struct Call<A>(A);
impl<F: FnOnce(A) -> B, A, B> Callable<F> for Call<A> {
type Output = B;
}
impl<A> Call<A> {
fn build<F>(f: F) -> impl FnOnce(A) -> <Self as Callable<F>>::Output
where
Self: Callable<F>
{
move |a| todo!()
}
}
fn foo<F>(f: F)
where
Call<()>: Callable<F>
{
Call::build(Call::build(f));
}
fn bar() {
Call::build(Call::build(|()| 0));
}
I expected it to compile, but it doesn't. Instead, I get the following compile error:
error[E0308]: mismatched types
--> src/lib.rs:25:17
|
13 | fn build<F>(f: F) -> impl FnOnce(A) -> <Self as Callable<F>>::Output
| ----------------------------------------------- the found opaque type
...
21 | fn foo<F>(f: F)
| - this type parameter
...
25 | Call::build(Call::build(f));
| ^^^^^^^^^^^^^^ expected type parameter `F`, found opaque type
|
= note: expected type parameter `F`
found opaque type `impl FnOnce<((),)>`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
This is unusual because Call::build
is implemented for all types F: FnOnce(A) -> _
(through the Callable
trait), and since Call::build
returns a type that implements FnOnce(A) -> _
, it should be possible to recursively call Call::bulid
if the first one succeeds. However, Rust overzelously assumes that Call::build
can only be called with F
(the concrete type parameter) instead of any type that implements FnOnce(A) -> _
. (I'm trying to abstract over Fn*
traits for a single argument, so this is road bump is annoying to work around, it requires duplicating all applicable functions).
Metadata
Metadata
Assignees
Labels
A-inferenceArea: Type inferenceArea: Type inferenceA-trait-systemArea: Trait systemArea: Trait systemC-bugCategory: This is a bug.Category: This is a bug.T-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.