Re:Rust 1.25 released
by steveklabnik on Thursday March 29, 2018 @11:13AM
(#16707672)
Consider this code:
Given the let ()s, this will fail to compile for both. For the first, you get
for the second, you get
The former gets longer and longer based on how many iterator chains you do, the latter will be the same no matter how many you add. It's also just generally way more clear, "I was expecting something implementing Iterator, and I didn't get it" vs "I was expecting this exact chain of nested iterators".
[ Parent
| on HN ]
Re:Rust 1.25 released
by mike-cardwell on Thursday March 29, 2018 @02:11PM
(#16709473)
Can you explain why an explicit lifetime is needed in foo_impl? I don't see a connection between the function argument lifetime and the return value lifetime, as the return value is a brand new object with cloned values... I realise I'm missing something fundamental here.
Re:Rust 1.25 released
by steveklabnik on Thursday March 29, 2018 @03:02PM
(#16710084)
okay so, the un-elided version of foo_no is
fn foo_no<'a>(v: &'a [i32]) -> std::iter::Cloned<std::slice::Iter<'a, i32>> {
I am not sure why the impl Trait version doesn't elide properly; I wrote it without the lifetime first and the compiler told me I need it, so I wrote it out, which is often what happens to me in these situations. I assume, since the elision rules were written years before impl Trait became a thing, that there's some sort of reason why it doesn't elide, but honestly, I'm not sure.
Re:Rust 1.25 released
by mike-cardwell on Thursday March 29, 2018 @03:13PM
(#16710173)
So why is the lifetime of the return value linked to the lifetime of the function argument? Couldn't the return value live longer than the function argument in that example?
Re:Rust 1.25 released
by steveklabnik on Thursday March 29, 2018 @03:51PM
(#16710481)
In both cases, the iterators are over the slice, so their lifetimes need to be tied together. The iterator can't live longer than the slice, or it'd be a use after free. Does that make sense?
Re:Rust 1.25 released
by mike-cardwell on Thursday March 29, 2018 @04:27PM
(#16710746)
Yes. Thanks for the explanation.
Re:Rust 1.25 released
by irishsultan on Thursday March 29, 2018 @04:30PM
(#16710771)
The Cloned iterator clones the elements of the underlying iterator, but only on-demand, so obviously it can't do that once the argument isn't live anymore.
Re:Rust 1.25 released
by Buttons840 on Thursday March 29, 2018 @01:11PM
(#16708779)
Ok. It looks like the new feature allows library authors to express their intentions with simpler code, and thus error messages will also be simpler. Looks good, thanks for taking the time to answer my question.
Re:Rust 1.25 released
by steveklabnik on Thursday March 29, 2018 @01:15PM
(#16708830)
No problem! It also does enable some other things too. For example, closures have a type that's not writable, so
fn foo() -> impl Fn(i32) -> i32 {
|x| x + 1
}
can be written, since closures implement the Fn trait, but there's no way to write the type directly.