---
# System prepended metadata

title: Impl trait elision examples (#107378)

---

# 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
}
```