Can we have bound on associated type of impl trait in return position?

Is it possible to add a bound to the associated item of an impl Trait in return position?

Some kind of hypothetical syntax:

trait Trait;

// inline
fn make_foo() -> impl Iterator<Item: impl Trait> { /* ... */ }

// where clause
fn make_bar() -> impl Iterator
where
    <return as Iterator>::Item: Trait
{ /* ... */ }

This would allow to return an anonymous type implementing a trait, and where the associated type of said trait itself is anonymous.

Edit: The functionality is stable under a different syntax, see @SNCPlay42 's reply below. Original reply follows.


It's an accepted RFC but not yet stable. Here's an example on nightly.

#![feature(associated_type_bounds)]
use core::fmt::Debug;

fn make_foo() -> impl Iterator<Item: Debug> { 0..10 }

fn main() {
    for foo in make_foo() {
        println!("{:?}", foo);
    }
}
1 Like

Note that associated_type_bounds only adds new syntax for bounds that can already be expressed. As the RFC notes, this:

#![feature(associated_type_bounds)]
fn make_foo() -> impl Iterator<Item: Trait>

Is equivalent to this:

fn make_foo() -> impl Iterator<Item = impl Trait>
3 Likes

Huh, ignore me. I could have swore that was the case and even tested it but must have made a mistake. I double checked myself and, yeah. My bad.

@robin assuming you're using stable, you'll want to select @SNCPlay42 's reply as the solution and use that approach.

It was more a general question, that an an immediate need. I’ve updated the chosen solution nonetheless.

Btw, I guess it’s not possible to name the return type in a where clause?

fn make_foo() -> impl Iterator<Item> 
    where Item: Debug
{ 0..10 }

This could be useful to express more complex bound (like where T: SomeTrait<usize, Item> if T is for example the type of a parameter of the function).