# Impl trait elision examples (#107378)
## Competing axes
* Utility: is the resulting expansion *useful*
* GAT consistency: `impl Foo<Bar = &u32>` vs `impl Foo<Bar<..> = &u32>`, do we want them to mean same thing? How do we think about it?
* Where-clause vs impl consistency: Do `where T: <X>` and `impl <T>` mean the same thing?
The last two are tricky since `'_` is not yet accepted in GATs or where-clause, so we have multiple degrees of freedom.
### Accidental (?) stabilizations
The behavior in `async fn` and `->` has already been stabilized, with `'_` acting the same as it would within a type (i.e., fresh parameter or reference to lifetime appearing in the arguments).
## Function that takes an iterator over references
tmandry gave this example:
```rust
fn fun(t: impl Iterator<Item = &u32>) {}
// ...which surely wants to be...
fn fun<'a>(t: impl Iterator<Item = &'a u32>) {}
```
[as explained here](https://github.com/rust-lang/rust/pull/107378#issuecomment-1779629217), expanding to `impl for<'a> Iterator<Item = &'a u32>` would be useless, as there is literally no impl one could write that would satisfy that bound.
## Compiler visitor
## Serde's lifetime
The `'de` lifetime on Serde is interesting.
```rust
fn fun(t: impl Deserialize<'_>) {}
```
What should this mean?
* It is quite possible that the `Self` type is carrying a lifetime that will appear in the deserialized data (e.g., `&'a Path`), in which case you want `fn fun<'a>(t: impl Deserialize<'a>)`
* On the other hand, it is very often the case that one wants to write `where T: for<'de> Deserialize<'de>`, indicating fully owned data, and hence dispense with the lifetime. There exists an alias for this ([`DeserializeOwned`](https://docs.rs/serde/latest/serde/de/trait.DeserializeOwned.html)), which can be seen either a "feature request" for `where T: Deserialize<'_>` having that meaning, or as a reason that it's ok that it doesn't, since people can use the alias.
* Niko's take: the alias is a feature request.
## Lending iterator
```rust
trait LendingIterator {
type Item<'s> where Self: 's;
fn next(&mut self) -> Self::Item<'_>;
}
// Equivalent: `iter: impl for<'a> LendingIterator<Item<'a> = &'a str>`
fn concat(iter: impl LendingIterator<Item<'_> = &str>) -> String {
let mut out = String::new();
for s in iter {
out.push_str(s);
}
out
}
```