Impl Trait in argument position can be replaced with a bounded generic parameter, so the following are equivalent:
fn f<T >(_: impl A + B) {}
fn f<T: A + B>(_: T ) {}
Can something similar be done with impl Trait in return position? The obvious thing doesn't work:
fn b<T: Clone + Copy>() -> T { 42 }
error[E0308]: mismatched types
--> src/bin/return_impl_trait.rs:2:32
|
2 | fn b<T: Clone + Copy>() -> T { 42 }
| - - ^^ expected type parameter `T`, found integer
| | |
| | expected `T` because of return type
| this type parameter help: consider using an impl return type: `impl Clone + Copy`
It would be nice to have, if not strictly necessary, when many bounds accumulate on the return type. But if a bound needs to be placed on a returned trait's associated type, can it be done with impl Trait in return position at all?
Here's a minimal example of the problem:
/// A function with bounds on generic parameter's associated type
fn take<T>(_: T)
where
T: Iterator,
T::Item: Copy, // How can this requirement be satisfied by `make` below?
{}
/// A function which returns something that can be passed to `take`
fn make() -> impl Iterator /* what about Item: Copy? */ { 0..42 }
fn main() {
take(make());
}
How can we express the fact that make
returns an iterator whose items are Copy
?
Note: This is a minimal example whose purpose is to generate the relevant compiler error with trivial code: in real life I need to do something much more complex than return a range, so solutions along the lines of
fn make() -> std::ops::Range<u32> { 0..42 }
which address the irrelevant details of the toy example, are not what this question is about.