Hacker News new | ask | show | jobs
by ForkMeOnTinder 925 days ago
About #10:

> because to unify them at this point would be a breaking change

Couldn't they change this in a future edition without breaking older editions?

4 comments

A new edition is not a free pass to break source compatibility; it's more like a fire axe hidden behind breakable glass. You really, really want to avoid breaking changes because your users will now have to know about the difference between the compiler editions used by each of their projects.

In short, yes, but be very wary.

Technically yes, but editions are more like different "flavors" of Rust than actual breaking changes. A 2021 crate is supposed to be able to import a 2018 crate, likewise for 2015 and 2024. Because they all need to work together, edition changes still need to be somewhat compatible with older versions.

Because you can pass closures into functions across crate boundaries, which requires consistent lifetime semantics, I find it unlikely that this will be implemented.

As far as I can tell, this change is compatible with other editions. Closures can already be higher-ranked, and changing closures to be higher-ranked will work with existing editions.

A more problematic thing is that `cargo fix --edition` should be able to transform existing code to the same meaning in a new edition, so there should be a way to opt-in for the old behavior.

Most likely yes.

However, if you don't specify the argument type, it compiles fine. It's rare that you need to specify argument or return types on a closure, so it's not actually a large issue.

Wouldn't fixing 10 just mean allowing things that were previously not allowed? That's not a breaking change. What am I missing?
No it will not:

    fn requires_static(_: &'static str) {}
    
    let long_lifetime: &'static str = "";
    let closure = |_input: &str| -> &str { long_lifetime };
    let short_lifetime = &String::new();
    requires_static(closure(short_lifetime));
This code compiles currently as the returned `&str` is inferred to be `&'static str` because this is what it actually returns, but with #10 fixed it will not because lifetime elision rules say that the lifetime of the output is the same as the lifetime of the input.
Hm, in this case it's actually nice that this works because there's nothing unsafe or unexpected going on.