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