Help With Unfamiliar `impl` Use

In one of the many kind replies I've received to my cry fo help there was this code:

fn fib() -> impl Iterator<Item=i32> {
    let mut x: i32 = 0;
    let mut y: i32 = 1;
    std::iter::from_fn(move || Some({
        let z = x + y;
        let out = x;
        x = y;
        y = z;
        out
    }))
}

Being a noobie, I've found impl only as an implemantation for Structs; now, what's its purpose in the returned value of the function and where can I find a reference for it in The Book, or other sources for that matter?

This syntax is called "return position impl Trait", or RPIT for short. It's introduced in the book here, and you can read the original proposal that introduced this feature to the language here (RFC 1522, from 2016). The short version is that the syntax means "this function returns a specific type that implements the stated Trait, but which specific type is not visible or nameable outside the body of the function". This allows you to write type signatures for functions that return a type that can't be named at all (like the types of function items, closures, and async blocks), or for which you don't want to promise a specific return type, while still letting callers use the return value in a limited number of ways (by calling methods, etc., of the Trait in question).

3 Likes

A useful trick is that, if you're using rust-analyzer, you can use the standard LSP docs interface for keywords. For example, in VSCode, hovering over the impl keyword gives the following snippet:

The other use of the impl keyword is in impl Trait syntax, which can be seen as a shorthand for "a concrete type that implements this trait". Its primary use is working with closures, which have type definitions generated at compile time that can't be simply typed out.

fn thing_returning_closure() -> impl Fn(i32) -> bool {
    println!("here's a closure for you!");
    |x: i32| x % 3 == 0
}
2 Likes

The important thing to remember is that the function is still returning a concrete type that happens to implement that trait, not a trait object (a dyn Something), and if there are multiple return points they all have to return the same type. That last point is an extremely common source of confusion.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.