I want to write a macro to automatically generate implementation of a trait for all types that can implement it. But I encountered a problem.
Usage
#[impl_trait_alias]
pub trait FutureIter<Err>
where
Self: Future<Output = Result<Self::FutOut, Err>>,
Self::FutOut: Iterator<Item: Display>,
{
type FutOut;
}
it generates
// ... original trait item
impl<
Err,
#[allow(non_camel_case_types)] __ImplTraitAlias_Self,
#[allow(non_camel_case_types)] __ImplTraitAlias_FutOut,
> FutureIter<Err> for __ImplTraitAlias_Self
where
Self: Future<Output = Result<__ImplTraitAlias_FutOut, Err>>,
__ImplTraitAlias_FutOut: Iterator<Item: Display>,
{
type FutOut = __ImplTraitAlias_FutOut;
}
And you can express a bundle of trait bounds with only typing a name!
fn get() -> impl FutureIter<String> {
async { Ok([123].into_iter()) }
}
Problem
As you can see, the existing macro logic contains an operation that replacing all Self::FutOut to a custom generic __ImplTraitAlias_FutOut. Of course the generated code in this example works fine, but the shortcoming is obvious: The user can only write Self::FutOut and any other style is unacceptable, like <Self>::FutOut, <Self as FutureIter<Err>>::FutOut, macros, etc.
So the problem is: is there a way to realize the auto-implementation without modifying where-predicates? Thanks.
Note: Directly keep the origin where-predicates unchanged will trigger an compile error.
The code:
impl<
Err,
#[allow(non_camel_case_types)] __ImplTraitAlias_Self,
#[allow(non_camel_case_types)] __ImplTraitAlias_FutOut,
> FutureIter<Err> for __ImplTraitAlias_Self
where
Self: Future<Output = Result<Self::FutOut, Err>>,
Self::FutOut: Iterator<Item: Display>,
{
type FutOut = __ImplTraitAlias_FutOut;
}
The error:
error[E0275]: overflow evaluating the requirement `<__ImplTraitAlias_Self as FutureIter<Err>>::FutOut == _`