Impl trait with generic associated type in return position causes lifetime error

As far as I can tell, the compiler's error message is misleading, what it actually requires is an explicitly defined associated type:

fn map(i: &str) -> impl '_ + IntoState<State = String> {
    i
}

The excellent answer given to the quesion: Why does the compiler not infer the concrete type of an associated type of an impl trait return value? provides enough information on why this is actually needed.

See also Rust issue #42940 - impl-trait return type is bounded by all input type parameters, even when unnecessary

You can use a generic type parameter instead of returning an impl in which case you don't have to specify the associated type:

fn map<T: IntoState>(i: T) -> T {
    i
}

Apparently there is still some confusion about what exactly is going on here, so I'll try to destil my comments into a short answer.

The problem here is the prototype of the function map():

fn map(i: &str) -> impl '_ + IntoState

This specifies that the return type of map() is some type implementing IntoState, with an unspecified associated type State. The return type has a lifetime parameter with the lifetime of the argument i; let's call that lifetime 'a, and the full return type T<'a>. The associated type State of this return type now is <T<'a> as IntoState>::State, which is parametrized by 'a. The compiler is currently not able to eliminate this lifetime parameter from the assoicated type, in spite of the 'static declaration in the trait definition. By explicitly specifying the associated type as String, the compiler will simply use the explicitly specified type String instead of <T<'a> as IntoState>::State, so the lifetime parameter is gone, and we don't get an error anymore.

This compiler shortcoming is discussed in this Github issue.

Tags:

Rust